声明对象的两种语法
object定义
无序的数据集合 键值对的集合
语法
let obj = { 'name': 'tarro', 'age': 18}
let obj = new Object({'name': 'tarro'})
console.log({'name': 'tarro', 'age': 18})
细节:
键名是字符串,不是标识符,可以包含任意字符
引号可省略,省略之后只能写标识符,但键名也还是字符串
属性名——每个key都是对象的属性名(property)
属性值——每个value都是对象的属性值
删除对象属性
写法
delete obj.xxx或delete obj['xxx']——删除obj的xxx属性
注意:obj.xxx = {undefined}——这种写法只能将obj的xxx属性值改为空,但属性名还在
不含属性名
'xxx' in obj => false——判断'xxx'是否为obj的属性(但不判断为自身属性还是共有属性)
含有属性名,但值为indefined
'xxx' in obj && obj.xxx => undefined
注意 obj.xxx === undefined 不能断定 'xxx' 是否为 obj 的属性,只能用 'xxx' in obj
查看对象的属性
查看所有属性
查看自身所有属性
Object.keys(obj)
查看自身+共有属性(原型)
- console.dir(obj)
- 或者自己一次用Object.keys打印出obj.__proto__
判断一个属性是自身还是共有
obj.hasOwnProperty('toString(该属性)')
查看属性
- 中括号语法:obj['key']
- 点语法:obj.key
- 坑新人语法:obj[key] //变量key值一般不为'key'
tips: 请优先使用中括号语法; 点语法会误导你,让你以为key不是字符串; 确定不会弄混两种语法,再改用点语法。
三段论逻辑
每个对象都有原型
- 原型里存着对象的共有属性
- 比如obj的原型就是一个对象
- Obj.__proto__存着这个对象的地址
- 这个对象里有toString/constructor/valueOf等属性
对象的原型也是对象
- 所以对象的原型也有原型
- obj={}的原型即为所有对象的原型
- 这个原型包含所有对象的共有属性,是对象的根
- 这个原型也有原型,是null——人为指定的(复杂的可能还会指定一个地址) 即:每个对象都有原型; 对象的原型也是对象; 这个原型也有原型,是null。
例:分清变量name和常量字符串'name'
选2(所有属性打印,如果是1只有name)
解析
修改或增加对象的属性
直接赋值
有则改,无则增
let obj = {name: 'tarro'} | name是字符串 |
---|---|
obj.name = 'tarro' | name是字符串 |
obj['name'] = 'tarro' | |
错,因为name值不确定,不一定是字符串 | |
obj['na'+'me'] = 'tarro' | |
let key = 'name'; obj[key] = 'tarro' | key是变量,key='name',故变量key='tarro' |
let key = 'tarro'; | 错,因为obj.key等价于obj['key'] |
批量赋值
- Object.assign(obj, {age:18, gender:'man'})
- 追加在obj数组里,之前obj里原有的内容保留
修改或增加共有属性
无法通过自身修改或增加共有属性
- let obj = {}, obj2 = {} //原型toString
- obj.toString = ‘xxx’只会改在obj自身属性上
- obj2.toString还是在原型上
修改或增加原型上的属性
obj.__proto__.toString = 'xxx' | //不推荐用__proto__(可以用下面这种) |
---|---|
Object.prototype.toString = 'xxx' | 但一般不要修改原型,会引起bug的 |
修改隐藏属性
不推荐使用__proto__ | 推荐使用Object.create() |
---|
Object.create(属性,这里还有一个可以直接赋值的属性比较麻烦),示例:
'name' in obj和obj.hasOwnProperty('name')的区别
'name' in obj //'name'是obj的属性true,不是则false obj.hasOwnProperty('name') //判断是否为自身属性。是则true,不是则false