对象
写法
let obj = {'name':'mx','age':18}
let obj = new Object({'name':'mx'})
细节:
-
键名是字符串,不是标识符,可以包含任意字符
-
引号可省略,省略之后就只能写标识符
-
就算引号省略了,键名也还是字符串
-
属性名:每个key都是对象的属性名
-
属性值:每个value都是对象的属性值
-
Object.keys(obj)可以得到obj的所有key
变量作属性名
let p1 = 'name'
let obj = {p1:'mx'}//属性名为'p1'
let obj = {[p1]:'mx'}//属性名为'name'
对比:
- 不加[]的属性名会自动变成字符串
- 加了[]则会当做变量求值
- 值如果不是字符串,则会自动变成字符串
对象的隐藏属性
JS中每一个对象都有一个隐藏属性,这个隐藏属性储存着其公有属性组成的对象的地址,这个共有属性组成的对象叫做原型,也就是说,隐藏属性储存着原型的地址
var obj = {}
obj.toString() //不报错,因为obj的隐藏属性对应的对象上有toString()
增删改查
删除属性
- delete obj.xxx 或 delete obj['xxx'],即可删除obj的xxx属性
- 不含属性名:'xxx' in obj === false
- 含有属性名,但是值为undefined:'xxx' in obj && obj.xxx === undefined
- 注意obj.xxx === undefined:不能断定'xxx'是否为obj的属性
查看所有属性(读属性)
- 查看自身所有属性:Object.keys(obj)
- 查看自身+共有属性:console.dir(obj) 或者 自己依次用Object.keys打印出obj._proto_
- 判断一个属性是自身的还是共有的:obj.hasOwnProperty('toString')
原型
每个对象都有原型
- 原型里存着对象的共有属性。比如obj的原型就是一个对象,obj._proto_存着这个对象的地址,这个对象里有toString/constructor/valueOf等属性
对象的原型也是对象
- 所以对象的原型也有原型。obj={}的原型即为所有对象的原型,这个原型包含所有对象的共有属性,是对象的根。这个原型也有原型,是null
查看属性
两种方法查看属性
- 中括号语法:obj['key']
- 点语法:obj.key,这里的key是字符串
优先使用中括号语法。点语法会误导人,让人以为key不是字符串。
obj.name等价于obj['name']
obj.name不等价于obj[name],obj[name]中的name是变量
简单来说,这里的name是字符串,而不是变量
let name = 'mx'
obj[name]等价于obj['mx']而不是obj['name']和obj.name
需要分清变量name和常量字符串'name'
修改或增加属性(写属性)
直接赋值
let obj = {name:'mx'} //name是字符串
obj.name = 'mx' // name是字符串
obj['name'] = 'mx'
obj['na'+'me'] = 'mx'
let key = 'name'
obj[key]='mx'
批量赋值
Object.assign(obj,{age:18,gender:'man'})
- 修改或增加共有属性
- 无法通过自身修改或增加共有属性
let obj = {},obj2={} //共有toString
obj.toString = 'xxx' //只会在改obj自身属性
obj2.toString //还是在原型上
修改隐藏属性
不推荐使用__proto__
let obj = {name:'mx'}
let obj2 = {name:'jack'}
let common = {kind:'human'}
obj.__proto__ = common
obj2.__proto__ = common
推荐使用Object.create
let obj = Object.create(common)
obj.name = 'mx'
let obj2 = Object.create(common)
obj2.name = 'jack'
资料来源:饥人谷