快捷搜索: 王者荣耀 脱发

作用域与作用域链学习笔记


作用域指程序中定义变量的区域,它决定了当前执行代码对变量的访问权限。 作用域就是一个独立的地盘,让变量不会外泄、暴露出去,也就是说 作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。

全局作用域和函数作用域

全局作用域的情况

    最外层函数和在最外层函数外面定义的变量拥有全局作用域。 所有未定义直接赋值的变量拥有全局作用域。 所有window对象的属性拥有全局作用域

全局作用域有个弊端:如果我们写了很多行 JS 代码,变量定义都没有用函数包括,那么它们就全部都在全局作用域中。这样就会 污染全局命名空间, 容易引起命名冲突。

// 不带var的情况,相当于给window对象设置一个属性
// 1
console.log(a, b)
var a =12, b =林一一
function foo(){
          
   
// 2
    console.log(a, b)
// 3
    var a = b =13
    console.log(a, b)
}
foo()
console.log(a, b)

/* 输出:
    undefined undefined
    undefined "林一一"
    13 13
    12 13
*/

函数作用域

是指声明在函数内部的变量,和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部。

值得注意的是:块语句(大括号“{}”中间的语句),如 if 和 switch 条件语句或 for 和 while 循环语句,不像函数,它们不会创建一个新的作用域。

块级作用域

块级作用域可通过新增命令let和const声明,所声明的变量在指定块的作用域外无法被访问。在大括号中使用let和const声明的变量存在于块级作用域中。在大括号之外不能访问这些变量。

    声明变量不会提升到代码块顶部 禁止重复声明 循环中的绑定块作用域的妙用
for (let i = 0; i < 10; i++) {
          
   
  // ...
}
console.log(i);
// ReferenceError: i is not defined

作用域链

当前作用域没有定义的变量,这称为 自由变量 。

Javascript的作用域也可以嵌套,Javascript引擎会层层遍历作用域来寻找用到的变量,这种一层一层的关系就是 作用域链。

取自由变量x的值时,要到哪个作用域中取?——要到创建fn函数的那个作用域中取,无论**fn**函数将在哪里调用。

var x = 10
function fn() {
          
   
  console.log(x)
}
function show(f) {
          
   
  var x = 20
  (function() {
          
   
    f() //10,而不是20
  })()
}
show(fn)
var a = 10
function fn() {
          
   
  var b = 20
  function bar() {
          
   
    console.log(a + b) //30
  }
  return bar
}
var x = fn(),
  b = 200
x() //bar()
//fn()返回的是bar函数,赋值给x。执行x(),即执行bar函数代码。取b的值时,直接在fn作用域取出。取a的值时,试图在fn作用域取,但是取不到,只能转向创建fn的那个作用域中去查找,结果找到了,所以最后的结果是30
经验分享 程序员 微信小程序 职场和发展