一、首先要了解js中作用域链
1.执行环境
1.执行环境的定义(也称为执行上下文):简单来说就是当前js代码在解析和执行时所在的环境。在一个执行环境中,有一个与之关联的变量对象(简称对象),在该对象中,存储着这个执行环境中定义的变量和函数;但这个对象是抽象的,并不能被外界所访问到。
2.那么在js中,就只有两种执行环境:
- 一个是window的全局执行环境:这个是默认的代码执行环境,一旦代码被载入,引擎最先进入的就是这个环境。例如,我们在全局运行下列代码,那么当前的执行环境就是 window ,也就是全局,在该环境中关联的对象中存储着定义的变量,也就是 color 。
<script>
var color = 'red'
console.log(color);
</script>
- 在JavaScript中,函数也会形成一个环境。看下面代码,在函数的内部就是一个局部的环境,与该环境关联的对象中存储着变量 mycolor,而在全局环境中 color和 app函数就是该环境关联对象中存储的 变量和 函数。
<script>
//全局环境下
var color = 'red'
console.log(color);
function app() {
//函数环境内
var mycolor = 'green'
console.log(mycolor);
}
app();
</script>
2.作用域链
1.在了解了上面的执行环境后,换个角度思考:那么函数环境内能不能访问全局环境下的变量呢?
看下列代码:
<script>
//全局环境
var color = 'red'
console.log(color);
function app() {
//局部环境
var mycolor = 'green'
console.log(mycolor + '---' + color)
}
app();
console.log(color + '---' + mycolor)
</script>
打印结果:
可以看到结果是可以的,但是在全局环境下访问函数环境内的变量却报错。
作用域链的概念:当代码在一个环境中执行的时候,会针对环境中存储变量和函数的对象创建一个作用域链,作用域链的最前端就是当前环境的对象;如果当前环境是个函数,则作用域链的下一部分就是全局 window环境的变量对象。 而window环境的变量对象始终都是作用域链中最后一个对象。
分析一下代码:
首先 app()执行,app函数内的执行环境会 先访问内部的变量,然后找到了mycolor变量,但是没找到color变量,因为app是个函数,所以它的作用域链还会延申到全局window下,所以由于作用域链在全局下寻找color变量;
再看window环境下的代码:
console.log(color + '---' + mycolor)
首先会在window环境中寻找到color变量,然后开始寻找mycolor但是没有找到,所以会沿着作用域链往下寻找;因为在window环境下,所以此时作用域链已经到达了尾部,不会再向下寻找了,所有就不能访问到 color变量。
现在应该可以大概了解作用域链概念了&#x