title | date | tags | categories |
---|---|---|---|
this指向哪去了? |
2017-12-12 10:54:01 -0800 |
JavaScript |
JavaScript |
我们知道ES5中的坑众多,尤其是
this
的只想问题,应该算是其中一个大坑了😣,今天总结一下关于this
的指向问题,以及如何改变它们的指向,并对call
、apple
和bind
进行区分。
很简单,this就是调用的那个对象,其实就是父级对象, 举个栗子:
var a = {
b:'zyy',
c:function(){
console.log(a.b);//zyy
}
}
a.c();
想在我们看到能打印zyy,可是我们要是把a换个名字,就会显示a未定义了,所以我们把它写成this指向父级,就不会发生这种错误了,这就是this。
var aaaa = {
b:'zyy',
c:function(){
console.log(this.b);//zyy
}
}
aaaa.c();
其实乍一看可能觉得this的指向会有些混乱,但是我们只要记住一个真理-->this
永远指向最后调用它的那个对象
,我们的问题就会迎刃而解。
我们下面简单看几个例子。
var name = 'zyy';
var log = function(){
console.log(this.name);//zyy
console.log(this);//Window
}
log();
在上面我们看到,this指向的就是Window,为什么呢?因为我们说过,它永远指向最后调用的对象,而Window正是这个全局变量,所以指向Window。
var people = {
name:'zyy',
log:function(){
console.log(this.name);//zyy
console.log(this);//people
}
}
people.log();
从这个例子中我们看到,我们调用的log函数是people这个对象中的,所以不出意外,this指向最后调用的对象本身。
即使现在你把调用改为了
window.people.log();
它也仍然会是以上的结果,因为最后调用的对象还是没变。
还是回归上面的代码,我们定义一个变量:
var people = {
name:'zyy',
log:function(){
console.log(this.name);//zyy
console.log(this);//Window
}
}
var f = people.log
f();
这时候你会发现:夭寿了!!!,this指向又变成全局对象了!
为什么!!!
因为**this
永远指向最后调用它的那个对象
**,这里没有对象调用,所以又默认了全局对象。
所以我们调用ajax的时候,为什么回调函数我们要加一个var self = this
,因为函数调函数的时候,我们的this丢失了指向,通过这种方法我们可以找回指向。
通过这几个例子我们�只要记住,�找最后调用对象,就能找到指向。
注意,在严格模式下,�指向全局对象会显示�undefined。
var name = 'zyyWin';
var people = {
name:'zyy',
log:function(){
var self = this;
(function() {
console.log(this.name);//>>> zyyWin
console.log(this);//>>> window
console.log(self.name);//>>> zyy
console.log(self);//>>> people
})();
}
}
people.log();
显示:
VM8067:7 zyyWin
VM8067:8 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
VM8067:9 zyy
VM8067:10 {name: "zyy", log: ƒ}
我在函数内部套了个自调用函数,通过self赋值this,这样最后调用时,就指向了people。
var name = 'zyyWin';
var people = {
name:'zyy',
log:function(){
(() => {
console.log(this.name);//>>> zyy
console.log(this);//>>> people
})();
}
}
people.log();
显示:
VM8255:6 zyy
VM8255:7 {name: "zyy", log: ƒ}
关于箭头函数,只需记住,“箭头函数中的this是在定义函数的时候绑定,而不是在执行函数的时候绑定”。
继承已经介绍了call
的使用方法,具体我要过一阵子在区分一下。
实例化this指向会改变,我们也在原型和继承已经说过了,就不过多赘述了。