声明对象的两种语法
let obj = { 'name': 'kong', 'age': 22} // 简写
let obj = new Object({'name': 'kong'}) // 标准写法
如何删除对象的属性
delete
删除属性名和属性值
delete obj.xxx
delete obj['xxx']
不含属性名
'xxx' in obj === false
含属性名但值为 undefined
'xxx' in obj && obj.xxx === undefined
obj.xxx = undefined 不能断定 xxx 是否为 obj 的属性!
仅仅删除属性值
如何查看对象的属性
查看自身所有属性
Object.keys(obj)
查看自身+共有属性
console.dir(obj)
判断一个属性是自身还是共有的
obj.hasOwnProperty('toString')
in
与 hasOwnProperty
区别
in
不能识别属性是来自对象自身的还是来自原型。
var obj = { p: 1 };
'p' in obj // true
'toString' in obj // true
hasOwnProperty
表示该对象自身是否具有该属性。
var obj = {
p: 123
};
obj.hasOwnProperty('p') // true
obj.hasOwnProperty('toString') // false
读取属性的两种写法
obj.key
obj['key']
注意 obj[key]
变量key值一般不为 'key'(坑人语法)
obj.name
// 等价于 obj['name']
let name = 'kong'
// obj[name] 等价于 obj['kong'] 而不是obj['name']和obj.name
如何修改或增加对象的属性
- 直接赋值
let obj = {name: 'frank'} // name是字符串
obj.name = 'frank' // name字符串
obj['name'] = 'frank'
obj['na'+'me'] = 'frank'
let key = 'name'; obj[key] = 'frank'
obj[name] = 'frank' // 错误写法,因为name的值不确定
let key = 'name';obj.key = 'frank' // 错误写法。因为obj.key等价于obj['key']
- 批量赋值
Object.assign(obj, {age: 22, gender: 'man'})
-
修改或增加共有属性
注:无法通过自身修改或增加共有属性
let obj = {}, obj2 = {} // 共有 toString
obj.toString = 'xxx' // 只会在改 obj 自身属性
obj2.toString // 还是在原型上
- 偏要修改或增加原型上的属性
obj.__proto__.toString = 'xxx' // 不推荐用 __proto__
Object.prototype.toString = 'xxx'
// 不要修改原型,会引起很多问题
- 修改隐藏属性
不推荐使用proto
let obj = {name:'kong'}
let obj2 = {name: 'jerry'}
let common = {kind: 'human'}
obj.__proto__ = common
obj2.__proto__ = common
使用 Object.create
let obj = Object.create(common)
obj.name = 'frank'
let obj2 = Object.create(common)
obj2.name = 'jack'
// 要改就一开始就改,别后来再改
对象的隐藏属性
隐藏属性
- JS每一个对象都有一个隐藏属性
- 这个隐藏属性存储着其共有属性组成的****对象的地址
- 这个共有属性组成的对象叫做原型
- 隐藏属性存储着原型的地址
var obj = {}
obj.toString() //不报错
// 因为obj的隐藏属性对应的对象上有toString</pre>
原型
每个对象都有原型
- 原型里存着对象的共有属性
- 比如obj的原型就是一个对象
-
obj.__proto__
存着这个对象的地址 - 这个对象里有
toString/constructor/valueOf
等属性
对象的原型也是对象
- 所以对象的原型也有原型
-
obj = {}
的原型就是所有对象的原型 - 这个原型包含所有对象的共有属性,是对象的根
- 这个原型也有原型,原型就是 null