资讯专栏INFORMATION COLUMN

浅谈javascript作用域

leiyi / 2663人阅读

摘要:理解作用域作用域负责收集并维护由所有声明的变量组成的集合,等待引擎的查找。当遇到时,编译器会询问作用域是否存在变量。词法作用域就是定义在词法阶段的作用域。但函数不是唯一的作用域单元。块作用域属于某个代码块通常指内部。

理解作用域

作用域负责收集并维护由所有声明的变量组成的集合,等待引擎的查找。

var a = 2;
console.log(a);  // 2
console.log(b);  // ReferenceError: b is not defined

var a = 2 可以分解为var a; a = 2。当遇到var a时,编译器会询问作用域是否存在变量a。如果存在,则忽略该声明,否则会在当前作用域的集合中声明一个新的变量a

遇到a = 2时,引擎会询问当前作用域是否存在变量,如果未找到,则会继续在上级作用域查找。如果最终找到就会将2赋值给变量a

console.log(a)时,引擎会去作用域中查找 a,找到把结果返回,输出2, console.log(b)时,引擎未在作用域查找到b,抛出异常。

LHS和RHS查询

可以看出"L"和"R"分别代表左侧和右侧,即赋值的左侧和右侧。赋值不只是=的赋值,函数参数的传递也是一种赋值操作。

var a = 2;  // LHS查询,a出现在赋值左侧
console.log(a);  // RHS查询, a出现在赋值右侧,将变量a赋值给参数

查询失败会出现什么情况
对于LHS查询a = 2 若a未找到,在非严格模式下并不会报错,而变量 a 会被自动创建。而对于 RHS 来说,直接使用未声明的变量就会报 ReferenceError。

console.log(b);  // ReferenceError: b is not defined
词法作用域

作用域主要有两种工作模型:词法作用域和动态作用域。
词法作用域就是定义在词法阶段的作用域。换句话说,词法作用域是由你写代码时变量和块作用域写在哪决定的。

function foo(a) {
    var b = a * 2;
    function bar(a) {
        console.log(a, b, c);
    }
    bar(b*3);
}
foo(2);

在这个例子有三个逐级嵌套的作用域。

全局作用域,包含一个标识符:foo

foo所创建的作用域,包含三个标识符:a, bar, b

bar所创建的作用域,包含一个标识符:c

函数作用域

函数作用域是指属于这个函数的变量都可以在整个函数范围内使用和复用。

function fn() {
    var a = 2;
    console.log(a);  // 2
}

console.log(a); // ReferenceError: a is not defined

从中可以看出,函数外部将无法访问函数内部的变量。

块作用域

ES6引入letconst将变量绑定到所在块作用域(通常是{...}内部)

{
    let a = 2;
    console.log(a);  // 2
}
console.log(a);  // ReferenceError: a is not defined

letconst外,withtry/catchcatch分句会创建一个块作用域。

小结

函数是Javascript中最常见的作用域单元。但函数不是唯一的作用域单元。块作用域属于某个代码块(通常指{...}内部)。
接下来会讲解提升和闭包两个概念。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105163.html

相关文章

  • 浅谈Javascript闭包中作用及内存泄漏问题

    摘要:将作用域赋值给变量这里的作用域是,而不是将作用域赋值给一个变量闭包返回浏览器中内存泄漏问题大家都知道,闭包会使变量驻留在内存中,这也就导致了内存泄漏。 上一章我们讲了匿名函数和闭包,这次我们来谈谈闭包中作用域this的问题。 大家都知道,this对象是在运行时基于函数的执行环境绑定的,如果this在全局就是[object window],如果在对象内部就是指向这个对象,而闭包却是在运行...

    source 评论0 收藏0
  • 浅谈JavaScript闭包

    摘要:但是函数返回了内部函数,内部函数会随时访问变量所以垃圾回收机制是不会回收函数的内部作用域的,这就是闭包的含义。也就是函数在定义的词法作用域以外的地方被调用,闭包使得函数可以继续访问定义时的词法作用域。   初学JavaScript闭包时,闭包这个概念在我眼里及其的神秘,也不知道这个东西在讲什么,尤其某些地方的闭包概念定义的非常抽象,属于那种本来你可能明白这个概念,看了反而又把你给绕糊涂...

    hsluoyz 评论0 收藏0
  • 云天视角-浅谈闭包

    摘要:函数在执行的时候执行函数,将当前的变量对象由于当前的环境是函数,所以将其活动对象作为变量对象添加到作用域链的前端。此时,由于在执行,而作用域链也存在,所以可以在作用域链上进行查找,去访问的变量。 一、现状 闭包是jser绕不过的坎,一直在都在说,套用 simpson 的话来说:JavaScript中闭包无处不在,你只需要能够识别并拥抱它。 闭包是基于词法作用域书写代码时的自然结果,你甚...

    nanfeiyan 评论0 收藏0
  • 浅谈JavaScript作用

    摘要:我们在面试时,总会碰到一些奇奇怪怪的关于作用域的面试题,其实弄清楚原理,万变不离其宗,大部分的面试题都可以得姐。 showImg(https://segmentfault.com/img/bV7Cri?w=1563&h=879); 我们在面试时,总会碰到一些奇奇怪怪的关于 作用域 的面试题,其实弄清楚原理,万变不离其宗,大部分的面试题都可以得 ‘姐’。 所以,今天我们来谈谈 JavaS...

    figofuture 评论0 收藏0
  • 浅谈JavaScript中的闭包

    摘要:在内部,理所当然能访问到局部变量,但当作为的返回值赋给外的全局变量时,神奇的事情发生了在全局作用域中访问到了,这就是闭包。而闭包最神奇的地方就是能在一个函数外访问函数中的局部变量,把这些变量用闭包的形式放在函数中便能避免污染。 一、闭包是什么? 《JavaScript高级程序设计》中写道:闭包是指有权访问另一个函数作用域中的变量的函数,如果用下定义的观点看,这句话就是说闭包是函数,我...

    Riddler 评论0 收藏0

发表评论

0条评论

leiyi

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<