过完中秋就变懒了,这几天看了看图解算法有点小收获。又赶上去去上海听泽野弘之的演奏会,所以这边的更新就慢了下来,这几天把他补上。
理解对象
创建自定义对象的最简单的方式就是创建一个Object实例
1
2
3
4
5
6
7let person = {
name: 'xnnnnn',
age: 22,
sayName: function() {
console.log(this.name)
}
}
对象有两种属性:数据属性和访问器属性
数据属性
数据属性包含一个数据值的位置(Value)。在这个位置能读取和写入值。有四个描述其行为的特性。
Configurable
表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。
Enumerable
表示能否通过for-in 循环属性的特性。
Writable
表示能否修改属性的值。
Value
包含这个属性的数据值。读取属性值的时候,把新值保存在这个位置。这个特性默认为undefined。
对于上面那个的那个定义对象的方式,Configurable、Enumerable 都被设置成了 true,Value被设置成了指定的值。
要修改属性的特性必须使用Object.defineProperty()。
Object.defineProperty()
这个方法接受三个参数:属性所在的对象、属性的名字、和一个描述对象。其中,描述符对象属性必须是:configurable、enumberable、writable和value。设置其中的一个或者多个,可以修改队形的特性值。
1 | let person = {}; |
这两天复习ES6又补充了点新知识,本想开个ES6笔记的坑然后看见之前有关于对象的笔记,索性就写在这里。
Object.is()
用途基本上和 ‘===’相同,但是在 +0与-0、NaN与Nan的判断上有些出入
1 | console.log(+0 === -0) // true |
Object.assign(target,…source)
用途:深拷贝,拷贝可枚举属性给目标对象。
注意点:属性限定简单类型。同名的属性会被覆盖(调用target的set和source的get)。
ES6里Object的属性顺序规则
具体规则: 数字key > 其他key(按照设置的先后顺序排列)
1 | let obj = { |
可枚举性和遍历
对象的每个属性都有一个描述对象。用来控制该属性的行为。Object.getOwnPropertyDescriptor(object, ‘attributes’) 能获取到行为的描述对象。
1 | let temp = { |
可遍历对象可枚举的方法有(忽略enumberable为 false的):
for…in 遍历继承和自身的可枚举属性。
JSON.Stringfy() 字符串化可枚举的属性
Object.keys() 返回自身可枚举的键名
Object.assign() 只能拷贝自身的可枚举属性
其中for…in会遍历继承过来的属性,而其他三个不会属性的遍历
- for…in
遍历继承和自身的可枚举属性不包括symbol - Object.keys()
遍历自身可枚举属性的键值,返回一个数组。 - Object.getOwnPropertyNames()
遍历自身所有的属性(不包括symbol属性,包括不可枚举属性),返回一个数组。 - Object.getOwnPropertySymbol()
遍历自身的所有symbol属性的键名,返回一个数组。 - Reflect.ownKeys()
遍历自身的所有属性(包括symbol属性和不可枚举属性)的键名,返回一个数组。
- for…in
对象的解构
1 | let { b, a, ...c } = { a: 1, b: 2, c: 3, d: 4 } |
备注:在上面的例子 b、a 属于解构赋值,能赋值继承过来的属性。…c属于扩展运算符的解构赋值不能复制继承过来的属性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19const proto = {
foo: 'hello',
xx: 'xnnnnn'
};
const obj = {
foo: 'world',
find() {
return super.foo;
}
};
Object.setPrototypeOf(obj, proto);
for(let item in obj){console.log(item)}
let {a, xx}= obj //解构赋值
console.log(xx) //"xnnnnn"
let {a,...xx} = obj // 扩展运算符解构赋值
console.log(xx) // {foo: "world", find: ƒ}解释:左右侧得有相同的属性名才会成功赋值,’…c’这种形式的会赋值右侧对象里可枚举的属性,但尚未读取的属性。
注意:解构赋值要求等号右面是个对象,还是浅拷贝。 右侧是null或者undefined会报错。 且 …c ,也要放在参数的最后。不然会报语法错误。
super
指向当前对象的原型对象。
注意:super表示原型对象时,只能用在对象的方法里。用在其他地方会报错。
1 | let superObj = { |
链判断运算符
直接上代码好理解
1 | let name = request?.data?.name ?? 'xnnnn' //attr |
以上两个是从顶部判断属性是否存在,request?代表request是否存在,?? 是||的代替符,||在值是false或者0的时候会返回右侧值。而??(null判断运算符)只对null和undefined返回右侧值。
- 注意: 1. ??和其他运算符(|| &&)是必须用括号圈起来表示优先级,否则会报错。
2. 关于?的语法问题: new a?.(), a?.`{b}`, super?.(), a?.b = c, 构造函数,右侧有模板字符串,左侧是 super,用于赋值运算符左侧都会报错