JavaScript我的第n+1次学习

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/M_sdn/article/details/86499339

一,数据类型

五种原始类型:

number,

string, 对应的包装类String

boolean,

null,

undefined,

对象类型:

Function, Array, Date。。。

相等 vs 严格相等

typeof  vs instanceof vs Object.prototype.toString

  1. typeof,适合基本类型及function检测,遇到null失效。
  2. instanceof,适合自定义对象,也可以用来检测原生对象,在不同iframe和window间检测时失效。
  3. Object.prototype.toString,遇到null和undefined失效

二,表达式

数组,对象初始化表达式:

[1,2] ==> new Array(1,2);

[1,,,4] ==> [1, undefined, undefined, 4];

{x:1, y:2} ==> var o = new Object(); o.x1 = 1; o.x2 = 2;

函数表达式:

var func = function(){};
// 直接将函数用括号扩起来,然后再最后面写一个括号,表示函数调用。
(function(){console.log('hhhhiiii');})();

属性访问表达式:

var o = {x:'hello'};
//访问1
o['x']
//访问2
o.x

对象创建表达式:

new Func(1,2);  //带参数
new Object;     //不带参数

调用表达式:

func(); //函数名加上()

 三,运算符

三目运算符:c ? a: b

逗号运算符:var val = (1,2,3);   // val == 3;

delete:删除一个属性

in:判断一个属性是否属于某个对象

instanceof:根据原型链来判断

new/this/typeof/void,略

四,对象

对象中包含一系列属性,属性是无序的,一个属性由key和value组成。

对象的创建:(1)字面量var o = {x:1, y:2},可嵌套  (2)new 构造器  (3)Object.create({x:3});

原型链(有点像Java里面类的继承)

五,属性标签

用下面的方法获取一个对象的属性值

Object.getOwnPropertyDescriptor({pro:true}, 'pro');
{ value: true,
  writable: true,
  enumerable: true,
  configurable: true }

//如果属性不存在,则返回undefined
Object.getOwnPropertyDescriptor({pro:true}, 'prr');
undefined

给对象创建一个属性

> Object.defineProperty(person, 'name', {
... configurable:false,
... writable:false,
... enumerable:true,
... value:'Jackey'
... });

//因为writable是false的,所以不能修改name的属性
> person.name //打印当前name值
'Jackey'
> person.name=100; //修改name值
100
> person.name; //可以看到并没有被修改
'Jackey'
> delete person.name; //删除也是删除不了的
false

对象标签:proto, isExtensible, class

对象序列化

六,数组

6.1 弱类型,什么样类型的元素都可以往里面塞

var arr = [1, true, null, undefined, {k:1}, [1,2,3]];

6.2 创建数组

//除了使用6.1那样使用字面量的方法,还可以如下
var arr = new Array();
var arrWithLength = new Array(10);
var arrLikeLiteral = new Array(true, false, null, 11, 'rrr');

6.3 元素增删除

动态,无需指定大小.

var arr = [11,22,33,44];
//尾部添加元素
arr.push(-55);
//头部添加元素
arr.unshift(-11)
//尾部删除元素
arr.pop();
//头部删除元素
arr.shift();

6.4 数组迭代

//法1
for(var i = 0; i<arr.length; i++) {
    console.log(arr[i]);
}
//法2
for(i in arr) {
    console.log(arr[i]);
}
//原型链上添加元素
Array.prototype.x='added';
//遍历数组会访问添加的元素

//使用这个判断可以过滤
if(arr.hasOwnProperty(i)){
    console.log(arr[i]);
}

6.5 数组方法

Array.prototype.join
Array.prototype.reverse
Array.prototype.sort //1.in place 2.sort by string order
Array.prototype.concat //array to be filled will be flatted
Array.prototype.slice //原数组不被修改
Array.prototype.splice //原数组被修改
Array.prototype.forEach
Array.prototype.map //数组映射
Array.prototype.filter //数组过滤
Array.prototype.every //表示每一个元素都要符合一定的条件
Array.prototype.some  //表示任一个元素,只要一个符合
Array.prototype.reduce
Array.prototype.reduceRight
Array.prototype.indexOf
Array.prototype.lastIndexOf
Array.isArray

