对象的定义是什么?
- 无序的数据集合
- 键值对的集合
声明对象的两种方法
写法
let obj = {'name':'jack','age':18}let obj = new Object({'name':'jack'})
我们把'name','age'称为key(键),每个key都是对象的属性名
把'jack','18'称为value(值),每个value都是对象的属性值
细节
- 键名是字符串!不是标识符,可以包含任意字符
- 引号可以省略,但省略之后就只能写标识符和数字
- 就算引号省略,键名也还是字符串!
Object.keys(obj)可以看到obj的所有key
几个奇怪的属性名
- 1e2 1e-2 科学计数法会自动转换成数字
- .234 会自动转换成小数
- OxFF 会自重转换成十进制
如何用变量属性名
- 不加[]的属性会自动变成字符串
- 加了[]则会当成变量求值
- 值如果不是字符串,则会自动变成字符串
对象的隐藏属性
我们在上面的图中,经常可以看到一个我们没有声明过的属性__proto__,这是一个什么属性呢?
这是JS的隐藏属性
- JS中每个对象都有一个隐藏属性
- 这个隐藏属性储存着其共有属性组成的对象的地址
- 这个共有属性组成的对象叫做原型
- 简而言之,隐藏属性储存着原型的地址
我们来进行简单的验证:
这里并没有报错,是因为obj的隐藏属性指向的对象上有toString()属性,我们可以直接使用
这样的储存方法不用对共有属性重复声明,省时省空间
原型
- 每个对象都有原型,它包含所有对象的共有属性,方便理解我们把它称为原型1
- 原型1也是一个对象
- 所以这个原型1也有原型,方便理解我们称为原型0
- 原型0是null
增删改查
删除属性
delete obj.xxxdelete obj['xxx']注意:obj.xxx=undefined这种方法只是把属性值改为undefined,并不能删除
'xxx' in obj查看该属性是否在对象里,注意要加上引号!
查看属性
查看所有属性
Object.keys(obj)查看自身所有属性console.dir(obj)查看自身+共有属性obj.hasOwnProperty('xxx')判断一个属性是自身属性还是共有属性- true 自身
- false 共有
obj.hasOwnProperty('xxx')与'xxx' in obj的区别?
'xxx' in obj 不区分是自身还是共有
obj.hasOwnProperty('xxx') 可以区分
查看单个属性
obj['name']obj.name
这两者中的name都是字符串!
切记:obj.name 不等价于 obj[name]!
前者name是字符串,后者name是变量!
加深记忆
例:
let list = ['name','age''gender']
let person = {
name:'jack',age:18,gender:'man'
}
for(let i = 0;i<list.length;i++){
let name = list[i]
console.log(??????)
}
用这段代码使得person的所有属性都被打印出来,
则??????应该是什么
- console.log(person.name)
- console.log(person[name])
答案应该是2,因为2的name是变量,而1的name是字符串,1只会打印出'jack'
修改或增加属性
修改或增加自身属性
我们可以直接用查的方式给对象赋值
obj['name']obj.name还可以通过设置变量,用变量给对象赋值let key = 'name'obj[key] = 'jack'
也可以批量赋值:
Object.assign(obj,{age:18,gender:'man'})
修改或增加共有属性
首先,我们无法通过自身修改或增加共有属性
可见obj2.toString还是在原型上
但如果非要修改或增加原型上的属性,可用以下方法实现
obj.__proto__.toString='xxx'不推荐Object.prototype.toString='xxx'
一般来说,不要修改原型,因为会引起很多问题,
原型可以随意修改,这也体现出了JS的脆弱性
修改隐藏属性
obj.__proto__不推荐
- 隐藏属性可以直接修改为空
- 这样就无法调用它的隐藏属性了
- 隐藏属性也可以指定为其他对象
- 对象里包含了原本的隐藏属性,这个隐藏属性指向原型
Object.create(common)
- 以common这个对象为原型来创建一个新对象
推荐只用第二种方法,第一种十分影响性能