this, call, apply 和 bind
1 this:它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用。
1.1 纯粹的函数调用:属于全局性调用,因此this就代表全局对象。
var name=‘kenn‘;
function hi(){ console.log(this.name);}
hi();//kenn
1.2 作为对象方法的调用:函数还可以作为某个对象的方法调用,这时this就指这个上级对象。
var name=‘kenn‘;
function hi(){ console.log(this.name);}
var hello={};
hello.name="keny";
hello.sayHi=hi;
hello.sayHi();//keny
hi();//kenn
1.3 作为构造函数调用:所谓构造函数,就是通过这个函数,可以生成一个新对象。这时,this就指这个新对象。
var name=‘kenn‘;
function hi(){this.name=‘kit‘}
var k=new hi();
name;//kenn
k.name;//kit
1.4 apply 调用:apply()是函数的一个方法,作用是改变函数的调用对象。它的第一个参数就表示改变后的调用这个函数的对象。因此,这时this指的就是这第一个参数。apply()的参数为空时,默认调用全局对象
var name=‘kenn‘
function hi(){console.log(this.name);}
var hello={};
hello.name=‘keny‘;
hello.sayHi=hi;
hello.sayHi.apply();//kenn
hello.sayHi.apply(hello);//keny
1.5 this 永远指向最后调用它的那个对象
var name=‘kenn‘
var hi={};
hi.name=null;
hi.sayHi=function(){ console.log(this.name);}
hi.sayHi();//null
hello =hi.sayHi;
hello();//kenn
1.6 改变this的指向
1.6.1 使用 ES6 的箭头函数:箭头函数的 this 始终指向函数定义时的 this,而非执行时;箭头函数中没有 this 绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,否则,this 为 undefined
var name=‘kenn‘
var hi={
name:‘keny‘,
fun1:function(){
console.log(this.name);
},
fun2:function(){
setTimeout(()=>{this.fun1()},100);
}
};
hi.fun2(); //keny
1.6.2 在函数内部使用 _this = this
var name=‘kenn‘
var hi={
name:‘keny‘,
fun1:function(){
console.log(this.name);
},
fun2:function(){
var _this=this;
setTimeout(function(){
_this.fun1();
},100);
}
};
hi.fun2(); //keny
1.6.3 使用 apply、call、bind
var name=‘kenn‘
var hi={
name:‘keny‘,
fun1:function(){
console.log(this.name);
},
fun2:function(){
setTimeout(function(){
this.fun1()
}.call(hi),100); //}.apply(hi),100); //,}.bind(hi),100);
}
};
hi.fun2(); //keny
1.6.3.1 apply() 方法调用一个函数, 其具有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数,fun.apply(thisArg, [argsArray])
1.thisArg:在 fun 函数运行时指定的 this 值。需要注意的是,指定的 this 值并不一定是该函数执行时真正的 this 值,如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。
2.argsArray:一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数。如果该参数的值为null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。浏览器兼容性请参阅本文底部内容。
1.6.3.2 call()方法。apply 和 call 基本类似,他们的区别只是传入的参数不同。fun.call(thisArg[, arg1[, arg2[, ...]]])。apply 和 call 的区别是 call 方法接受的是若干个参数列表,而 apply 接收的是一个包含多个参数的数组。
1.6.3.3 bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。
1.6.4 new 实例化一个对象
js this, call, apply 和 bind