最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 正经人一辈子都用不到的 JavaScript 方法总结 (二)

    正文概述 掘金(编程三昧)   2021-08-26   418

    这是我参与8月更文挑战的第25天,活动详情查看:8月更文挑战

    前言

    现在有这样一个需求:用一个对象存储某学生的各科成绩,要求每次只能改变科目分数,不能再添加或者删除科目。

    分析一下,这个需求其实就是需要创建一个固定属性的对象,其属性不可增删,但属性值可更改。

    有些同学可能就这么开始了:

    • 首先,定义一个符合要求的对象:
    // 声明成绩存储对象
    let reportObj = {};
    // 给成绩存储对象添加科目,并设置科目属性不可增删,但科目成绩可修改
    Object.defineProperties(reportObj, {
        ChineseMark: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: 60
        },
        EnglishMark: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: 60
        }
    });
    
    • 然后写入成绩:
    // 存入科目成绩
    reportObj.ChineseMark = 99;
    reportObj.EnglishMark = 95;
    console.log(reportObj);  // {ChineseMark: 99, EnglishMark: 95}
    

    删除属性来试试:

    delete reportObj.ChineseMark;  // false
    console.log(reportObj);  // {ChineseMark: 99, EnglishMark: 95}
    

    貌似确实符合条件了,那么再试试增加属性吧:

    reportObj.PhysicsMark = 100;
    console.log(reportObj);  // {ChineseMark: 99, EnglishMark: 95, PhysicsMark: 100}
    

    咋回事,怎么突然就不太符合要求了呢?Object.defineProperties() 只能精确控制所增添的属性的特质,但如果给对象添加属性的话,它就无力控制了。

    今天我们就用简单的接口方法来实现一下这幺蛾子需求 ︿( ̄︶ ̄)︿

    Object.seal()

    描述

    seal 如果作动词,那它的解释就是“密封”:

    正经人一辈子都用不到的 JavaScript 方法总结 (二)

    见名知意,Object.seal() 方法就是用来“密封”一个对象的,它阻止对象添加新属性,并将对象所有的现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变。

    作用

    通常,一个对象是可扩展的(可以添加新的属性)。

    密封一个对象会让这个对象变的不能添加新属性,且所有已有属性会变的不可配置。属性不可配置的效果就是属性变的不可删除,以及一个数据属性不能被重新定义成为访问器属性,或者反之。但属性的值仍然可以修改。

    尝试删除一个密封对象的属性或者将某个密封对象的属性从数据属性转换成访问器属性,结果会静默失败或抛出 TypeError(在严格模式 中最常见的,但不唯一)。

    const object1 = {
        property1: 42
    };
    
    Object.seal(object1);
    object1.property1 = 33;
    console.log(object1.property1);
    // expected output: 33
    
    delete object1.property1; // cannot delete when sealed
    console.log(object1.property1);
    // expected output: 33
    

    总结起来,Object.seal() 其实就是做了以下事情:

    • 设置Object.preventExtension(),禁止添加新属性(绝对存在)
    • 设置configurable为false,禁止配置(绝对存在)
    • 禁止更改访问器属性(getter和setter)

    语法

    Object.seal(obj)
    

    参数

    参数 obj 代表将要被密封的对象。

    返回值

    被密封的对象。

    实现需求

    既然有这么好用的方法,那我们当然要好好利用一番啦,终于可以完美实现文章开头的需求了:

    // 声明成绩存储对象及其属性
    let reportObj = {   
        ChineseMark: 60,
        EnglishMark: 60
    };
    // 密封成绩对象
    let sealedReportObj = Object.seal(reportObj);
    // 更改科目分数
    sealedReportObj.ChineseMark = 99;
    sealedReportObj.EnglishMark = 97;
    console.log(sealedReportObj); // {"ChineseMark": 99, "EnglishMark": 97}
    

    验证一下:

    // 增加属性
    sealedReportObj.PhysicsMark = 100;
    console.log(sealedReportObj); // {"ChineseMark": 99, "EnglishMark": 97}
    
    // 删除属性
    delete sealedReportObj.ChineseMark; // false
    console.log(sealedReportObj); // {"ChineseMark": 99, "EnglishMark": 97}
    

    可以看到对象的属性确实是增删不了了,算是简单实现了需求吧。

    扩展

    如果要判断一个对象是否“密封”,我们可以使用 Object.isSealed() 方法:

    Object.isSealed(sealedReportObj); // true
    

    Object.freeze()

    看到这里,可能很多同学都想起了 Object.freeze() 方法,它的作用是用来冻结一个对象。实际作用就是字面意思:冻结一个对象,使其属性和属性值都不可更改。用来实现这个需求显然是不合适的。

    共同点

    Object.seal()Object.freeze() 有以下共同点:

    • 作用的对象变得不可扩展,这意味着不能再添加新属性。
    • 作用的对象中的每个元素都变得不可配置,这意味着不能删除属性。
    • 如果在 ‘use strict’ 模式下使用,这两个方法都可能抛出错误。

    不同点

    Object.seal() 能让你修改属性的值,但 Object.freeze() 不能。

    总结

    以上就是关于 Object.seal() 方法的一些简单介绍和应用,以及它和 Object.freeze() 的异同点,希望能对大家有所帮助。

    ~

    ~本文完,感谢阅读!

    ~

    参考文档:

    Object.seal()

    Object.freeze()


    下载网 » 正经人一辈子都用不到的 JavaScript 方法总结 (二)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元