this是和执行上下文绑定的,也就是说每个执行上下文中都有一个 this
,执行上下文分为3种:
①全局执行上下文
②函数执行上下文
③eval执行上下文
所以对应的this
也只有这三种,全局执行上下文中的 this
、函数中的 this
和 eval
中的 this
局执行上下文中的 this
是指向 window
对象的
现在你已经知道全局对象中的 this
是指向 window
对象了,那么接下来,我们就来重点分析函数执行上下文中的 this
。还是先看下面这段代码:
function foo(){
console.log(this)
}
foo()
我们在 foo
函数内部打印出来 this
值,执行这段代码,打印出来的也是 window
对象(非严格模式),这说明在默认情况下调用一个函数,其执行上下文中的 this
也是指向 window
对象的。估计你会好奇,那能不能设置执行上下文中的 this
来指向其他对象呢?答案是肯定的。通常情况下,有下面三种方式来设置函数执行上下文中的 this
值。
你可以通过函数的 call
方法来设置函数执行上下文的 this
指向,比如下面这段代码,我们就并没有直接调用 foo
函数,而是调用了 foo
的 call
方法,并将 bar
对象作为 call
方法的参数
let bar = {
myName : “hk”,
test1 : 1
}
function foo(){
this.myName = “lcf”
}
foo.call(bar)
console.log(bar)
console.log(myName) // 报错 未定义 myName
执行这段代码,然后观察输出结果,你就能发现 foo
函数内部的 this
已经指向了 bar
对象,因为通过打印 bar
对象,可以看出 bar
的 myName
属性已经由“极客邦”变为“极客时间”了,同时在全局执行上下文中打印 myName
,JavaScript 引擎提示该变量未定义。
其实除了 call
方法,你还可以使用 bind
和 apply
方法来设置函数执行上下文中的 this
,它们在使用上还是有一些区别的,如果感兴趣你可以自行搜索和学习它们的使用方法,这里我就不再赘述了。
要改变函数执行上下文中的 this 指向,除了通过函数的 call 方法来实现外,还可以通过对象调用的方式,比如下面这段代码:
var myObj = {
name : "hk",
showThis: function(){
console.log(this)
}
}
myObj.showThis()