js中的作用域及作用域链 2021.11.17

js中的作用域层面:函数作用域 -> 块级作用域 -> 作用域链

1)函数作用域:早期,js中只有函数有作用域,函数用来划分全局和局部作用域。

function f(){
            var a = 1;
            console.log(a)  // 1
        }
        f()
        console.log(a) //undefined

2)块级作用域:es6之后,增加了块级语句{}的作用域,例如 if() { ... }、for() {...}、while() { ... } 、

(也就是说 现在除了函数的{}外,所有{}语句块都可以有作用域,块级作用域看成是函数

作用域的升级)

var和let的区别:

1)let 会创建块级作用域,var只在函数{}才有作用域;

2)var有声明提升,let没有;

3)var可以重复声明 语法可以通过,let不行;

4)var声明的全局变量会挂在到window上,而let不是;

var fns = [];
        for (var i = 1; i < 4; i++) {
            fns.push(function () {
                console.log(i);
            });
        }
        console.log(fns); // [func, func, func]
        // 函数执行时  for已经结束 此时的i是循环的最大值 4
        fns[1](); // 4 
var fns = [];
        for (let i = 1; i < 4; i++) {
         // let 会绑定作用域,将i限定在{}里面用,每次循环时 创建的i 都有属于自己的{}
         // 相当于有3个 {i:1 function () {log(i)}} {i:2 function () {log(i)}} {i:3}
         // 函数每次调用时 要使用所属的{i},也就是说let能够保留循环时i的值
            fns.push(function () {
                console.log(i);
            });
        }
        console.log(fns); // [func, func, func]
        fns[1](); // 2

// 全局变量a 它属于全局变量对象window,它的作用域就是全局,记作:window(a)

// 函数function体内的变量b,它属于激活对象fAO,它的作用域是fAO,记作:fAO(b)

// 这里要注意,fAO是函数调用时动态创建出来,并添加到function作用域链的头部,也就说:

// fAO(b) => f.fAO(b) => [根]window(a,f).fAO(b)[头]

var a = 1; // window(a)
function f () {
// window(a,f).fAO(a,b)
        var b = 2;
        var a = 2;
        console.log(b);  // 2
        console.log(a);  // 2
    }
 f();

// 组成变量作用域其实是一个对象链。如果要使用某个变量 则沿着作用域链头部查找,如果找到则返回 找不到继续往下 直到根部 - 变量名的解析

// 作用域链的机制:变量由内向外 查找

内部环境可以通过作用域链访问所有外部环境,但外部环境不能访问内部环境的任何变量和函数。

おすすめ

転載: blog.csdn.net/weixin_50163576/article/details/121385266