# this 指向
概括:
- 全局作用域下的函数:window
- 匿名函数:window
- 对象属性方法:当前对象
- 作为构造函数调用:实例化的对象
- 箭头函数:定义该函数时所在的作用域指向的对象
# 全局函数中
全局声明式函数中, this 指代全局对象 window
var x = 2;
function test() {
var x = 1;
console.log(this.x);
}
test(); // 2
# 匿名函数中
匿名函数的执行环境具有全局性,this 对象通常指向 window 对象
// 匿名函数作为返回值被调用
var name = "The Window";
var obj = {
name: "My obj",
getName: function() {
return function() {
console.log(this.name);
};
}
};
obj.getName()(); // 'The Window'
// 匿名函数作为setInterval、setTimeout的参数
setInterval(function() {
console.log(this); // 'Window'
}, 300);
# 对象属性方法
函数作为对象属性方法调用, this 当前对象,数组同理
// 普通对象
var obj = {
name: "obj",
func1: function() {
console.log(this);
}
};
obj.func1(); // this--->obj
// 元素对象
document.getElementById("div").onclick = function() {
console.log(this);
}; // this--->div
# 构造函数中
作为构造函数调用,this 指代 new 实例化的对象
function Animal() {
this.x = 1;
}
var o = new Animal();
alert(o.x); // 1
# 箭头函数中
es6 箭头函数的 this
下面是普通函数的列子:
var name = "window"; // 其实是window.name = 'window'
var A = {
name: "A",
sayHello: function() {
console.log(this.name);
}
};
A.sayHello(); // 输出A
var B = {
name: "B"
};
A.sayHello.call(B); //输出B
A.sayHello.call(); //不传参数指向全局window对象,输出window.name也就是window
从上面可以看到,sayHello 这个方法是定义在 A 对象中的,当当我们使用 call 方法,把其指向 B 对象,最后输出了 B;可以得出,sayHello 的 this 只跟使用时的对象有关。
改造一下:
var name = "window";
var A = {
name: "A",
sayHello: () => {
console.log(this.name);
}
};
A.sayHello(); // 还是以为输出A ? 错啦,其实输出的是window
分析
我相信在这里,大部分同学都会出错,以为 sayHello 是绑定在 A 上的,但其实它绑定在 window 上的,那到底是为什么呢?
一开始,我重点标注了“该函数所在的作用域指向的对象”,作用域是指函数内部,这里的箭头函数,也就是 sayHello,所在的作用域其实是最外层的 js 环境,因为没有其他函数包裹;然后最外层的 js 环境指向的对象是 winodw 对象,所以这里的 this 指向的是 window 对象。
那如何改造成永远绑定 A 呢:
var name = 'window';
var A = {
name: 'A',
sayHello: function(){
var s = () => console.log(this.name)
return s//返回箭头函数s
}
}
var sayHello = A.sayHello();
sayHello();// 输出A
var B = {
name: 'B';
}
sayHello.call(B); //还是A
sayHello.call(); //还是A
OK,这样就做到了永远指向 A 对象了,我们再根据“该函数所在的作用域指向的对象”来分析一下:
该函数所在的作用域:箭头函数 s 所在的作用域是 sayHello,因为 sayHello 是一个函数。
作用域指向的对象:A.sayHello 指向的对象是 A。
总结:箭头函数体内的 this 对象,就是定义该函数时所在的作用域指向的对象,而不是使用时所在的作用域指向的对象。
如题
var x = 3;
var y = 4;
var obj = {
x: 1,
y: 6,
getX: function() {
var x = 5;
return (function() {
return this.x;
})();
},
getY: function() {
var y = 7;
return this.y;
}
};
console.log(obj.getX()); // 3
console.log(obj.getY()); // 6
var a = 10;
var obt = {
a: 20,
fn: function() {
var a = 30;
console.log(this.a);
}
};
obt.fn(); // 20
obt.fn.call(); // 10
说明:部分总结来源于各社区,资料仅用来学习,如有侵权,请 联系我
参考