属性名:每个 key 都是对象的属性名(property)
属性值:每个 value 都是对象的属性值
Object.keys(obj) 可以得到 obj 的所有 key
obj.key //点语法
obj['key'] //中括号语法
1. 声明对象的两种语法
let obj = { 'name': 'frank', 'age': 18 }
let obj = new Object({'name': 'frank'})
console.log({ 'name': 'frank, 'age': 18 })
2. 如何删除对象的属性
delete obj.xxx
delete obj['xxx']
注意:键名是字符串,不是标识符,可以包含任意字符;引号可省略,省略之后就只能写标识符;就算引号省略了,键名也还是字符串。
用法:delete obj.xxx 或 delete obj['xxx'],即可删除 obj 的 xxx 属性。其中undefined删除的是值,delete删除的是属性名;
请区分「属性值为 undefined」和「不含属性名」
- 不含属性名
'xxx' in obj === false - 含有属性名,但是值为 undefined
'xxx' in obj && obj.xxx === undefined
注意 obj.xxx === undefined,不能断定'obj'是否为obj的属性,只能判断属性值为undefined。
'xxx' in obj 用来判断属性名是否还在,返回false,删除成功;'xxx' in obj&&obj.xxx 返回undefined证明含有属性名,但是值为undefined。
类比:——你有没有卫生纸?
A: 没有 // 不含属性名
B: 有,但是没带 // 含有属性名,但是值为 undefined
3. 如何查看对象的属性
Object.keys(obj) //查看自身所有属性
console.dir(obj) //查看自身+共有属性
obj.hasOwnProperty('toString') //判断一个属性是自身的还是共有的
'toSrting' in obj //用来看是否存在该属性,但是不知道是谁的
let obj = { 'name': 'frank', 'age': 18 }
Object.keys(obj) //查看所有属性
// ['name', 'age']
Object.values(obj) //查看所有属性值
// ['frank', 18]
Object.entries(obj) //查看所有key和value
// [Array(2), Array(2)]
obj.name 等价于 obj['name'],简单来说,这里的 name 是字符串,而不是变量
let name = 'frank'时 obj[name] 等价于obj['frank']
let list = ['name', 'age', 'gender']
let person = {
name:'frank', age:18, gender:'man'}
for(let i = 0; i < list.length; i++){
let name = list[i]
console.log(person.name)
}
// 打出三个frank
person.name里面的name 是字符串,所以只会打出name字符串对应的'frank'
let list = ['name', 'age', 'gender']
let person = {
name:'frank', age:18, gender:'man'}
for(let i = 0; i < list.length; i++){
let name = list[i]
console.log(person[name])
}
// frank
// 18
// man
person[name]里面的name 是变量,person[name]会被替换成person.name 、person.age、person.gender
4. 如何修改或增加对象的属性
obj['name'] = 'jack' //直接赋值,改自身
Object.assign(obj, {age:18, ...}) //批量赋值,改自身
obj.__proto__['toString'] = 'xxx' //改共有属性,不推荐
Object.prototype['toString'] = 'xxx'//改共有属性
obj.__proto__ = common//改原型,不推荐
let obj = Object.create(common) //改原型
- 直接赋值
let obj = {name: 'frank'}// name 是字符串
obj.name = 'frank' // name 是字符串
obj['name'] = 'frank'
obj[name] = 'frank' // 错,因 name 值不确定
obj['na'+'me'] = 'frank'
let key = 'name'; obj[key] = 'frank'
let key = 'name'; obj.key = 'frank' // 错 因为 obj.key 等价于 obj['key']
- 批量赋值
Object.assign(obj, {age: 18, gender: 'man'})
5. 'name' in obj和obj.hasOwnProperty('name') 的区别
查看属性名name是否存在:'name' in obj 控制台的输出为false或true; 判断属性name是自身的还是共有的:obj.hasOwnProperty('name'),输出为false或true。
'name' in obj不能判断是否是自身属性,obj.hasOwnProperty('name')可以判断。
6.原型
- 每个对象都有原型
原型里存着对象的共有属性,比如 obj 的原型就是一个对象,
obj.__proto__存着这个对象的地址 这个对象里有 toString / constructor / valueOf 等属性 - 对象的原型也是对象 所以对象的原型也有原型,obj = {} 的原型即为所有对象的原型,这个原型包含所有对象的共有属性,是对象的根,这个原型也有原型,是 null。
7.总结
- 删
delete obj['name']
'name' in obj // false
obj.hasOwnProperty('name') // false
- 查
Object.keys(obj)
console.dir(obj)
obj['name']
obj.name // 记住这里的 name 是字符串
obj[name] // 记住这里的 name 是变量
- 改
- 改自身
obj['name'] = 'jack' - 批量改自身
Object.assign(obj, {age:18, ...}) - 改共有属性
obj.__proto__['toString'] = 'xxx' - 改共有属性
Object.prototype['toString'] = 'xxx' - 改原型
obj.__proto__ = common - 改原型
let obj = Object.create(common) - 注:所有
__proto__代码都是强烈不推荐写的
- 增 基本同上:已有属性则改;没有属性则增。
问题:
let obj = Object.create({name:'frank'})和 let obj1 = new Object({name:'frank'})的区别是什么
let obj = Object.create({name:'frank'})的属性是在原型上,Object.create是改变了原型的属性。
let obj1 = new Object({name:'frank'})的属性是自身的
obj.xxx === undefined不能判断xxx在不在obj里面
只能用'xxx' in obj 来判断。