JS对象
七个基本类型数据
四基:Number/String/Boolean/Symbol
两空:null undefined
一对象:Object
五个falsy值
null undefined 0 NaN ''(空字符串)
对象Object 唯一一种复杂类型
定义:无序的数据集合
键值对的集合
写法:
简化写法:
let obj{'name'='fred','age':18}
正规写法:
let obj=new Object({'name'=’fred’})
细节:
键名也是属性名(property),他的数据类型是字符串,不是标识符,可以包含任意字符。
引号是可以省略,省略之后只能写标识符,键名里面有空格或特殊符号则不能省略引号,就算引号省略了,键名还是字符串。没有数字下标,没有数字键名
属性值(value)每个value都是对象的属性值
所有属性名都会变成字符串
let obj={
1:'A',//单独写数字会转化为字符串”1”
1e2:true,//键名会变成”100”
1e-2:true,//键名会变成”0.01”
.234:true,//前面会变成”0.0234”
0Xff:true //会自动转为”255”他会认为是16进制转化为十进制
}
Object.key(obj)可以得到obj的所有key
属性名.用变量值做键名
let p1='name'
let obj={p1:'fred'}//"p1"为对象的属性名
let obj={[p1]:'fred'}//这样写表示属性名为变量p1的值'name'
所以,如果变量值要做属性名,就需要在变量里面加[]
对象的隐藏属性
隐藏属性
JS中每一个对象都有一个隐藏属性
这个隐藏属性存储着共有属性组成的对象地址
这个共有属性组成的对象叫做原型,也就是说隐藏属性存储原型地址
代码:
let obj={}
obj.toString()//不会报错
因为obj的隐藏属性对应的对象上有toString()
超纲知识
除了字符串,symbol也能做属性名
let a = symbol()
let obj={[a]:"hello"}
这个会在迭代的时候用到
删属性
增删改查属性
删除属性
delete obj.XX或delete obj[‘XX’]即可删除obj的XX属性
不含属性名(查看是否删除)
'XXX'in obj===false
查看是否删除成功用’删除属性名’+in 如果返回false则表示删除成功,属性名一定要加引号,否则返回的也是false
表示含有属性名,但是值为undefined
'xxx'in obj&&obj.xxx===undefined
注意obj.xxx===undefined只能判断属性值,不能判断属性名。
要判断属性名要用in操作符
类比
你有没有卫生纸?
没有//不含属性名
有,但是没有带//有属性名,但是值为undefined
读属性
查看obj所有属性
Object.keys(obj)
查看obj自身属性以及共有属性
console.dir(obj)
或者自己依次用object.keys打obj.__proto__(一般不推荐这种方式,因为隐藏属性每个浏览器是不同的)
判断一个属性是自身的还是共有的
obj.hasOwnProperty(‘toString’)//false 返回false表示‘toString’不是自身属性
原型
每个对象都有原型,原型里存着对象的共有属性,比如obj的原型就是一个对象
obj.__proto__存着这个对象的地址,这个对象里面存有toString/constructor/valueOf等属性
对象的原型也是对象
所以对象的原型也有原型
obj={}的原型即为所有对象的原型,只不过这个原型是包含所有对象的共有属性的根,这个原型也有原型,原型是null
查看单个属性
两种方法
中括号法:obj['key']
点语法:obj.key
坑新人语法:obj[key]//变量key值一般不为'key'
优先使用中括号语法
点语法会误导你让你以为key不是字符串
等你确定不会弄混两种语法后再改用点语法
修改或增加属性
直接赋值
let obj={name:'fred'}//name是字符串
obj.name='fred'//name是字符串
obj['name']='fred'
obj[name]='fred'//这里会报错,因为这里属性名是变量name的值,如果name并没有声明的话无法引用
obj["na"+"me"]="fred"//它会先求中括号里面的值
批量赋值
Object.assign(obj,{age:18,gender:'man'})
修改或增加共有属性
let obj={},obj2={}//共有toString
obj.toString='xxx'//只会在改obj自身属性
obj2.toString还是在原型上
我偏要修改或增加原型上的属性
obj.__proto__.toString='xxx'//不推荐应用__proto__因为会破坏原有属性。
obj.__proto__.abc='xxx'//增加一个值为xxx的abc属性
一般来说不要修改原型,会引起很多问题,因为你可以随意修改属性
修改隐藏属性
推荐使用Object.create()
let obj =Object.create(common) obj.name='fred'
这里指以common为原型来创建obj。obj的name属性为fred
let obj2=Object.create(common) obj2.name='jack'
这里指以common为原型来创建obj2,obj2的name属性为jack