一、对象基础总结
增删改查总结
-
删
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'] -
改原型:
obj.__proto__['toString'] = 'xxx' -
改原型推荐的方法 :
let obj = Object.create(common) -
注意:所有__proto__代码都是强烈不推荐写的
-
-
增
-
基本跟改的方法是一样的
-
有的属性通过上面的方法就是改,没有的属性通过上面的方法就是新增属性
-
写法
-
let obj = {'name':'jackey','age':18}简单的写法,一般用这个 -
let obj = new Object({'name': 'jackey','age': 18})正规的写法 -
console.log({'name': 'jackey','age': 18})匿名对象
细节
-
键名是字符串,不是标识符,可以包含任意字符
-
引号可以省略,省略之后就只能写标识符
-
就算引号省略了,键名也还是字符串(重要)
-
Object.keys(对象)能打印出该对象的所有键值对
1.属性名和属性值
-
每一个key都是对象的属性名 (property)
-
每一个value都是对象的属性值
奇怪的属性名
1.所有属性名会自动变成字符串
-
let obj = { 1:'a', 3.2:'b', 1e2:'true', 1e-2:'true', .234:'true', 0xff:'true' } Object.keys(obj) =>['1','3.2','100','0.01','0.234','225']JS会先换算,再把属性名变成字符串(有点蛋疼)
-
由此推论,加引号是最保险的写法
2.变量作为属性名
-
之前都用常量做属性名
-
如果用变量做属性名应该如下
let p1 ='name' let obj{p1:'frank'} // 这样写,属性名为'p1' let obj{[p1]:'frank'} // 这样写,属性名为'name' -
对比
-
不加
[]的属性名会自动变成字符串 -
加了
[]的属性名则被JS引擎当成变量值 -
值如果不是字符串,也会被自动变成字符串
-
对象的隐藏属性
a.隐藏属性
-
JS中每一个对象都有一个隐藏属性
-
这个隐藏属性储存着其共有属性组成的对象的地址
-
这个共有属性组成的对象叫原型
-
隐藏属性储存这原型的地址
b.代码示例
-
let obj = {} obj.toString() // 不会报错 -
因为
obj的隐藏属性对应的对象上有toString这个属性
超纲的知识
a.除了字符串,symbol也能做属性名
let a = symbol()
let obj = {[a]:'Hello'}
b.用途
-
目前,暂时没用,要到很久以后可能才会用到
-
在学习(迭代)的时候会用到
-
知道有这么个东西就行了
二、对象的增删改查
1. 删除属性
delete obj,xxx或delete boj['xxx']就能删除obj的xxx属性
一定区分属性值为undefined和不含属性名
-
不含属性名
'xxx' in obj === false
-
含有属性名,但是值为undefined
'xxx' in obj && obj.xxx === undefined
-
删除成功与否
-
'xxx' in obj若结果是false就代表删除成功了 -
必须要加引号,因为属性名始终是字符串
-
delete 只能删除属性,不能删除对象
2. 查看属性
(1)查看所有属性
-
(a).查看自身所有属性
Object.keys(obj) -
(b).查看自身+共有属性
console.dir(obj)或者依次用
Object.keys打印出obj.__proto__ -
(c).查看自身属性值
Object.Values(obj) -
(d).查看自身所有属性名和属性值
Object.entries(obj)
(2).判断一个属性是自身的还是共有的
obj.hasOwnProperty('toString')
属性是否共有
-
和
'xxx' in obj区别-
'xxx' in obj不管属性是自身属性还是共有属性,只要有xxx这个属性就会返回true -
obj.hasOwnProperty('xxx')只有这个xxx属性是自身属性,才返回true
-
(3)查看单一属性
-
两种方法
-
中括号语法:
obj['key'] -
点语法:'obj.key'
-
容易误解的语法:
obj[key]变量key的值,一般不为'key'
-
-
优先使用中括号法,因为点语法会误导新手,等确定不会搞混两种语法,再改用点语法
(4)需要注意的情况
第一种情况
obj.name 等价于 obj['name']
obj.name 不等价于 obj[name] 简单的说,这里的name是字符串,不是变量
第二种情况
let name = 'jackey'
obj[name]等价于obj['jackey']
不是obj['name']和obj.name
千万不要记错了
3.修改或增加属性(写属性)
(1)直接赋值
-
let obj = {name:'jackey'}这里的name是字符串 -
obj.name = 'jackey'这里的name是字符串 -
obj['name'] = 'jackey' -
这样是错的,因为这里的obj[name] = 'jackey'name是变量,值不确定 -
obj['na'+'me'] = 'jackey'
(2)批量赋值
-
Object.assign(obj,{age:18,gender:'man'}) -
这时ES6的心属性
(3)修改或增加共有属性
-
无法通过自身修改或增加共有属性
-
let obj = {},obj2 = {}共有属性toString -
obj.toString = 'xxx'只会更改或添加obj这个对象的自身属性 -
obj2.toString还是在原型上
-
-
如果你非要修改或增加共有属性
-
obj.__proto__.toString = 'xxx'任何时候都不推荐用__proto__ -
Object.prototype.toString = 'xxx' -
一般来说,不要直接修改共有属性,会引起许多问题,如果要修改请直接在对象声明前给一个新的原型链
-
(4)修改隐藏属性
-
a.不推荐用__proto__
let obj = {name:'jackey'} let obj2 = {name:'frank'} let common = {kind:'human'} obj.__proto__ = common obj2.__proto__ = common 这样obj和obj2的隐藏属性就存了common这个属性的地址 -
b.推荐使用
Object.createlet obj = Object.create(common) obj.name = 'jackey' let obj2 = Object.create(common) obj2.name = 'frank' 这样和上面的实现效果是一样的,但性能比上面好 -
规则的意思是,要改一开始声明对象的时候你就改,不要后面再来改
三、原型补充
1.每一个对象都有原型
-
原型是存着对象的共有属性的
-
比如
obj的原型就是一个对象 -
obj.__proto__存着这个对象的地址 -
这个对象里有
toString/constructor/valueOf等共有属性
2.对象的原型也是对象
-
所以对象的原型也有原型
-
obj = {}的原型即为所有对象的原型 -
这个原型包含所有对象的共有属性,是对象的根
-
这个原型也有原型,存的是
null