zoukankan      html  css  js  c++  java
  • JavaScript 中的不可变对象(Immutable Objects)

      默认情况下,JavaScript 中的对象是可变的。我们可以更改原始值(字符串,数字等)和对象。我们来看看这个对象:

    let obj = {
        num: 10,
        obj: {
            content: "mutable object"
        }
    }

      你可以轻松地改变它:

    obj.num = 5;
    obj.obj = { content: "changed!" }
     
    console.log(obj);
     
    // {
    //     num: 5,
    //     obj: {
    //         content: "changed!"
    //     }
    // }

      非常明确是吧?那么,我们有什么办法使对象不可变呢?

    1、让我们试用 const !

      很好的尝试,但是不起作用。如果你尝试一下,你会发现:这种办法根本就不起作用。const 关键字只是修改了某个变量名和其值之间的链接,而不是实际值。您仍然可以像上面所做的那样在 const 对象中更改这两个原始值和对象。例如:

    const obj = {
        num: 10,
        obj: {
            content: "mutable object"
        }
    }
     
    obj.num = 5;
    obj.obj = { content: "changed!" }
     
    console.log(obj);
     
    // {
    //     num: 5,
    //     obj: {
    //         content: "changed!"
    //     }
    // }

    2、继续尝试:Object.freeze()。

      有很多关于 ES2015 新特性的文章和讨论。我们知道 ES2015 比 ES5 更好。例如,我们可以使用一个Object 方法来实现我们的目的:Object.freeze()。该方法使对象的原始属性不可变。我们把这个方法应用到我们原来的 obj 对象上:

    Object.freeze(obj);
    obj.num = 5;
    obj.obj = { content: "changed!" }
     
    console.log(obj);
     
    // {
    //     num: 10,
    //     obj: {
    //         content: "changed!"
    //     }
    // }

      结果比原先的尝试稍后好一点,原始值现在已经修复,不可更改,但是我们仍然可以更改嵌套对象。

    3、最终解决方案

      为了使对象完全不可变,我们还需要freeze()所有的嵌套对象。例如:

    function deepFreeze(obj) {
        var propNames = Object.getOwnPropertyNames(obj);
        propNames.forEach(function(name) {
            var prop = obj[name];
            if (typeof prop == 'object' && prop !== null) {
                deepFreeze(prop);
            }
        });
        return Object.freeze(obj);
    }

      使用这个函数,现在我们可以创建完全不可变的对象:

    deepFreeze(obj);
    obj.num = 5;
    obj.obj = { content: "changed!" }
     
    console.log(obj);
     
    // {
    //     num: 10,
    //     obj: {
    //         content: "mutable object"
    //     }
    // }

    总结:

      采用递归freeze()所有嵌套对象

  • 相关阅读:
    注释神器
    Q币直充-迅银渠道商(php 面向对象类)
    rsync 同步多台服务器项目目录
    wdcp 打开网页显示 Apache 2 Test Page powered by CentOS -- 来自辉哥博客
    elasticsearch批量修改,批量更新某个字段
    Ik分词器没有使用---------elasticsearch-analysis-ik 5.6.3分词问题
    spring-boot-starter-data-elasticsearch 整合elasticsearch 5.x详解
    FastJson--SerializerFeature.PrettyFormat 如何实现格式化源码查看
    由Premature end of Content-Length delimited message body因发的问题排查
    JVM的YoungGC日志查看
  • 原文地址:https://www.cnblogs.com/goloving/p/7679569.html
Copyright © 2011-2022 走看看