在javascript中我们总是会遇到各种各样的this,由于this是在代码运行期确定的,它可以是全局对象、当前对象或者任意对象,这完全取决于this的调用方式。《javascript语言精粹》一书中将this的调用方式总结为以下四种:
- 作为对象方法调用
- 作为函数调用
- 作为构造函数调用
- apply或call 调用
在补充2点:
- ES5中引入的bind调用
- ES6中箭头函数里的this
下面我们将按照调用方式的不同,分别讨论 this 的含义。
作为对象方法调用
当一个函数被保存为对象的一个属性时,我们称它为一个方法。方法被调用时,this被绑定到该对象。通过this可取得所属对象的公有方法
var myObject = {
value:0,
increment:function(inc){
this.value += typeof inc === 'number' ? inc : 1;
console.log(this); //{value:1,increment:function(){}}
}
}
myObject.increment(); //作为对象方法调用
作为函数调用
当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用的,以此模式调用函数时,this被绑定到全局对象。
var myObject = {
value : 0,
double : function(){
var helper = function(){
console.log(this); //window
};
helper(); //作为函数调用
}
}
作为构造函数调用
如果一个函数前面带上new来调用,那么背地里将会创建一个连接到该函数的prototype成员的新对象,同时this会被绑定到那个新对象上。
function Quo(string){
this.status = string;
}
Quo.prototype.getStatus = function(){
return this;
}
var myQuo = new Quo("confused");
console.log(myQuo.getStatus()); //作为构造函数调用 this指向这个新对象Quo {status: "confused"}
apply或call 调用
apply方法允许我们构建一个函数数组传递给调用函数,也允许选择this的值
var statusObject = {
status: "ok"
};
function Quo(string){
this.status = string;
}
Quo.prototype.getStatus = function(){
return console.log(this); //{status: "ok"}
}
Quo.prototype.getStatus.apply(statusObject); //将方法中的this指向传入的对象
Quo.prototype.getStatus.call(statusObject); //将方法中的this指向传入的对象
通过bind调用
bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。
fun.bind(thisArg[, arg1[, arg2[, ...]]])
** 返回由指定的this值和初始化参数改造的原函数拷贝**
window.color = "red";
var o = {color:"blue"};
function sayColor(){
return this.color;
}
var objectSayColor = sayColor.bind(o); //此处将方法中的this指向了o对象
objectSayColor();//由于bind返回的是改造后的原函数的拷贝,并没有执行
箭头函数里的this
函数体内的 this 对象,是定义时所在的对象,而不是使用时所在的对象。
var handler = {
id: '123456',
init: function() {
document.addEventListener('click',event => this.doSomething(event.type), false);
},
doSomething: function(type) {
console.log('Handling ' + type + ' for ' + this.id);
}
};
上面代码的 init 方法中,使用了箭头函数,这导致这个箭头函数里面的 this ,总是指向 handler 对象。否则,回调函数运行时, this.doSomething 这一行会报错,因为此时 this 指向 document 对象。
this 指向的固定化,并不是因为箭头函数内部有绑定 this 的机制,实际原因是箭头函数根本没有自己的 this ,导致内部的 this 就是外层代码块
的 this 。正是因为它没有 this ,所以也就不能用作构造函数。
原文链接: https://jesse121.github.io/blog/articles/2017/07/08.html
版权声明: 转载请注明出处.