1.通常情况下
“ this
对象是在运行时基于函数的执行环境绑定的。在全局函数中,this
等于 Window
;而当函数被作为某个对象的方法调用时,this 等于那个对象。”
// 代码示例 1
function myContext() {
console.log(this);
}
myContext();
// Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
let obj1 = {
name: 'obj1',
myContext: function() {
console.log(this);
}
}
obj1.myContext();
// {name: "obj1", myContext: ƒ}
2.匿名函数中
匿名函数的执行环境具有全局性,因此其 this 对象通常指向 Window
。
// 代码示例 2
var obj = {
name: 'obj',
myContext: function() {
return function() {
console.log(this);
}
}
}
obj.myContext()();
// Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
3.闭包访问
闭包(匿名函数)情况下,如果想访问作用域中的 arguments
对象,必须将该对象的引用保存到另一个闭包能够访问的变量中。
// 代码示例 3
var name = 'window';
var obj = {
name: 'obj',
myContext: function() {
return function() {
console.log(this.name);
}
}
}
obj.myContext()();
// window
var obj = {
name: 'obj',
myContext: function() {
var that = this;
return function() {
console.log(that.name);
}
}
}
obj.myContext()();
// obj
4.特殊情况
// 代码示例 4
var name = 'The Window';
var obj = {
name: 'obj',
getName: function() {
console.log(this.name);
}
}
obj.getName();
// obj
(obj.getName = obj.getName)();
// The Window
上述代码示例 4 中两次执行结果不同。第二次执行的代码先执行了一条赋值语句,然后再调用赋值后的结果。因为这个赋值表达式的值是函数本身,所以 this
的值不能得到维持。???????????????
总结
一般情况下,this
对象的指向是由当前执行环境决定的。而匿名函数(闭包)的执行环境具有全局性,所以如果想要访问作用域中的 arguments
对象,可以将该对象的引用保存到闭包可以访问到的变量中。
同时要注意,语法的细微变化,都可能意外改变 this
的指向。
注:文章参考总结自 《JavaScript 高级程序设计》(第 3 版)[美] Nicholas C.Zakas 著 第 182 页。