首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >JavaScript的闭包(closure)是什么?

JavaScript的闭包(closure)是什么?

原创
作者头像
Learn-anything.cn
发布2021-11-27 07:06:08
发布2021-11-27 07:06:08
5680
举报
文章被收录于专栏:learn-anything.cnlearn-anything.cn
一、闭包是什么?

闭包(closure)就是通过嵌套函数的方式,缓存嵌套函数及其执行环境,等待下一次调用。直观的说就是形成一个不销毁的栈环境。这样可以保护变量和方法,使其私有化。


1、私有化变量
代码语言:txt
复制
function makeFunc() {
    var name = "Mozilla";
    function displayName() {
        alert(name);
    }
    return displayName;
}
// 闭包隐藏了变量name,myFunc无法直接访问
var myFunc = makeFunc();

// 只能通过执行闭包,来访问name
myFunc();
2、缓存执行环境
代码语言:txt
复制
function makeAdder(x) {
    return function (y) {
        return x + y;
    };
}

// 闭包的执行环境被缓存,也就是x的值和嵌套函数被缓存在add5
var add5 = makeAdder(5);

// 调用执行闭包,输出结果:7
console.log(add5(2));

3、数据封装与隐藏

JavaScript中没有Java中private关键字,但可以用闭包来实现,做到对数据的隐藏和封装。

代码语言:txt
复制
// 成功的隐藏了 变量(privateCounter) 和 方法(changeBy)
var makeCounter = function () {
    var privateCounter = 0;
    function changeBy(val) {
        privateCounter += val;
    }
    return {
        increment: function () {
            changeBy(1);
        },
        decrement: function () {
            changeBy(-1);
        },
        value: function () {
            return privateCounter;
        }
    }
};

var Counter1 = makeCounter();
var Counter2 = makeCounter();
console.log(Counter1.value()); /* logs 0 */
Counter1.increment();
Counter1.increment();
console.log(Counter1.value()); /* logs 2 */
Counter1.decrement();
console.log(Counter1.value()); /* logs 1 */
console.log(Counter2.value()); /* logs 0 */

4、性能优化

如果不是特殊需求,在函数中创建函数是不明智的,因为闭包需要消耗更多CPU和内存资源,对脚本性能有负面影响。当创建新的对象时,应该在 prototype 中定义方法,而不是对象构造器。因为每一次创建对象,都要重新赋值构造器中的方法。

代码语言:txt
复制
// 比较糟糕的使用闭包的方式,
// 因为每一次 new MyObject,都会重新赋值getName和getMessage
function MyObject(name, message) {
    this.name = name.toString();
    this.message = message.toString();
    this.getName = function () {
        return this.name;
    };

    this.getMessage = function () {
        return this.message;
    };
}
代码语言:txt
复制
// 推荐使用这种方式,替代上面。
// prototype 是所有MyObject对象共享的,无需重新赋值getName和getMessage
function MyObject(name, message) {
    this.name = name.toString();
    this.message = message.toString();
}
MyObject.prototype.getName = function () {
    return this.name;
};
MyObject.prototype.getMessage = function () {
    return this.message;
};

二、参考文档:

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、闭包是什么?
    • 1、私有化变量
    • 2、缓存执行环境
    • 3、数据封装与隐藏
    • 4、性能优化
  • 二、参考文档:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档