欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Javascript作用域和作用域链

程序员文章站 2024-02-17 16:35:52
...

作用域

作用域就是一个独立的地盘,让变量不会外泄、暴露出去。也就是说作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。
ES6 之前 JavaScript 没有块级作用域,只有全局作用域函数作用域。ES6 的到来,为我们提供了‘块级作用域’,可通过新增命令 let 和 const 来体现。
全局作用域

  1. 最外层函数 和在最外层函数外面定义的变量拥有全局作用域
var outVariable = "我是最外层变量"; //最外层变量
function outFun() { //最外层函数
    var inVariable = "内层变量"; //内层变量
    function innerFun() { //内层函数
        console.log(inVariable);
    }
    innerFun();
}
  1. 所有末定义直接赋值的变量自动声明为拥有全局作用域
function outFun2() {
    variable = "未定义直接赋值的变量";
    var inVariable2 = "内层变量2";
}
outFun2();
console.log(variable); //未定义直接赋值的变量
console.log(inVariable2); //inVariable2 is not defined
  1. 所有 window 对象的属性拥有全局作用域
    函数作用域
    是指声明在函数内部的变量,和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部。
function doSomething(){
    var blogName="浪里行舟";
    function innerSay(){
        alert(blogName);
    }
    innerSay();
}
alert(blogName); //脚本错误
innerSay(); //脚本错误

作用域是分层的,内层作用域可以访问外层作用域的变量,反之则不行。
Javascript作用域和作用域链
泡泡 1 是全局作用域,有标识符 foo;
泡泡 2 是作用域 foo,有标识符 a,bar,b;
泡泡 3 是作用域 bar,仅有标识符 c

作用域链

1. *变量
如下代码中,console.log(a)要得到 a 变量,但是在当前的作用域中没有定义 a(可对比一下 b)。当前作用域没有定义的变量,这成为 *变量 。*变量的值如何得到 —— 向父级作用域寻找

var a = 100
function fn() {
    var b = 200
    console.log(a) // 这里的a在这里就是一个*变量
    console.log(b)
}
fn()

2.什么是作用域链
如果父级也没呢?再一层一层向上寻找,直到找到全局作用域还是没找到,就宣布放弃。这种一层一层的关系,就是 作用域链 。

var a = 100
function F1() {
    var b = 200
    function F2() {
        var c = 300
        console.log(a) // *变量,顺作用域链向父作用域找
        console.log(b) // *变量,顺作用域链向父作用域找
        console.log(c) // 本作用域的变量
    }
    F2()
}
F1()

3.*变量取值的歧义

var x = 10
function fn() {
  console.log(x)
}
function show(f) {
  var x = 20
  (function() {
    f() //10,而不是20
  })()
}
show(fn)

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

相关标签: 前端 javascript