前言
最近参加若川的源码共度活动,第 24 期 vue2 源码工具函数,最开始:
var emptyObject = Object.freeze({});
之前知道 Object.freeze() 是冻结,可是具体是什么呢,错过了就错过了,要不看看吧,那就看看吧,嗯,我这种读源码的方式比较低效,但是还是得看看,不然后面的都不易于理解,就暂且打打基础。
然后就看了MDN Web Docs Object.freeze()
Object.freeze()
Try it
Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性
,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。
可枚举型、可配置性、可写性,啥意思,要不搜搜?嗯,搜搜。
然后找到了这个js 对象中什么是可枚举性(enumerable)?
看完了这篇,懂了 enumerable,那可配置性呢,继续搜。
找到了这篇JavaScript 属性的可迭代、可修改和可配置特性。
看了一半,有原文链接Javascript properties are enumerable, writable and configurable也看看。
看过中文,英文看着还可以理解。
由于看过第一篇,所以第二篇的标题写错了,加上原文链接是 enumerable,所以,enumerable 是可枚举型,并不是可迭代性 iterable。
所以引用 MDN Web Docs 里的名字,JavaScript 的可枚举性、可配置性、可写性
是什么意思呢?
现总结如下。
阅读《js 对象中什么是可枚举性(enumerable)?》有感
读后感
-
讲 JS 对象的属性的可枚举性(属性的 enumerable):
如果为 false,(for..in 循环、Object.keys 方法、JSON.stringify 方法)这三个操作不会取到该属性。
- 我的示例
// 1. 一个没隐式原型的对象a,没有继承性,因为对象a太美了。a自己有 aa aaa aaaa 三个属性 let a = Object.create(null); a.aa = 1; a.aaa = 2; a.aaaa = 3; // 2. 弄一个对象b,b继承了a的美貌。b自己也有 b bb bbb 仨属性。 let b = Object.create(a); b; b.b = "b1"; b.bb = "b2"; b.bbb = 333; // 3. for...in 循环,发现了对象 b 拥有 b bb bbb 和 a aa aaa 一共六个属性的值,属性就是什么方面美,值就是什么方面具体到多少,a4腰,1.8米大长腿。 for (let key in b) { console.log(b[key]); } // for...in 循环 // b1 // b2 // 333 // 1 // 2 // 3 // 4. Object.keys() 列出 对象的 属性什么方面美。 Object.keys(b); // ['b', 'bb', 'bbb'] // 5. JSON.stringify() 列出了 对象b 拥有 的属性和值,{腰:a4,腿:1.8m} JSON.stringify(b); // '{"b":"b1","bb":"b2","bbb":333}' // 6. enumerable 是枚举的,列出,上面 3 4 5 都罗列了 对象b 的属性及其值,所以是可枚举性。 // 7. Object.getOwnPropertyNames() 罗列 对象b 所有属性(包括 可枚举性属性 & 不可枚举性属性),发现:b bb bbb 都是可枚举属性,因为是[.key]的方式定义的嘛。 Object.getOwnPropertyNames(b); // ['b', 'bb', 'bbb'] // 8. Object.defineProperty() 新建 | 修改属性。因为 b 没有 属性 bbbb,所以给对象b定义新属性bbbb,值34,设置属性bbbb具有不可枚举性。 Object.defineProperty(b, "bbbb", { value: 34, enumerable: false }); // {b: 'b1', bb: 'b2', bbb: 333, bbbb: 34} // 9. 罗列b的属性key,发现没有bbbb,因为上面设置了enumerable为false Object.keys(b); // (3) ['b', 'bb', 'bbb'] // 10. 获取 对象b 的 光明正大定义的属性 和悄悄定义的属性。 Object.getOwnPropertyNames(b); // (4) ['b', 'bb', 'bbb', 'bbbb']
收获
-
Object.freeze 对象后,对象属性不能添加,不能删除,不能给对象以.key 方式修改值,不能给对象以 Object.defineProperty(obj,key9,{value:val9,enumerable:false})方式修改值。
-
for...in 循环的 key 是自己的属性和原型链上的属性们,所以深拷贝的时候 for...in 循环里要判断 if(obj.hasOwnProperty(key)){ result[key] = deepClone(obj[key])}。
-
Object.keys 方法:得到对象自己的属性数组,不包含原型链上的属性。
-
Object.getOwnPropertyNames 方法得到对象 b 的自己及原型链上的属性。
-
JSON.stringify 方法将 obj 序列化为 JSON 字符串,也是自己的属性,跟 Object.keys 一样,不包括原型链上的属性。
-
上面 2、3、5 :
都得不到不可枚举性(使用 Object.defineProperty 方法给对象赋值并设置可枚举型 enumerable 为 false)的属性。 -
上面 4 :
Object.getOwnPropertyNames 方法可以得到不可枚举性的属性的数组。 -
上面 6、7 即:
for...in 循环、Object.keys 方法、JSON.stringify 方法 这仨只能得到枚举性属性,得不到不可枚举性的属性(悄悄的属性得不到);
Object.getOwnPropertyNames 方法 可以得到不可枚举型(悄悄的属性可得)
-
上面所有的意思
(对于 Object.freeze 来说):Object.freeze 冻结对象后,增加属性、删除属性、光明正大修改属性、悄悄修改属性,都不可以!
参考链接
Javascript properties are enumerable, writable and configurable
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?