和其他语言不同,JavaScript的this总是指向一个对象,this
的“超级”延迟绑定决定了this
到对象的绑定发生在调用的时候,而非函数被声明时的环境。
在JavaScript中this
的值取决于调用模式,大致可以分为以下几种:
- 作为对象的方法调用
- 作为普通函数调用
- 作为内部函数调用
- 构造器调用
-
Function.prototype.call
或Function.prototype.apply
调用
作为对象的方法调用
当函数作为对象的方法被调用时,this指向该对象
const myObject={
value:1,
increment:function(inc){
this.value+=typeof inc === 'number' ?inc:1;
}
};
myObject.increment();
document.writeln(myObject.value); //2
myObject.increment(2);
document.writeln(myObject.value); //4
作为普通函数调用
当函数被作为普通函数调用时,this
被绑定到全局对象。在浏览器中,这个全局对象是window
window.value = 100;
const getGlobalValue = function () {
return this.value;
};
const myObject = {
value: 16,
getValue: function () {
return this.value;
}
};
const getName = myObject.getValue;
/*此时getName为普通函数
getName=function(){
return this.value;
}*/
document.writeln(getGlobalValue()); //函数式调用 100
document.writeln(getName()); //函数式调用 100
作为内部函数调用
window.value = 89;
const myObject = {
value: 45,
increment: function (inc) {
this.value += typeof inc === 'number' ? inc : 1;
},
double: function () {
const helper = function () {
document.writeln(this.value);
};
helper();//以函数的形式调用helper
}
};
//以方法的形式调用double
myObject.double(); //89
在内部函数中,this没有按预想的绑定到外层函数对象上,而是绑定到了全局对象。一般的处理方式是将this作为变量保存下来,一般约定为that
或者self
:
window.value = 89;
const myObject = {
value: 45,
increment: function (inc) {
this.value += typeof inc === 'number' ? inc : 1;
},
double: function () {
const that = this;
const helper = function () {
document.writeln(that.value);
};
helper(); //以函数的形式调用helper
}
};
//以方法的形式调用double
myObject.double(); //45
构造器调用
当用new运算符调用函数时,该函数总会返回一个对象,通常情况下,构造器里的this就指向返回的这个对象
const MyObject = function () {
this.value = 90;
};
const myObject = new MyObject();
document.writeln(myObject.value); //90
如果构造函数显式的返回一个对象,那么 this 则会指向该对象
const MyObject = function () {
this.value = 90;
return {
value: 120
}
};
const myObject = new MyObject();
document.writeln(myObject.value); //120
Function.prototype.call
或Function.prototype.apply
调用
call和apply可以动态的地改变传入函数的this
const object = {
value: 90,
getValue: function () {
document.writeln(this.value);
}
};
const newObject = {
value: 100
};
object.getValue(); // 90
object.getValue.call(newObject); //100
object.getValue.apply(newObject); // 100
参考资料:
https://segmentfault.com/a/1190000008757250
https://segmentfault.com/a/1190000000501212
https://segmentfault.com/a/1190000003046071
https://segmentfault.com/a/1190000004553064
网友评论