删除属性
一般 delete 只能删属性,如果要删其他的最好不要用delete
删除属性的语法
/* 语法1 */delete obj.xxx/* 语法2 */delete obj['xxx']
区分「属性值为 undefined」和「不含属性名」
定义一个名为
obj的对象,并给它属性name,属性值为undefinedvar obj = {'name': undefined}
此时,
obj含有属性name,name并没有被删除,只不过其值为undefined'xxx' in obj && obj.xxx === undefine:含有属性名,但是值为undefined

【注意】
**obj.xxx === undefined**
- 不能断定 ‘xxx’ 是否为 obj 的属性
- 这只能判断属性值,不能判断属性名,要判断属性名只能用
in图示:
如何检测是否为属性
- 把属性名作为字符串,然后
in这个对象即可。 'xxx' in obj === false:检测'xxx'是否为对象obj的属性
查看所有属性(读属性)
查看自身所有属性
Object.keys(obj) // 查看所有 keyObject.values(obj) // 查看所有 valueObject.entries(obj) // 查看所有 key 和 value
查看自身 + 共有属性
console.dir(obj)
或者自己依次用 Object.keys 打印出 obj.proto
判断一个属性是自身还是共有的
obj.hasOwnProperty('toString')
如果为 false 就说明这个属性不是它自身的,有可能是原型上的,也有可能不存在。
查看单个属性
/* 中括号语法 */obj['key']/* 点语法 */obj.key/* 坑新人语法 (若属性名是一个变量) */obj[key]
优先使用中括号语法
- 点语法会误导人以为 key 不是字符串
- 确定不会弄混两种语法后,再改用点语法
【注意】:
obj.name等价于obj['name']obj.name不等价于obj[name]- 简单来说,这里的 name 是字符串,而不是变量
let name = 'frank' obj[name]等价于obj['frank']- 而不是
~~obj['name'] 和 obj.name~~
修改或增加属性(写属性)
- 读属性的时候会看隐藏属性对应的原型
- 写属性(改/增)的时候不走原型,只能写到属性自身身上
直接赋值
/* 语法一 */obj.name = 'tk'/* 语法二 */obj['name'] = 'tk'/* 神奇的写法 */obj['na' + 'me'] = 'tk'/* 使用变量的写法 */let key = 'name'obj[key] = 'tk'
错误的语法:
obj[name] = 'tk' // 错,因 name 是变量,值不确定let key = 'name'; obj[key] = 'frank' // 正确写法let key = 'name'; obj.key = 'frank' // 错,因为 obj.key 等价于 obj['key']
批量赋值
Object.assign(obj, {age: 18, gender: 'man'})
修改或增加共有属性
无法通过自身修改或增加共有属性
let obj = {}, obj2 = {}// 共有 toStringobj.toString = 'xxx'只会在改 obj 自身属性-
硬要修改或增加原型上的共有属性
obj.__proto__.toString = 'xxx'// 不推荐用 protoObject.prototype.toString = 'xxx'- 一般来说,不要修改原型,会引起很多问题
修改隐藏属性
不推荐使用 proto
let obj = {name:'frank'}let obj2 = {name: 'jack'}let common = {kind: 'human'}obj.__proto__ = commonobj2.__proto__ = common
推荐使用 Object.create
let obj = Object.create(common)obj.name = 'frank'let obj2 = Object.create(common)obj2.name = 'jack'规范大概的意思是,要改就一开始就改,别后来再改
原型和共有属性的区别?
- 原型是对象
- 共有属性是属性
- 原型包含了所有共有属性(共有属性依附在原型这个对象上)
| 红圈为原型
蓝线画的是一个个共有属性 |
|
| —- | —- |
总结
删
delete obj['name']'name' in obj// falseobj.hasOwnProperty('name')// false查
Object.keys(obj)console.dir(obj):通过目录的形式看它自身的、它原型的、它原型的原型的所有属性obj['name']:查看单个属性obj.name// 这里的 name 是字符串-
改
改自身:
obj['name'] = 'jack'- 批量改自身:
Object.assign(obj, {age:18, ...}) - 改共有属性:
obj.__proto__['toString'] = 'xxx' - 改共有属性:
Object.prototype['toString'] = 'xxx' - 改原型:
obj.__proto__ = common - 改原型:
let obj = Object.create(common) - 注:所有 proto 代码都是强烈不推荐写的
增
- 基本同上:已有属性则改;没有属性则增。
部分资料来源:饥人谷 - 方方老师

