资讯专栏INFORMATION COLUMN

JS基础-闭包

Scliang / 3118人阅读

摘要:如果不用的话,你实际上声明了一个全局变量闭包有权访问另一个函数作用域的变量,常见的创建方式就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。

变量作用域

变量的作用域无非就是两种:全局变量和局部变量。

函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!

闭包

有权访问另一个函数作用域的变量,常见的创建方式就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。

简单的说就是,闭包就是能够读取其他函数内部变量的函数

由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。

MDN中定义的是:

闭包是指能够访问自由变量的函数。换句话说,在闭包中定义的函数可以“记忆”它被创建的环境。

注:自由变量是既不是在本地声明又不作为参数传递的一类变量。

简单的例子

function A(){
    function B(){
        console.log("Hello Closure!");
    }
    return B;
}

var b = A();
b();//Hello Closure!

所以通过这个例子可以简单理解闭包。

* 定义一个函数A()
* A中定义了函数B()
* A中返回B
* 执行A(),把A的返回结果赋值给变量b
* 执行b()   

总结一句话:函数A的内部函数B被函数A外的一个变量b引用。所以当一个内部函数被其外部函数之外的变量引用时,就形成了一个闭包

闭包的作用

在一个模块中定义一个变量,希望这个变量保存在内存中又不会污染全局变量,就用闭包来定义这个模板。

它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

闭包的注意点

闭包优点,也是缺点,局部变量驻留在内存中,可以回避使用全局变量,但由于闭包里的资源不会被立刻销毁回收,所以可能占用更多的内存,过度使用闭包会导致性能下降。

闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

注意:可以使用之后,给它加null,接触引用。

举例

例子1:

var name = "The Window"; // 全局
var object = {    
    name: "My Object", // 局部
    getNameFunc: function () { // 对象中的方法,this指向obj这个对象      
        return function () { // 闭包       
            return this.name; // this指向window    
        };     
    } 
};
     
alert(object.getNameFunc()()); // The Window

例子2:

var name = "The Window"; // 全局
var object = {    
    name: "My Object", // 局部
    getNameFunc: function () { // 对象中的方法,this指向obj这个对象 
        var that = this; // 将getNameFunc()的this保存在that变量中      
        return function () { // 闭包   
            return that.name; // that指向object    
        };     
    } 
};
     
alert(object.getNameFunc()()); // My Object

例子3:

var name = "The Window"; // 全局
var object = {    
    name: "My Object", // 局部
    getNameFunc: function () {   
        return function () { // 闭包   
            var that = this;  
            return that.name;     
        };     
    } 
};
     
alert(object.getNameFunc()()); // The Window

例子4:

var name = "The Window"; // 全局
var object = {    
    name: "My Object", // 局部
    getNameFunc: function () { // 对象中的方法,this指向obj这个对象      
        return function () { // 闭包   
            var that = this; // 将getNameFunc()的this保存在that变量中 
            return that.name; // this指向window    
        };     
    } 
};
     
alert(object.getNameFunc().call(object)); // My Object call改变this指向

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

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

相关文章

  • JS函数的一些基础知识

    摘要:为了更好的讲解构造函数原型原型链等,我们需要复习一下函数的一些基础知识。闭包在复习了函数的相关基础知识之后,我们终于可以进入闭包。我们可以这样理解闭包,首先,闭包是一个函数,是一个什么样子的函数呢是一个可以访问另一个函数中变量的函数。 为了更好的讲解构造函数、原型、原型链等,我们需要复习一下函数的一些基础知识。接下来,就让我们一起回味一些JS的基础知识点。 全局变量VS局部变量 简单粗...

    Ashin 评论0 收藏0
  • JS基础知识:变量对象、作用域链和闭包

    摘要:前言这段时间一直在消化作用域链和闭包的相关知识。而作用域链则是这套规则这套规则的具体运行。是变量对象的缩写那这样放有什么好处呢我们知道作用域链保证了当前执行环境对符合访问权限的变量和函数的有序访问。 前言:这段时间一直在消化作用域链和闭包的相关知识。之前看《JS高程》和一些技术博客,对于这些概念的论述多多少少不太清楚或者不太完整,包括一些大神的技术文章。这也给我的学习上造成了一些困惑,...

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

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

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

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

    XFLY 评论0 收藏0

发表评论

0条评论

Scliang

|高级讲师

TA的文章

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