this
JS中的this是什么
this是和执行上下文绑定的,也就是说每个执行上下文都有一个this
执行上下文主要分为三种——全局执行上下文、函数执行上下文、eval执行上下文
所以**this也对应着三种——全局执行上下文的this、函数中的this、eval中的this**
全局执行上下文中的this
全局执行上下文中的this很简单,就是指向window对象
这也是this和作用域链的唯一交点,作用域链的最底端包含了window对象,全局执行上下文中的this也指向window对象
函数执行上下文中的this
我们可以通过三种方式来设置函数执行上下文中的this值
通过函数的call方法设置
let bar = {
myName : " 极客邦 ",
test1 : 1
}
function foo(){
this.myName = " 极客时间 "
}
foo.call(bar)
console.log(bar)
console.log(myName)
在这里,foo函数内部的this已经指向了bar对象,打印bar可以发现,myName属性已经变成极客时间了
全局打印myName,则提示未定义
除了call,bind和apply也可以设置函数执行上下文中的this
通过对象调用方法设置
var myObj = {
name : " 极客时间 ",
showThis: function(){
console.log(this)
}
}
myObj.showThis()
在这里,执行showThis打印出来的this其实是myObj
使用对象来调用内部的一个方法,该方法的this是指向对象本身的
现在再来看一个例子:
var myObj = {
name : " 极客时间 ",
showThis: function(){
this.name = " 极客邦 "
console.log(this)
}
}
var foo = myObj.showThis
现在将这个showThis函数赋给一个全局对象,然后调用该对象
这时候会发现this又指向了全局window对象
所以,可以得到一个结论:
在全局环境中调用一个函数,函数内部的 this 指向的是全局变量 window
通过一个对象来调用其内部的一个方法,该方法的执行上下文中的 this 指向对象本身
通过构造函数中设置
function CreateObj(){
this.name = " 极客时间 "
}
var myObj = new CreateObj()
这段代码中,this的指向应该是新创建出来的myObj
其实在这其中,new关键字做了以下四件事:
- 首先创建了一个空对象
tempObj - 接着调用
CreateObj.call方法,并将tempObj作为call方法的参数,这样当CreateObj的执行上下文创建时,它的this就指向了tempObj对象; - 然后执行
CreateObj函数,此时的CreateObj函数执行上下文中的this指向了tempObj对象; - 最后返回
tempObj对象
所以构造函数中的this其实就是新对象本身
this的设计缺陷以及应对方案
嵌套函数中的this不会从外层函数中继承
var myObj = {
name : " 极客时间 ",
showThis: function(){
console.log(this)
function bar(){console.log(this)}
bar()
}
}
myObj.showThis()
这里函数showThis中的this指向的是myObj对象,而**bar中的this指向的却是全局对象window**
要解决这个问题,我们有两个解决方案:
-
使用变量
self保存this利用变量的作用域机制传递给嵌套函数
var myObj = { name : " 极客时间 ", showThis: function(){ console.log(this) var self = this function bar(){ self.name = " 极客邦 " } bar() } } myObj.showThis() console.log(myObj.name) console.log(window.name) -
使用箭头函数
箭头函数没有自己的执行上下文,所以会继承调用函数中的
thisvar myObj = { name : " 极客时间 ", showThis: function(){ console.log(this) var bar = ()=>{ this.name = " 极客邦 " console.log(this) } bar() } } myObj.showThis() console.log(myObj.name) console.log(window.name)
普通函数的this默认指向全局对象window
在默认情况下调用一个函数,其执行上下文中的this默认指向全局对象window
这个问题可以通过call方法来显示调用
也可以通过设置JS的严格模式来解决,在严格模式下,默认执行一个函数,这个函数的执行上下文中的this值就是undefiend