首先要了解这两个概念,什么是词法作用域和动态作用域参考链接:词法作用域和动态作用域
采取文章重要部分,下面我们会用到
变量分为有this引用的变量和没有this引用的变量,没有this引用的变量也就可以从词法作用域中找到变量的值,也就是上面说的顺着作用域链去找就可以了。有this引用的,要顺着调用栈找。文章没有给出有this的情况,这里我们举一个例子一起分析。
先看下面代码:
let name='小王',age=16
let obj={
name:"小张",
objAge:this.age,
myFun:function(){
console.log(name,this.age)
}
}
let db={
name:"德玛",
age:99
}
obj.myFun()//name:小王
我们关注输出的name值,因为name没有this引用,所以我们可以按照作用域链来找出他的值,先分析作用域,js作用域分为全局作用域和函数作用域,所以我们可以这么划分,
明显作用域2里面没有name变量,往上找,只能找到name=‘小王’。所以我们就确定了name值。
下面我们看有this引用的情况:
let name='小王',age=16
let obj={
name:"小张",
objAge:this.age,
myFun:function(){
console.log(this.name,this.age)
}
}
let db={
name:"德玛",
age:99
}
obj.myFun()//name:小张
同样,我们只关注this.name,顺着调用栈来找this.name的值,调用this.name所在的函数的上一级是obj,所以this指向了obj,this.name就等于obj里面的name也就是‘小张’ 了。
这个是正常的情况,js中所有函数都自带可以改变this指向的方法,call,apply,bind,这种情况下,我们就看这些函数将this指向哪个对象了。比如下面代码:
let name='小王',age=16
let obj={
name:"小张",
objAge:this.age,
myFun:function(){
console.log(this.name,this.age)
}
}
let db={
name:"德玛",
age:99
}
obj.myFun.call(db)//name:"德玛"
这时候this指向通过call指向了db了,相当于db.name,所以等到了”德玛“。