函数闭包

函数的执行依赖于作用域,这个作用域时在函数定义时决定的,而不是函数调用时决定的。函数可以通过作用域链相互关联起来,函数体内部的变量都可以保存在函数作用域内,这种特性在计算机科学中就称之为“闭包”。可以说,所有的JavaScript都是闭包

首先熟悉作用域:

var scope = "global";
function constructFunction(){
    var scope = "local";
    function f(){return scope};
    return f();
}
constructFunction();    //local

在上述代码中,执行函数constructFunction,执行函数f,返回函数f的返回值,返回函数constructFunction的值。

作用

闭包可以从外部读取内部数据

var scope = "global";
function constructFunction(){
    var scope = "local";
    function f(){return scope};
    return f;
}
constructFunction()();  //local

JavaScript函数执行的过程中用到了作用域链,作用域链是在函数定义的时候创建的,嵌套函数f定义在作用域链中,其中的变量是局部变量,无论何时何地执行函数f(),这种绑定在执行时都是有效的。换言之,闭包可以捕捉到局部变量,并一直保存下来,看起来就像变量绑定到了在其中定义他们的外部函数

闭包不会破坏作用域链。

“外部函数定义的局部变量在函数返回之后就不存在了”这句话在JavaScript中是不对的。
每次调用函数的时候,就会创建一个新的对象来保存局部变量,把整合各对象添加到作用域中。当函数返回的时候,就从作用域链中将这个绑定变量的对象删除。如果不存在嵌套的函数,也没有其他引用指向这个绑定对象,那么他就会被垃圾回收。如果定义了一个嵌套函数,每个嵌套的函数都对应一个作用域链,并且这个作用域链指向一个变量绑定对象。但如果这些嵌套的函数对象在外部函数中保存下来,那么他们也会和所指向的变量绑定对象一样被垃圾回收。但是如果这个函数定义了嵌套函数,并将它作为返回值返回或者存储在某个属性中,这是就会有一个外部引用指向这个嵌套的函数,就不会被垃圾回收。

闭包的安全性:将变量放在函数内部,避免将变量重置。

var cnt = (function(){
    var count = 0;
    return function(){
        return count++;
    }
}());
cnt();  //0
cnt();  //1

内部私有属性的共享

//constfuncs方法循环创建了十个闭包,存储在数组中,由于这些闭包都是在同一个函数中定义的,所以函数中的变量i共享
function constfuncs(){
    var funcs = [];
    for(var i = 0; i < 10; i++){
        funcs[i] = function(){return i}
    }
    return funcs;
}
var funcs = constfuncs();
funcs[5]();

闭包使用注意事项:

  1. 大量的闭包会造成网页的性能问题,容易导致内存泄漏。
  2. 闭包可以改变外部函数的变量
  3. 需要注意this的指向,有调用对象指向对象,没有调用对象就指向window,举个栗子。
var name = "global";
var object = {
name : "local",
getNameFunc : function(){
    console.log(this);
    return function(){
        console.log(this);
        return this.name;
        };
    }
};  
console.log(object.getNameFunc()());

控制台输出如下:
object调用getNameFunc,这个时候this指向object,执行返回匿名函数function的引用,此时的执行环境就变成了全局,this指向了window。
这里写图片描述

修改:

var name = "global";
var object = {
name : "local",
getNameFunc : function(){
    var self = this;
    console.log(this);
    return function(){
        console.log(self);
        return self.name;
        };
    }
  };
console.log(object.getNameFunc()());

控制台输出:
这里写图片描述

关于JavaScript中的this

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值