示例 reduce

var arr = [11, 22, 33, 44];
var sum = arr.reduce(function(x, y){
    return x+y;
}, 0);

var max = arr.reduce(function(x ,y){
    return x>y?x:y;
});

 示例 判断数组

Array.isArray({});
[] instanceof Array;
({}).toString.apply([]) === '[object Array]';
[].constructor === Array;

数组 vs 对象

相同
1.都可以继承
2.都可以当作对象添加/删除属性


不同
数组自动更新length
数组对象继承Array.prototype上的大量数组操作方法

 七,函数

Js函数不同于其他语言中的函数,js函数可以像其他对象那样操作和传递,所以js函数也称为函数对象

7.1 调用方法

直接调用: foo();
对象方法式调用: o.method();
构造器调用: new Foo();
call/apply/bind: func.call(o);

函数声明

function add(a, b) {
	a = +a;
	b = +b;
	if(isNaN( || isNaN(b)) return;
	return a + b;
}

函数表达式

//function variable	   
var add = function(a,b) {
	// do sth	
}
	
//Immediately Executed Function
(function() {
	// do sth
})();
	
// first-class function
return function() {
	// do sth
}	

// Named function expression
var add = function foo(a,b) {
	// do sth
}

变量&函数的声明前置

7.2 this

(1) 在浏览器中,全局的this,就是window;

     在node.js中,全局的this,就是global.

console.log(this.document === document);
console.log(this === window);
this.a = 37;
console.log(window.a);
function f1() {
	return this;
}	
f1() === global; // true

严苛模式下: 

function f1() {
	"use strict";
	return this;
}
f1() === global; 	//false
f1() === undefined; //true	

 (2) 作为对象方法的函数的this

var o = {
	prop:37;
	f:function() {
		return this.prop;
	}
};
console.log(o.f());

(3) 对象原型链上的this

var o = {f:function(){return this.a + this.b;}};
var p = Object.create(o);
p.a = 1;
p.b = 4;
console.log(p.f());

(4) 构造器中的this

function MyClass() {
	this.a = 73;
	//没有return或返回值为基本类型,则将this作为返回值
}
var o = new MyClass();
console.log(o.a); //73
function C2() {
	this.a = 37;
	return {a:38}; //回值为对象类型,则将该对象作为返回值
}
o = new C2();
console.log(o.a); //38

(5) call/apply与this

function add(c, d) {
	return this.a + this.b + c+ d;
}

var o = {a:1, b:3};
add.call(o, 5,7); //1+3+5+7 = 16
add.apply(o, [10, 20]); //1+3+10+20=34

function bar() {
	console.log(Object.prototype.toString.call(this));
}

bar.call(7); //"[object Number]"

(6) bind与this

function f() {
	return this.a;
}

var g = f.bind({a:"test"});
console.log(g());

var o = {a:37, f:f, g:g};
console.log(o.f(), o.g());

 7.3 函数属性&arguments

function foo(x, y, z) {
	arguments.length;
	arguments[0];
	arguments[0] = 10;
	x;
	
	arguments[2] = 100;
	z;
	arguments.callee === foo;
}
foo(1, 2);
foo.name; //函数名
foo.length; //形参个数
arguments.length; //实参个数

call & apply

function fo(x, y) {
	console.log(x, y, this);
}
fo.call(100, 1,2); // 1,2,Number(100)
fo.apply(true, [3,4]); //3,4,Boolean(true)
fo.apply(null); //undefined, undefined, window
fo.apply(undefined); //undefined, undefined, window

bind, 改变函数里面的this 

this.x = 9;
var module = {
	x:81,
	getX: function() {return this.x}
};
module.getX(); //81

var getX = module.getX;
getX(); // 9

var boundGetX = getX.bind(module);
boundGetX(); // 81

bind与currying

function add(a,b,c) {
	return a+b+c;
}

var func1 = add.bind(undebined, 100); //100被赋值给第1个参数a
func1(1,2); //103, 1赋值给b,2赋值给c

var func2 = func1.bind(undebined, 200); //因a已经绑定到了a,200会绑定到b
func2(10);  //310, 10绑定到c

bind与new

function foo() {
	this.b = 100;
	return this.a;
}

var func = foo.bind({a:1}); //this指向bind的参数

func(); //因为this指向对象{a:1},所以返回值this.a就是1
new func(); //会产生一个空对象,空对象指向foo_prototype,返回值忽略this.a;直接将100返回(what the fuck!)

八,函数和作用域

8.1 闭包

(1) 演示闭包

function outer() {
	var localVal = 30;
	return function() {
		return localValue;
	}
}

var func = outer(); //外部函数调用完之后,localVal不能立即释放,因为return的函数引用了它
func(); //30

(2) 闭包常用错误:循环闭包

function Outer {
	var tempList = [];
	for (var i = 0; i < 10; i++) {
		tempList[i] = function () {
			return i;
		}
	}
	return tempList;
}
//调用方:
var list = Outer();
for (var i = 0; i < list.length; i++) {
	console.log(list[i]() + " "); // 闭包回调, 10, 10, 10, 10...
}

(3)闭包概念

闭包(也称词法闭包或函数闭包)是指一个函数或函数的引用,与一个环境变量绑定在一起.这个引用环境是一个存储该函数每个非局部变量(也叫自由变量)的表.

闭包,不同于一般的函数,它允许一个函数在立即词法作用域外调用时,仍可访问非本地变量

8.2 作用域

js没有块作用域的概念

(1) 全局,局部

var globle_a = 10; //全局变量
(function() {
	var func_b = 20; //函数局部变量
})();
console.log(globle_a); //10
console.log(func_b);   //error, b is not defined

for(var item in {a:1, b:2}) {
	console.log(item);
}
console.log(item);  // item is still in scope

eval("var a = 1;");

(2) 执行上下文

全局的this(浏览器)
一般函数的this(浏览器)
作为对象方法的函数的this
对象原型链上的this
get/set方法与this
构造器中的this
call/apply方法与this
bind方法与this

九,OOP

9.1 基于原型的继承

function Foo() {
	this.y = 2;
}

typeof Foo.prototype; // "object"
Foo.prototype.x = 111;
var obj = new Foo();

obj.y; //2
obj.x; //111

Foo.prototype的结构:

{
    constructor:Foo,
    _proto_:Object.prototype,
    x:1

prototype是函数上预设的对象属性,原型是构造器的prototype属性(what the fuck!!!)

9.2 图解原型链

对象继承代码示例

function Person(name, age) {
	this.name = name;
	this.age  = age;
}

Person.prototype.hi = function() {
	console.log('Hi, my name is '+this.name +", I'm " + this.age + " years old now.");
};

Person.prototype.LEGS_NUM = 2;
Person.prototype.ARMS_NUM = 2;
Person.prototype.walk = function() {
	console.log(this.name + " is walking");
};

function Student(name, age, className) {
	Person.call(this, name, age);
	this.className = className;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

Student.prototype.hi = function() {
	console.log('Hi, my name is ' + this.name + ", I'm " +
			   this.age + " years old now, and from " +
			   this.className + ".");
};

Student.prototype.learn = function(subject) {
	console.log(this.name + ' is learning ' + subject + ' at '+ this.className+'.');
}

// test
var littleTom = new Student('Tom', 20, 'Class 3, Grade 2');
littleTom.hi();
littleTom.LEGS_NUM;
littleTom.walk();
little.learn('computer science');

多种方式实现继承

function Person() {}
function Student() {}
Student.prototype = new Person(); //1
Student.prototype = Object.create(Person.prototype); //2
Student.prototype.constructor = Person; //3

猜你喜欢

转载自blog.csdn.net/M_sdn/article/details/86499339
今日推荐