本文记录对 JS 中 this 的详解
this的绑定方式
默认绑定
没调用对象指向全局
function foo() {
console.log(this.a);
}
var a = 1;
foo();//1
隐式绑定
var a = 1;
function foo() {
console.log(this.a);
}
var obj = {
a: 2,
foo: foo
}
obj.foo();//2
var bar = obj.foo;
bar();//1
显式绑定
function foo() {
console.log(this.a);
}
var a = 1;
var obj = {
a: 2
}
foo.call(obj);//2
foo.apply(obj);//2
var bar = foo.bind(obj);
bar();//2
new绑定
function foo(a) {
this.a = a;
}
var a = 1;
var bar = new foo(3);
console.log(bar.a);//3
各绑定方式的优先级
显示与隐式的比较
function foo() {
console.log(this.a);
}
var obj1 = {
a: 1,
foo: foo
}
var obj2 = {
a: 2
}
obj1.foo();//1
obj1.foo.call(obj2);//2
所以显式优先级高于隐式
new与隐式的比较
function foo(a) {
this.a = a;
}
var obj = {
a: 1,
foo: foo
}
obj.foo(2);
console.log(obj.a);//2
var bar = new obj.foo(3);
console.log(obj.a);//2此时obj.foo(3)未起作用,new优先级大于隐式
console.log(bar.a);//3
显式与new的比较
function foo(a) {
this.a = a;
}
var obj = {};
var bar = foo.bind(obj);
bar(2);
console.log(obj.a);//2
var baz = new bar(3);
console.log(obj.a);//2使用new未将obj.a改变为3,显式优先级高于new
console.log(baz.a);//3this绑定新创建的对象baz
bind的用法
一般情况下在使用对象调用函数是会使用以下方式书写,将对象赋值给函数内部的局部变量,调用函数时能从局部变量中获取
var x = 10;
var myObj = {
x: 0,
deal: function() {
var that = this;
return function() {
return ++that.x;
}
}
};
var aaa = myObj.deal();
console.log(aaa());//1
不将对象赋值到函数内部的局部变量,函数调用时从全局中去获取
var aaa = myObj.deal();
console.log(aaa());//1
var x = 10;
var myObj = {
x: 0,
deal: function() {
return function() {
return ++this.x;
}
}
};
var aaa = myObj.deal();
console.log(aaa());//11
bind相当于将myObj(上下文)传入到函数中
var x = 10;
var myObj = {
x: 0,
deal: function() {
return (function() {
return ++this.x;
}).bind(this);
}
};
var aaa = myObj.deal();
console.log(aaa());//1
bind使用参数的形式传入时
function foo(p1) {
this.val = p1;
}
var baz = foo.bind(null, 'p1');
var bar = new baz('p2');
console.log(bar.val);//p1
function foo(p1, p2) {
this.val = p1 + p2;
}
var baz = foo.bind(null, 'p1');
var bar = new baz('p2');
console.log(bar.val);//p1p2
function foo(p1) {
this.val = p1;
}
var baz = foo.bind('p1');
var bar = new baz('p2');
console.log(bar.val);//p2
使用new新建对象时即被忽略
null、undefined作为this绑定对象传入call、apply和bind时,实际应用的是默认绑定规则
function foo() {
console.log(this.a);
}
var a = 1;
foo.call(null);//1
绑定到全局的this改为局部,使用空集合符号
var Ø = Object.create(null);
function foo() {
console.log(this.a);
}
foo.call(Ø);//undefined
ES6箭头函数中的this(与self=this的机制一样)
以下例子需要ES6环境下使用,可参考https://github.com/PLDaily/ES6
var Person = function() {
this.name = 'pcd';
this.hello = () => {
console.log(this.name);//this在定义是已经被锁死
}
}
var bb = new Person();
bb.hello.bind({"name": "dcp"});
bb.hello();//pcd
注意事项
var a;
a++;
console.log(a);//NaN