对象的语法
第七种数据类型,唯一一种复杂类型,因为里面可以包含东西(包括它自己)
1.定义
- 无序的数据集合:下方
name
和age
的顺序改变都可以 - 键值对的集合:
name
是键(key),frank
是值,组成一对 - 一对或者一对以上都是对象
2.写法
let obj = { 'name' : 'frank', 'age' : 18}
其中name
和age
只能是字符串,就算删掉也只能是字符串let obj = new Object({ 'name' : 'frank'})
这是正规写法,但太复杂,一般用第一种console.log({ 'name' : 'frank', 'age' : 18})
匿名对象,没有名字
3.细节
- 键名(如name和age)是字符串,不是标识符(不能以数字开头),可以包含任意字符(数字、emoji、空等)
- 引号可以省略,省略后就只能写标识符
- 就算引号省略,键名也还是字符串
4.属性名
每一个key都是对象的属性名(property)
4.1 奇怪的属性名
- 所有属性名都会自动变成字符串
- 想知道对象有哪些键(key)
Object.keys(obj)
:括号里为对象名
let obj = {
1: 'a',
3.2: 'b',
1e2: true,//会换算成 100,最终变成 100: true
1e-2: true,//会换算成0.01,最终变成 0.01: true
.234: true,//0.234
0xFF: true//会换算成十进制数,如果想要保持,还是要加上 '0xFF'
};
4.2 变量做属性名
-
let p1 = 'name'
-
let obj = {p1: 'frank'}
这样写,属性名为'p1'
字符串 -
let obj = {[p1]: 'frank'}
这样写,属性名为'name'
,是变量p1
的值
对比: -
不加 [ ] 的属性名就会自动变成字符串
-
加了 [ ] 则会当做变量求值(先求值,再将值作为字符串)
-
值如果不是字符串,就会自动变成字符串
5.属性值
每一个value都是对象的属性值
6.对象的隐藏属性
6.1 隐藏属性
-
JS中每一个对象都有一个隐藏属性
-
这个隐藏属性存储着其共有属性组成的对象的地址
-
这个共有属性组成的对象叫做原型(是对象不是地址)
-
也就是说,隐藏属性存储着原型的地址
6.2 代码示例 -
var b = {}
-
obj.toString()
-
因为
obj
的隐藏属性对应的对象上有toString()
删属性
对象属性的增删改查
delete obj.xxx
或delete obj['xxx']
即可删除obj
的xxx
属性
注意区分 属性值为undefined
和 不含属性名
undefined
只删除 值
- 如何判定 ‘xxx’ 是否是obj的属性:
'xxx' in obj
注意加单引号
- 注意:
obj.xxx===undefined
不能断定'xxx'
是否为obj
的属性
因为可以赋予某个属性的值为undefined
读属性
- 查看自身所有属性:
Object.keys(obj)
只看属性名
Object.values(obj)
只看属性值
obj
和Object.entries(obj)
:名字和值都看(推荐前者)
- 查看自身+共有属性
console.dir(obj)
或者可以打出隐藏属性的名字,不推荐
(查看自身+共有属性,可以考虑用for-in循环——待学习)
- 判断一个属性是自身还是共有
obj.hasOwnProperty('toString')
区分于in
,in
是看是否含有,hasOwnProperty
是看是否自身的
- 查看属性
中括号语法:obj['key']
注意单引号不要掉了,优先用
点语法:obj.key
- 查看属性特殊情况:[ ]里不是字符串要先计算
obj.name
等价于obj['name']
obj.name
不等价于obj[name]
- 总结:这里的 name 是字符串,而不是变量
- 当
let name = 'frank'
,这里的 name 是变量
因此:obj[name]
等价于obj['frank']
原型
1.每个对象都有原型
- 原型里存折对象的共有属性
- 比如
obj
的原型就是一个对象 obj.__proto__
存着这个对象的地址- 这个对象里有:
toString
、construction
、valueOf
等属性
2.对象的原型也是对象
- 对象的原型也有原型
obj={}
的原型即为所有对象的原型- 这个原型包含所有对象的共有属性,是对象的根
- 这个原型也有原型,是 null(是被人为指定为null)
写属性
修改或增加属性
1.直接赋值
obj.name = 'jack'
赋值给name,没有name属性就增加obj['name'] = 'jack'
同上obj['na'+'me'] = 'jack'
先运算结果为'name'
,同上
2.批量赋值
Object.assign(obj,{p1:1,p2:2,p3:3})
3.修改或增加共有属性
- 无法通过自身修改或增加共有属性
只能读到共有属性,任何修改都是基于自身的改变
相当于obj
有了两个toString
,但用的时候没办法用共有的,只能用自己的
- 偏要修改原型上的属性
直接从原型进去修改toString
,这样就改变了原型上的toString
1.obj.__proto__.toString = 'xxx'
不推荐使用这个方法
2.window.Object.prototype
是window上的属性,从这上面改
3.2 修改隐藏属性(原型链)
- 不推荐使用
__proto__
- 推荐使用
Object.creat
直接以 common为原型创建对象
let obj = Object.create(common)
- 原型链:这样创造出来的叫做一个原型链(三个对象连成一串)
总结