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

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

1.png


前言


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


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


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


  • 首先,定义一个符合要求的对象:


// 声明成绩存储对象
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 如果作动词,那它的解释就是“密封”:


2.png


见名知意,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()


~本文完,感谢阅读!


学习有趣的知识,结识有趣的朋友,塑造有趣的灵魂!


你来,怀揣期望,我有墨香相迎! 你归,无论得失,唯以余韵相赠!


知识与技能并重,内力和外功兼修,理论和实践两手都要抓、两手都要硬!




相关文章
|
20天前
|
Web App开发 JavaScript 前端开发
如何确保 Math 对象的方法在不同的 JavaScript 环境中具有一致的精度?
【10月更文挑战第29天】通过遵循标准和最佳实践、采用固定精度计算、进行全面的测试与验证、避免隐式类型转换以及持续关注和更新等方法,可以在很大程度上确保Math对象的方法在不同的JavaScript环境中具有一致的精度,从而提高代码的可靠性和可移植性。
|
1月前
|
缓存 监控 前端开发
JavaScript 实现大文件上传的方法
【10月更文挑战第17天】通过以上步骤和方法,我们可以实现较为可靠和高效的大文件上传功能。当然,具体的实现方式还需要根据实际的应用场景和服务器要求进行调整和优化。
|
5天前
|
监控 JavaScript Java
Node.js中内存泄漏的检测方法
检测内存泄漏需要综合运用多种方法,并结合实际的应用场景和代码特点进行分析。及时发现和解决内存泄漏问题,可以提高应用的稳定性和性能,避免潜在的风险和故障。同时,不断学习和掌握内存管理的知识,也是有效预防内存泄漏的重要途径。
|
19天前
|
JavaScript 前端开发 索引
js中DOM的基础方法
【10月更文挑战第31天】这些DOM基础方法是操作网页文档结构和实现交互效果的重要工具,通过它们可以动态地改变页面的内容、样式和行为,为用户提供丰富的交互体验。
|
19天前
|
缓存 JavaScript UED
js中BOM中的方法
【10月更文挑战第31天】
|
8天前
|
JavaScript 前端开发
js中的bind,call,apply方法的区别以及用法
JavaScript中,`bind`、`call`和`apply`均可改变函数的`this`指向并传递参数。其中,`bind`返回一个新函数,不立即执行;`call`和`apply`则立即执行,且`apply`的参数以数组形式传递。三者在改变`this`指向及传参上功能相似,但在执行时机和参数传递方式上有所区别。
|
19天前
|
JavaScript 前端开发
.js方法参数argument
【10月更文挑战第26天】`arguments` 对象为JavaScript函数提供了一种灵活处理参数的方式,能够满足各种不同的参数传递和处理需求,在实际开发中具有广泛的应用价值。
36 7
|
20天前
|
JavaScript 前端开发 图形学
JavaScript 中 Math 对象常用方法
【10月更文挑战第29天】JavaScript中的Math对象提供了丰富多样的数学方法,涵盖了基本数学运算、幂运算、开方、随机数生成、极值获取以及三角函数等多个方面,为各种数学相关的计算和处理提供了强大的支持,是JavaScript编程中不可或缺的一部分。
|
25天前
|
JavaScript 前端开发 Go
异步加载 JS 的方法
【10月更文挑战第24天】异步加载 JavaScript 是提高网页性能和用户体验的重要手段。通过使用不同的方法和技术,可以实现灵活、高效的异步加载 JavaScript。在实际应用中,需要根据具体情况选择合适的方法,并注意处理可能出现的问题,以确保网页能够正常加载和执行。
|
20天前
|
JavaScript 前端开发 开发者