掘金 阅读 ( ) • 2024-04-26 17:40

theme: channing-cyan

前言

作用域(Scope)在编程中是指变量和函数的可访问性和可见性的范围。在JavaScript中,作用域定义了变量和函数在代码中的可访问范围。作用域规定了在代码中的哪些位置可以访问某个变量或函数,以及在这些位置如何解析变量名。作用域控制着变量的生命周期以及其在代码中的可见性。其中作用域分为全局作用域,函数作用域和块级作用域,内层作用域是可以访问外层作用域的,反之,则不行

全局作用域

代码演示

var a = 1;

对于上述的代码进行的步骤:

  • 词法分析:词法单元:var,a,=,2
  • 解析:将词法单元=转换成一个 逐级嵌套 的程序语法结构树 --- 抽象语法树
  • 生成代码:var a = 2

有效标识符:a

函数作用域

代码演示

function foo(b) {
    var b = 2;
    console.log(b);
}

有效标识符:b

综合代码

var b;

function foo(a) {
  function bar(a){
    return a - 1;
  };
   b = a + bar(a * 2);
    console.log(b * 3);
};

foo(2);

image.png

  • 全局作用域的有效标识符:b,foo(2)
  • foo函数作用域的有效标识符:a,bar()
  • bar函数作用域的有效标识符:a

分析:当执行b = a + bar(a * 2);时,该bar函数作用域没有a,那么这个时候内层作用域是可以访问外层作用域的,就去foo函数作用域,查找到a=2,此时就可以执行,则b=5。

块级作用域

代码演示

if (true) {
    let a = 1;
}
    console.log(a);

image.png

分析:报错是因为{let/const}这种形式会形成块级作用域,并且外层不能访问内层,所以报错。

小知识

自执行函数 (立即执行函数)

(function() {
   var a = 3;
   console.log(a);
})();

image.png

声明提升

console.log(a);

var a = 1;//声明提升

image.png

分析:此时没有报错,因为var具有声明提升,上面的代码相当于:

var a;
console.log(a);
var a = 1;

注意:如果将上述的代码中的var改为let,将报错,因为var可以重复声明变量,let不可以。

let a;
console.log(a);
let a = 1;

image.png

image.png let VS var

  • var存在声明提升,let不存在
  • let会和{}形成块级作用域
  • var可以重复声明变量,let不可以

const:定义的为常量,不可改值

const a = 1; // 常量
a = 2;
console.log(a);

image.png

欺骗词法作用域

  • eval():将原本不属于这里的代码变成就像天生就定义在这里一样
function foo(str ,a) {
  eval(str);//var b = 3
  console.log(a ,b);
};

var b = 2;
foo('var b = 3', 1);

image.png

  • with():用于修改一个对象中的属性值,但如果修改的属性在原对象中不存在,那么该属性就会被泄露到全局
var obj = {
    a:1,
    b:2,
    c:3
};

with (obj) {
  a = 3,
  b = 4,
  c = 5
}

console.log(obj);

image.png

function foo(obj) {
   with(obj){
    a = 2;
   }
};

var o2 = {
    b: 3
};

foo(o2);
console.log(o2);
console.log(a);

image.png

结语

希望能给需要的人带来一点小小的帮助,喜欢的话,记得一键三连哦~

image.png