JS对象
-
定义
- 无序的数据集合
- 键值对的集合
-
写法
- let object = {'name':'tom','age':18}
- let object = new Object({'name':'tom','age':18})
- console.log({"name":"tom","age":18})
-
细节
- 键名是字符串,不是标识符,可以包含任意字符
- 引号可省略,省略之后就只能写标识符
- 就算引号省略了,键名还是字符串
可以通过Object.keys(对象名) 就可以得到对象的所有key
每个key都是对象的属性名,每个value都是对象的属性值
变量作属性名
-
如何用变量做属性名
- 之前都是用常量做属性名
let p1 = 'name'
let obj = {p1:'Wilson'} //这样写,属性名为p1
let obj = {[p1]:'wilson'} //这样写,属性名为name
-
对比
- 不加[]的属性名会自动变成字符串
- 加了[]则会当作变量求值
- 值如果不是字符串,则会自动变为字符串
对象的隐藏属性
-
隐藏属性
- JS中每一个对象都有一个隐藏属性
- 这个隐藏属性存储着其共有属性组成的对象的地址
- 这个公有属性组成的对象叫做原型
- 也就是说,隐藏属性存储着原型的地址
-
代码示例
var obj = {}
obj.toStirng() //没有报错
//因为obj的隐藏属性对应的对象上有toString()
增删改查
删除属性
-
delete obj .xxx 或 delete obj['xxx']
- 即可删除obj的xxx属性
- 请区分[属性值为 undefined] 和 [不含属性名]
-
不含属性名
- 'xxx' in obj === false
-
含有属性名,但是值为 undefined
- ‘xxx’ in obj && obj .xxx === undefined
-
注意 obj .xxx === undefined
- 不能断定'xxx'是否为obj的属性
-
类比
-
你作业呢
A:没写//不含属性名
B:有写,但是没带//含有属性名,但是值为undefined
-
没有就是没有,undefined就是undefined绝不含糊
-
查看属性
-
查看自身所有属性
- Object.keys(object)
-
查看自身+共有属性
- console.dir(object)
- 或者自身依次用Object.keys打印出obj. __ proto __
-
判断一个属性是自身的还是共有的
obj.hasOwnProperty('toStirng')
原型
-
每个对象都有原型
- 原型里存着对象的共有属性
- 比如object的原型就是一个对象
- object._ proto_ 存着这个对象的地址
- 这个对象里有toString/constructor/valueOf等属性
-
对象的原型也是对象
- 所有对象的原型也有原型
- object = {} 的原型即为所有对象的原型
- 这个原型包含所有对象的共有属性,是对象的根
- 这个原型也有原型,是null
直接通过对象查看属性
-
两种方法查看属性
- 中括号语法:object['key']
- 点语法:object.key
- 坑新人语法:object[key] //变量key值一般不为'key'
-
请优先使用中括号语法
- 点语法会误导你,让你以为key不是字符串
- 等你确定不回弄混两种语法,再使用点语法
修改或增加属性
- 直接赋值
let object = {name:'wilson'} //name是字符串
object.name = 'wilson'
object['name'] = 'wilson'
let key = 'name';object[key] = 'wilson';
- 批量赋值
Object.assign(object,{age:18,gender:'man'})
修改或增加共有属性
- 无法通过自身修改或增加共有属性
let object={}; object2={} //共有toString
object.toString='xxx' 只会在改object自身属性
object2.toString还是在原型上
- 我如果偏要修改或增加原型上的属性
object._proto_.toString = 'xxx'
Object.prototype.toString = 'xxx'
//一般来说,不要修改原型,会引起很多问题,而所有_proto__代码都是强烈不推荐写的
修改隐藏属性
- 不推荐使用_proto _
let obj={name:'wilson'}
let obj2={name:'Tom'}
let common = {kind:'human'}
obj._proto_ = common
obj2._proto_ = common
- 推荐使用Object.create
let obj = Object.create(common)
obj.name= 'frank'
let obj2 = Objext.create(common)
obj2.name = 'jack'
//规范大概的意思是,要改就一开始就改,别后来再改
'name' in obj 和obj.hasOwnProperty('name')的区别
'name' in obj 返回的是一个bool值,判断属性名是否存在对象obj中
obj.hasOwnProperty('name')判断name属性是不是obj对象独有的,而不是共有属性