本文详解JavaScript中this关键字的四种指向场景:对象调用指向所属对象,独立函数调用指向全局对象,构造函数使用new时指向新实例,以及通过apply、call或bind强制绑定指定对象。结合代码示例解析其工作原理。
JavaScript中this关键字的四种指向规则详解
this
函数运行时,this 的指向由调用该函数的对象决定。判定 this 归属,即确认函数所属主体。
《JavaScript语言精粹》将 this 场景归纳为四类,简述如下:
存在调用对象时指向该对象 无调用对象时指向全局对象 使用 new 构造时指向新实例 通过 apply、call 或 bind 指定指向。
函数有所属对象时:指向所属对象
1) 函数具备所属对象:指向该对象
当函数通过 . 表达式调用且拥有所属对象时,this 即指向该对象。示例如下:
var myObject = {value: 100};
myObject.getValue = function () {
console.log(this.value); // 输出 100
// 输出 { value: 100, getValue: [Function] },
// 其实就是 myObject 对象本身
console.log(this);
return this.value;
};
console.log(myObject.getValue()); // => 100
getValue() 方法归属于 myObject 对象,并由 myObject 通过 . 调用,故 this 指向 myObject。
函数没有所属对象:指向全局对象
2) 函数无所属对象:指向全局对象
var myObject = {value: 100};
myObject.getValue = function () {
var foo = function () {
console.log(this.value) // => undefined
console.log(this);// 输出全局对象 global
};
foo();
return this.value;
};
console.log(myObject.getValue()); // => 100
代码块中,foo 函数虽定义在 getValue 内部,但既不属于 getValue 也不属于 myObject。因 foo 未绑定至任何对象,调用时其 this 指向全局 global。
此行为被视为设计缺陷。
构造器中的 this:指向新对象
3) 构造器内的 this:指向新对象
在 JavaScript 中,使用 new 关键字调用构造函数时,this 将绑定至新创建的对象。
var SomeClass = function(){
this.value = 100;
}
var myCreate = new SomeClass();
console.log(myCreate.value); // 输出100
补充说明:在 JS 中,构造函数、普通函数、对象方法及闭包之间界限模糊,区分主要取决于人为定义。
apply 和 call 调用以及 bind 绑定:指向绑定的对象
4) apply、call 调用及 bind 绑定:指向指定对象
apply() 方法接收两个参数:第一个为函数执行的作用域,第二个为参数数组 (arguments)。
call() 方法的第一个参数含义与 apply() 一致,其余参数需逐一列举。
简言之,call 方式更贴近常规函数调用,而 apply 需传递数组形式参数。二者可相互转换。
var myObject = {value: 100};
var foo = function(){
console.log(this);
};
foo(); // 全局变量 global
foo.apply(myObject); // { value: 100 }
foo.call(myObject); // { value: 100 }
var newFoo = foo.bind(myObject);
newFoo(); // { value: 100 }
以上即为本文全部内容,希望读者喜爱。