首先,清楚一个概念
函数是对象的方法:
var person = {
firstName:"Bill",
lastName: "Gates",
fullName: function () {
return this.firstName + " " + this.lastName;
}
}
person.fullName();
//fullName 属性是一个方法。person 对象是该方法的拥有者。
//fullName 属性属于 person 对象的方法。
//如果一个函数不是 JavaScript 对象的方法,那么它就是全局对象的函数
然后,再明白一个问题,this的指向问题
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象;
function a(){
var user = "追梦子";
console.log(this.user); //undefined
console.log(this); //Window
}
a();
上面的代码:调用a方法的是window,所以this指向的是window
var o = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
o.fn();
而这段代码中,调用fn的是对象o,所以,this指向的是o,那this.user就是"追梦子"。
再次强调:::this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁,一定要搞清楚这个。
如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象
还有一个特殊情况:下面的代码在运行式,输出的this指向是window,这是因为his永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行所以最终指向的是window。
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var j = o.b.fn;
j();
一、call()、apply()、bind() 都是用来重定义 this 这个对象的!
1、call()、apply()、bind() 的使用
var person = {
fullName: function () {
return this.firstName + " " + this.lastName;
}
}
var person1 = {
firstName: "Bill",
lastName: "Gates",
}
var person2 = {
firstName: "Steve",
lastName: "Jobs",
}
console.log(person.fullName.call(person1)); // 将返回 "Bill Gates"
console.log(person.fullName.apply(person1)); // 将返回 "Bill Gates"
console.log(person.fullName.bind(person1)()); // 将返回 "Bill Gates"
通过call、apply、bind方法使fullName方法中的this指向person1,那this.firstName就是person1的firstName "Bill";this.fullName就是person1的fullName "Gates"
注意:以上出了 bind 方法后面多了个 () 外 ,结果返回都一致!
由此得出结论,bind 返回的是一个新的函数,你必须调用它才会被执行。
2、三者的传参区别
var person = {
fullName: function(city, country) {
return this.firstName + " " + this.lastName + "," + city + "," + country;
}
}
var person1 = {
firstName:"John",
lastName: "Doe"
}
console.log(person.fullName.call(person1, "Oslo", "Norway")); // 将返回 "John Doe,Oslo,Norway"
console.log(person.fullName.apply(person1,["Oslo", "Norway"])); // 将返回 "John Doe,Oslo,Norway"
console.log(person.fullName.bind(person1, "Oslo", "Norway")()); // 将返回 "John Doe,Oslo,Norway"
console.log(person.fullName.bind(person1,["Oslo", "Norway"])()); // 将返回 "John Doe,Oslo,Norway,undefined"
从上面四个结果不难看出:call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,主要是第二参数不同。
- call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 ;
- apply 的所有参数都必须放在一个数组里面传进去;
- bind 除了返回是函数以外,它 的参数和 call 一样;