穷究JavaScript——闭包

观点

  闭包是指能够援用外部函数中的部分变量的函数,并致使外部函数调用后函数对象与部分变量没法实时烧毁。函数是JavaScript中唯一具有本身作用域的组织,因而闭包的建立依赖于函数。

 var Foo = function() {
     var name = 'staven';
     this.getName = function() {
         return name;
     };
 };
 var foo = new Foo();
 console.log(foo.name);             //undefined
 console.log(foo.getName());     //staven

闭包中的轮回

   作用域链的这类设置机制引出了一个值得注意的副作用,即闭包只能取得包括函数中任何变量的末了一个值。

for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i);  //10次输出10
    }, 1000);
}

  为了准确的取得轮回序号,最好运用自实行匿名函数。

for(var i = 0; i < 10; i++) {
    (function(e) {
        setTimeout(function() {
            console.log(e);  
        }, 1000);
    })(i);
}

闭包中的this

  匿名函数的实行环境具有全局性,因而其 this 对象一般指向 window(在经由过程 call()或 apply()转变函数实行环境的情况下, this 就会指向其他对象)。

var name = '全局';
var obj = {
    name: '部分',
    getName: function(){
        var that = this;
        return function(){
            return that.name;
        }
    }
};
console.log(obj.getName()());   //部分

  把外部作用域中的 this 对象保留在一个闭包能够接见到的变量里,就能够让闭包接见该对象了。

var name = "全局";
var obj = {
    name: "部分",
    getName: function() {
        var that = this;
        return function() {
            return that.name;
        };
    }
};
console.log(obj.getName()());  //"部分"

闭包的作用

模仿块级作用域:

  只需我们暂时须要一些变量,都能够运用块级作用域(私有作用域)。当匿名函数实行终了,其作用域链马上烧毁,从而能够削减闭包占用资本题目。

(function($, window, document, undefined){
    var name = "staven";
    $.fn.getName = function(){
        
    };
})(jQuery, window, document);
在内存中保留变量:

  缓存数据、柯里化

模仿私有属性和私有要领:
//应用闭包完成
var Book = (function(){
    //静态私有变量
    var bookNum = 0;
    //静态私有要领
    function checkBook(name){
        console.log("checking Book……");
    }
    //建立类
    function _book(newId, newName, newPrice){
        if(this instanceof _book){
            //私有变量
            var name, price;
            //私有要领
            function checkID(id){
                console.log("checking id……");
            }
            //特权要领
            this.getName = function(){};
            this.getPrice = function(){};
            this.setName = function(){};
            this.setPrice = function(){};
            //公有属性
            this.id = newId;
            //公有要领
            this.copy = function() {
                console.log("copying……")
            };
            bookNum++;
            if(bookNum > 100){
                throw new Error('我们仅出书100本书');
            }
            //组织器
            this.setName(name);
            this.setPrice(price);
        }else{
            return new _book(newId, newName, newPrice);
        }
        
    }
    //构建原型
    _book.prototype = {
        //静态共有属性
        isJSBook:false,
        //静态共有要领
        show:function(){
            console.log("showing……");
        }
    };
    //返回类
    return _book;
})();
Book(21,'staven',23).show();        //showing……
Book(21,'staven',23).copy();        //copy……
var book = new Book(21,'staven',23);
book.show();    //showing……
book.copy();    //copying…… 

  因为闭包会照顾包括它的函数的作用域,因而会比其他函数占用更多的内存。过分运用闭包可能会致使内存占用过量,发起只在相对必要时再斟酌运用闭包。

    原文作者:staven
    原文地址: https://segmentfault.com/a/1190000008619562
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