You-Dont-Know-JS-学习笔记-Book2-ch2
Chapter 2: How Objects Work
对象是怎么工作的, 对象不仅仅是一些属性的容器,尽管这是对象最常用的使用场景。
新知识点: “metaobject protocol” MOP。 [wiki](https://en.wikipedia.org/wiki/Metaobject,
MOP 对于理解对象行为有很大帮助
Property Descriptors 属性描述
一个对象都会有一个属性的描述对象,这个对象也有一些属性来控制对应属性的行为Object.getOwnPropertyDescriptor(..)
是 ES5 提供的一个方法,可以获取属性的描述对象
1 | const obj = { |
同样的还有另一个方法 Object.defineProperty(..)
可以来定义这个属性的行为、值。这个方法不仅可以添加,也可以覆盖已经存在的属性。即使存在的属性 configurable = false
的情况。
1 | const obj = {} |
以上两个方法都有对应的 ”复数“ 方法,Object.getOwnPropertyDescriptors
, Object.defineProperties()
,
Accessor Properties 访问类型(访问器)属性
就是指 getter 、setter 类型的属性
1 | let user = { |
Enumerable, Writable, Configurable
对象属性(properties),除 value 外,还有三个特殊的特性(attributes),也就是所谓的“标志”:
writable — 如果为 true,则值可以被修改,否则它是只可读的。
是否可修改,控制这属性是否可以赋值修改(”=“),不过即使是fasle
,依然可以通过Object.defineProperty(..)
来重新赋值enumerable — 如果为 true,则会被在循环中列出,否则不会被列出。
是否可枚举属性,控制这属性是否可以展示,例如在Object.keys
Object.entries
for ...in循环
,以及在复制、赋值中:...解构
,Object.assign
,都会忽略,不可枚举的属性configurable — 如果为 true,则此属性可以被删除,这些特性也可以被修改,否则不可以。
是否可配置, 这里的配置指的是 重新定义、删除, 这里和writable
区别就在于,configurable: false
之后,即使使用Object.defineProperty
也无法修改,相当于 ”锁定“了,也就是说 可以从true/false -> false
, 但是无法从false -> true
.
Object Sub-Types 子类型
子类型中,最常见就是 array 和 function了。 function 在js 是比较特殊的一个类型
通过 “子类型”,我们指的是一个派生类型的概念,它继承了父类型的行为,但又专门化或扩展了这些行为。换句话说,这些子类型完全是对象,但也不仅仅是对象。
Arrays 数组
通过数字索引存储值的对象,通过访问 数字下标 来获取指定的值。像是一个所有属性都是数字的对象,而且黑一个数字定义一个非数字的属性也是合法的,但是非常不推荐这样做。
语法为 [...]
,例如: const arr = [1,2,3]
, 起始的下标为 0,
有一些细节点主要注意:
- 使用非数字类型访问
一般来说。普通对象会将 属性名 作为字符串对待,而 数组会将 他们当做 数字 对待
1 |
|
- 空元素
数组中可以存在“空元素”, 既不是null 也不是undefined, 虽然获取时返回 的是undefined
. 但实际上并不是。 在 each、map 方法去就可可以看到明显的区别,“空元素”是不会参与循环的, 会被忽略。
Function 函数
函数有两个属性,name、length, name 是函数的名字,length 是参数的数量,指该函数期望传入的参数数量,即形参的个数。也不报错剩余参数个数, 如果是匿名函数,name 就是个空的
函数也可以添加自定属性,应为他也是一个 Object。
1 | function myFunc(arg1, arg2, ...moreArgs){ |
作者不推荐在函数上使用自定义属性,推荐使用 Map/WeakMap
来替代。不过有一个库也会给函数增加一些属性,方便实现一些功能,仁者见仁智者见智把。
Object Characteristics 对象特征
- extensible 扩展
- sealed 密封
- frozen 冻结
Extensible
一个对象可否添加新的属性,默认所有对象都是可扩展的。Object.preventExtensions()
可以让一个对象变的不可扩展,也就是永远不能再添加新的属性。
1 | const obj = { |
Sealed
???
Frozen
一个对象是冻结的是指它不可扩展,所有属性都是不可配置的,且所有数据属性(即没有 getter 或 setter 组件的访问器的属性)都是不可写的。
一个不可扩展的空对象同时也是一个冻结对象。
Extending The MOP
???
to be continued
You-Dont-Know-JS-学习笔记-Book2-ch2
https://www.md7.top/2022/10/08/You-Dont-Know-JS-学习笔记-Book2-ch2/