this 为何而生
随着你的使用模式越来越复杂,显示传递上下文对象会让代码变得越来越乱,使用 this 这不会。
this 提供了一种更优雅得方式来隐式“传递”一个对象引用,因此可以将 API 设计得更加简洁并且易于复用。
this 在任何情况下都不指向函数的词法作用域,this 实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。
把人绕晕的题目
开发者往往会把理解 this 的过程复杂化,并把它作为进阶中高级开发者的门槛。即使是非常有经验的 JavaScript 开发者也很难说清楚它到底指向什么。
var fullName = 'a';
var obj = {
fullName: 'b',
prop:{
fullName: 'c',
getFullName: function(){
console.log(this);
return this.fullName
}
}
}
console.log(obj.prop.getFullName());
var test = obj.prop.getFullName;
console.log(test());
console.log(obj.prop.getFullName())
严格来说 getFullName()
函数不属于 obj
对象,但调用位置会使用 obj
上下文来引用函数。
//console.log(this);
{fullName: "c", getFullName: ƒ}
c
当 getFullName()
函数被调用时,obj
对象包含了它,隐式绑定规则会把函数调用的 this 绑定到 obj
上下文,因此 this
和 obj.prop
是一样的;
console.log(test())
a
test 变量通过别名的方式引用了 getFullName()
函数,此时 test()
是一个不带任何修饰的函数调用,因此应用了默认绑定 ,this 指向全局对象
var num = 1;
var myObject = {
num: 2,
add: function() {
this.num = 3;
(function() {
console.log(this.num);
this.num = 4;
})();
console.log(this.num);
},
sub: function() {
console.log(this.num)
}
}
myObject.add();
console.log(myObject.num);
console.log(num);
var sub = myObject.sub;
sub();
myObject.add()
add
函数中含有匿名函数,在匿名函数中 this 被重新绑定到全局对象,所以匿名函数中的 this 是 window
;最后修改 window.num
为 4
1
add
函数执行时 隐式绑定 到 myObject
上下文,一般情况下此时的 this 就是 myObject
;
this.num = 3;
率先将 myObject.num
赋值为 3
3
console.log(myObject.num)
add
函数执行后修改了 myObject.num
为 3
3
console.log(num)
这里的 num
指的是 window.num
,add
函数中的匿名函数执行后修改了 window.num
为 4
4
sub()
sub 变量是 myObject.sub()
函数的引用,此时 sub()
是一个不带任何修饰的函数调用,因此应用了默认绑定 ,this 指向全局对象,即是 window.num
;
4