this
ES5中,this永远指向最后调用的那个对象
var name = "name";
var a = {
fn : function () {
console.log(this.name); // undefined
}
}
window.a.fn();
this最后调用的对象是a,而对象a中未定义name,所以为undefined
var name = "name";
var a = {
name : "Tom",
fn : function () {
console.log(this.name);
}
}
a.fn(); //Tom
var f = a.fn;
f(); // name
a.fn()中this调用的是对象a,所以为Tom
a.fn赋值给f时未调用,而f()指向的是window,所以为name
改变this的指向
var name = "name";
var a = {
name : "Tom",
f1: function () {
console.log(this.name)
},
f2: function () {
setTimeout( function () {
this.f1()
},1000);
}
};
a.f1(); //Tom
a.f2(); // this.f1 is not a function
a.f2()调用setTimeout()函数,setTimeout的对象是window,所以报错
使用that=this改变指向
var name = "name";
var a = {
name : "Tom",
f1: function () {
console.log(this.name)
},
f2: function () {
var that=this;
setTimeout( function () {
that.f1()
},1000);
}
};
a.f2() ; // Tom
1.ES6箭头函数
var name = "name";
var a = {
name : "Tom",
f1: function () {
console.log(this.name)
},
f2: function () {
setTimeout( () =>{
this.f1()
},1000);
}
};
a.f2() ; // Tom
箭头函数中没有 this 绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,否则,this 为 undefined”。
2.apply,call
var name = "name";
var a = {
name : "Tom",
f1: function () {
console.log(this.name)
},
f2: function () {
setTimeout( function () {
this.f1()
}.apply(a),1000);
}
};
a.f2() ; // Tom
apply()方法 接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。
apply([thisObj [,argArray] ]);
var name = "name";
var a = {
name : "Tom",
f1: function () {
console.log(this.name)
},
f2: function () {
setTimeout( function () {
this.f1()
}.call(a),1000);
}
};
a.f2() ; // Tom
call()方法 第一个参数和apply()方法的一样,但是传递给函数的参数必须列举出来。
call([thisObject[,arg1 [,arg2 [,...,argn]]]]);
apply和call的区别
var a ={
f1 : function (a,b,c) {
console.log( a + b+c)
}
}
var f = a.f1;
f.apply(a,[1,2,3]) // 6
var a ={
f1 : function (a,b,c) {
console.log( a + b+c)
}
}
var f = a.f1;
f.call(a,1,2,3) // 6
3.bind
var name = "name";
var a = {
name : "Tom",
f1: function () {
console.log(this.name)
},
f2: function () {
setTimeout( function () {
this.f1()
}.bind(a)(),1000);
}
};
a.f2() ; // Tom
bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。bind() 函数的参数跟 call() 一致
var a ={
name : "Tom",
f1 : function (a,b,c) {
console.log( a + b+c)
}
}
var f = a.f1;
f.bind(a,1,2,3) // 无输出
f.bind(a,1,2,3)() // 6
注意,bind创建一个新的函数,必须调用
总结
apply、call 、bind 都可以改变this的指向。
apply 、 call 、bind 的第一个参数都是this要指向的对象。
apply 、 call 、bind 都可以利用后续参数传参。
apply 、call 是立即调用,bind 是回调执行。