作用域的介绍:
我们在js中定义了一个变量,当变变量被使用时,就形成了一个作用域,看如下的实例
1:
* 变量使用及作用域问题
* 1:看表达式中变量在【自己的作用域】是否【声明】,只要自己的作用域中有var 变量 不论在哪里都可以,
* --------> 有 声明 那么该变量就会提升到当前作用域最顶端
* ------------->再看 使用变量时候 是否有【赋值】
* ----------------> 有 则用【该值】 无 【用undefine]
*
* --------> 没有声明 就去当前域的父域中找,直到全局域为止
* -----------> 无声明 报错 xxx is not define
* -----------> 有 声明 ---> 变量提升到 作用域顶部 -->再看是否赋值---> 无 【用undefined】有【用值】
*/
// 总结;一看是否声明;而看是否赋值。用 变量提升 作用域
// 注意: xxx = xx 变量xxx的作用域问题。
var c = 10
function fn() {
b = 20
console.log(b)
var b = 10
console.log(c)
return function fn2() {
console.log(a)
var a = 10
return a
}
}
var res = fn()
console.log(res)
function b() {
function c() {
b = 5
}
c()
console.log(b)
var b ;
}
b()
作用域链:
首先先来书面语来解释作用域和作用域链 [[scope]]指的就是我们所说的作用域 其中存储了 运行期上下文 的集合
运行期上下文就是所说的AO; 作用域链:[[scope]]中所存储的执行期上下文对象的集合 这个集合呈链式 链接
我们把这种链式链接叫做作用域链。 运行期上下文:当函数执行时 会创建一个称为 执行期上下文(AO) 的内部对象。
一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行
上下文都是独一无二的,所以多次调用一个函数会导致创建多个执行上下文,当函数 执行完毕,它所产生的执行上下文被销毁。
查找变量:从作用域链的顶端依次向下查找 (在哪个函数里面查找变量就去哪个函数的作用域链的顶端依次向下查找 )
根据我个人理解就是说作用域链就是在作用域中一层一层的查找,然后所形成的链就是作用域链了
看代码解释吧
1
2
function a(){
function b(){
function c(){
console.log('快乐的小二逼');
}
c()
}
b()
}
a()
执行的步骤
第一步 a被定义 a[[scope]] ---- 0:GO 第二步 a被执行 a[[scope]] ---- 0:AO 1:GO 第三步
b被定义 b[[scope]] ----- 0:a[[scope]].AO 1:a[[scope]].GO 第四步 b被执行
b[[scope]] ----- 0:AO 1:a[[scope]].AO 2:a[[scope]].GO 第五步 c被定义
c[[scope]] ----- b[[scope]] ----- 0:AO 1:a[[scope]].AO 2:a[[scope]].GO
第六步 c被执行 c[[scope]]----0:AO b[[scope]] ----- 0:AO 1:a[[scope]].AO
2:a[[scope]].GO
简单点的执行步骤
a defined a.[ [scope]] – > 0 : GO a doing a. [[scope]] – > 0 : aAO 1 :
GOb defined b. [[scope]] – > 0 : aAO 1 : GO b doing b. [[scope]] – > 0 :
bAO 1 : aAO 2 : GOFc defined C. [[scope]] – > 0 : bAO 1 : aAO 2 : GO C doing C. [[scope]]
– > 0 : CAO 1 : bA0 2 : aAO 3 : GO
再来个小例子吧
function a() {
function b() {
var bb = 234
aa = 0;
}
var aa = 123;
b()
console.log(aa);
}
var glob = 100;
a()
其实简单点来说就是说 内部函数查找变量的时候 它会先在自身里面找 如果自身没有
他就会向上一层查找 上一层没有 在向上查找 一直查找到全局 也就是函数体的外面
如果都没有 返回undefined