资讯专栏INFORMATION COLUMN

Javascript中的作用域与闭包

tianren124 / 1194人阅读

摘要:作用域分为词法作用域和动态作用域。这样就形成了一个链式的作用域。一般情况下,当函数执行完毕时,里面的变量会被自动销毁。而能够访问到这个在的编译阶段就已经定型了词法作用域。

什么是作用域?
在当前运行环境下,可以访问的变量或函数的范围。
作用域分为词法作用域动态作用域
词法作用域是在js代码编译阶段就确定下来的; 对应的,witheval语句会产生动态作用域。

会产生新的作用域的情况:

函数

{}(ES6)

eval

举个例子说明作用域

var a = "hello";
function f1(){
    var a = 1;
    console.log(a);
}
f1();  // 1
console.log(a); // hello

可以看到f1中的变量a只能在f1中有效,f1外部访问不到里面的a;所以在f1中的a,其作用域就只限定在f1中。

再来个新概念:作用域链

var a = "hello";
function f1(){
    console.log(a);// ps: f1中并未声明a
}
f1(); // hello

之所以输出hello, 是因为在f1中并未找到a的定义,此时程序并不会急于抛异常,而是会向调用f1的上一层寻找a的定义。如果没有,会继续再往上一层的上一层寻找,直到最顶层。
这样就形成了一个链式的作用域。

什么是闭包?

通常来讲,函数可以访问函数外面的变量;但是在函数外部,访问不到在函数里面定义的变量。

function f1(){
    var a = 1;
}
console.log(a);  // Uncaught ReferenceError: a is not defined

那么有没有可能访问到f1中的a呢?当然是有的, 看例子:

function f1(){
    var a = 1;
    function f2(){
        return a;
    }
    return f2;
}
var getA = f1();
console.log(getA()); // 1

我们在f1中,添加了一个函数f2(实际上f2就可以看做一个闭包)。
一般情况下,当函数执行完毕时,里面的变量会被自动销毁。但是因为我们把f2赋值给了外部的getA,所以f2不会被内存释放,同理f2中使用的a在f2的作用域中,也不会被释放,所以这个时候就可以访问到a。
而getA能够访问到a,这个在js的编译阶段就已经定型了(词法作用域)。

官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
相信很少有人能直接看懂这句话,因为他描述的太学术。其实这句话通俗的来说就是:闭包就是能够读取其他函数内部变量的函数。

闭包的特点
闭包可以在函数外部改变函数中的变量的值,如果你把函数作为对象、闭包作为方法、局部变量作为私有属性使用,则会改变该变量的值;闭包还会把函数中的变量的值存储于内存中,对内存消耗很大,所以滥用闭包的结果就是影响网页性能,IE中则可能导致内存泄露

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

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

相关文章

  • 你不知道的JavaScript上卷之作用域与闭包·读书笔记

    摘要:的分句会创建一个块作用域,其声明的变量仅在中有效。而闭包的神奇作用是阻止此事发生。依然持有对该作用域的引用,而这个引用就叫做闭包。当然,无论使用何种方式对函数类型的值进行传递,当函数在别处被调用时都可以观察到闭包。 date: 16.12.8 Thursday 第一章 作用域是什么 LHS:赋值操作的目标是谁? 比如: a = 2; RHS:谁是赋值操作的源头? 比如: conso...

    Raaabbit 评论0 收藏0
  • 《你不知道的javascript》笔记_作用域与闭包

    摘要:建筑的顶层代表全局作用域。实际的块级作用域远不止如此块级作用域函数作用域早期盛行的立即执行函数就是为了形成块级作用域,不污染全局。这便是闭包的特点吧经典面试题下面的代码输出内容答案个如何处理能够输出闭包方式方式下一篇你不知道的笔记 下一篇:《你不知道的javascript》笔记_this 写在前面 这一系列的笔记是在《javascript高级程序设计》读书笔记系列的升华版本,旨在将零碎...

    galaxy_robot 评论0 收藏0
  • Javascript重温OOP之作用域与闭包

    摘要:的变量作用域是基于其特有的作用域链的。需要注意的是,用创建的函数,其作用域指向全局作用域。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。 作用域 定义 在编程语言中,作用域控制着变量与参数的可见性及生命周期,它能减少名称冲突,而且提供了自动内存管理 --javascript 语言精粹 我理解的是,一个变量、函数或者成员可以在代码中访问到的范围。 js的变量作...

    JessYanCoding 评论0 收藏0
  • 先有蛋还是先有鸡?JavaScript 作用域与闭包探析

    摘要:而闭包的神奇之处正是可以阻止事情的发生。拜所声明的位置所赐,它拥有涵盖内部作用域的闭包,使得该作用域能够一直存活,以供在之后任何时间进行引用。依然持有对该作用域的引用,而这个引用就叫闭包。 引子 先看一个问题,下面两个代码片段会输出什么? // Snippet 1 a = 2; var a; console.log(a); // Snippet 2 console.log(a); v...

    elisa.yang 评论0 收藏0
  • Js基础知识(三) - 作用域与闭包

    摘要:是词法作用域工作模式。使用可以将变量绑定在所在的任意作用域中通常是内部,也就是说为其声明的变量隐式的劫持了所在的块级作用域。 作用域与闭包 如何用js创建10个button标签,点击每个按钮时打印按钮对应的序号? 看到上述问题,如果你能看出来这个问题实质上是考对作用域的理解,那么恭喜你,这篇文章你可以不用看了,说明你对作用域已经理解的很透彻了,但是如果你看不出来这是一道考作用域的题目,...

    lemanli 评论0 收藏0

发表评论

0条评论

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