Object
奇怪的属性名
let obj = {
1e2: true,
1e-2: true,
.234: true,
0xFF: true
};
Object.keys(obj)
1e2对应'100'。
.234对应'0.234'。
0xFF对应'255'。
变量作属性名
let x = 'str'
let obj1 = {
x : 1
}
Object.keys(obj1)
let obj2 = {
[x] : 1
}
Object.keys(obj2)
- 如果想用变量的值作属性名,必须要用
[]将变量包裹起来。
- 不加
[]的属性名会自动变成字符串。
- 加了
[]则会当做变量求值。
“__proto__”属性和原型
“__proto__”属性
- JS中每一个对象都有一个隐藏属性__proto__。
- 所有Object都有它们的共有属性。
- 它们的共有属性存放的地址,是__proto__的属性值。
- 注意
- __proto__已经从 Web 标准中删除,虽然在一部分浏览器中还支持,但在未来可能会停止支持。
- 不同浏览器对于__proto__可能有不同的命名,它并不是一个统一规范的称呼。因此所有相关语句都不推荐写。
原型
- 对于Object来说,有一个包含且只包含它们所有共有属性的Object,被称为它们的原型(prototype)。
- 原型的三段论推理
- 每个对象都有原型(大前提)
- 原型也是对象(小前提)
- 原型也有原型(结论)
- 非prototype和prototype的联系是:非prototype的__proto__属性的属性值为prototype的地址。
let obj = {a: 1}
obj.__proto__ === Object.prototype
- JS中标识符
Object,实际是一个Object的构造方法,即Object()。在这个方法中有一个属性prototype,即为原型。
- prototype也有__proto__。
Object.prototype.__proto__的值为null。
Array.prototype.__proto__的值为Object.prototype。
- 注意
- Object是可以包含Object的,所以
Object()方法中的prototype属性,其实也是一个Object,即原型。
Object()函数也是Object,自然有__proto__属性。Object.__proto__的值为ƒ () { [native code] }。
修改或增加共有属性
- 无法直接通过自身修改或增加共有属性。
- 试图直接通过自身修改,新的属性只会添加在自身属性,而不会添加到原型。
- 可以通过原型来修改或增加共有属性。
obj.__proto__.toString = '这里修改了原型的toString'(不推荐)
Object.prototype.toString = '这里修改了原型的toString'
- 修改原型会引起很多问题,一般来说不要修改。
修改隐藏属性
查看对象属性
- 查看属性
对象['key'](推荐)
对象.key
obj[代表key的变量]
- 查看对象中是否有指定属性:
'属性名' in 对象
- 判断对象的一个属性是自身的还是共有的:
对象.hasOwnProperty('属性名')
- 查看对象所有属性名:
Object.keys(对象)
- 查看对象所有属性值:
Object.values(对象)
- 查看对象所有键值对:
Object.entries(对象)
- 查看对象的共有属性:
对象.__proto__(不推荐)
- 查看对象自身+共有属性:
console.dir(对象)
删除对象属性
delete obj.xxx或delete obj['xxx']
- 即可删除 obj 的xxx属性
- 注意
修改或增加属性
- JS中修改属性和增加属性的操作是相同的。
- 直接赋值
let person = {
name : 'Andy',
age : 18
}
person['gender'] = '男'
person.hobby = '足球'
- 批量赋值
Object.assign(对象, {key1: value, key2: value})
- 例:
let person = {
name : 'Andy',
age : 18
}
Object.assign(person, {
'gender': '男',
'hobby': '足球'
})
拓展
Symbol作属性名
let a = Symbol()
let obj = {
[a]: 'Hello'
}
- Symbol值也能作属性名。
- 在“迭代”中可能会用到。
原型链在增删改查中
- 改、增、删都不会追溯原型链。
- 只有查询操作才会追溯原型链。
'name' in obj和obj.hasOwnProperty('name')的区别
'name' in obj是查询obj对象中是否有name这个属性。但无法判断name属性是它自身的,还是它原型的。只有当obj对象本身以及其原型都没有name属性时,才会返回false。
obj.hasOwnProperty('name')是查询obj对象自身是否有name这个属性,有两种情况它会返回false:
- 该obj对象没有name属性。
- 该obj对象有name属性,但是是在它原型中。