对象的扩展
/ / 点击 / 阅读耗时 7 分钟属性,方法的简洁写法
- 属性名为变量名,属性值为变量值。
1 | const name = 'lrh'; |
方法的简写
1
2
3
4
5
6
7
8const age = 18;
const person = {
name: 'lrh',
age,
getName() {
return this.name
}
}
属性名可以使用表达式
1 | //ES5定义对象的属性 |
使用Object.is()方法比较两个值相等
- 相等运算符(==)会自动转换数据类型。
- 严格相等运算符(===)会导致NaN不等于NaN,+0等于-0。
Object.is()方法与严格相等基本一致,并弥补了以上两个不足。
1
2
3
4NaN === NaN;
+0 === -0;
Object.is(NaN, NaN);
Object.is(+0, -0);
使用Object.assign()方法浅拷贝对象
将源对象合并到目标对象
如果有同名属性,源对象的属性会覆盖掉目标对象的属性。
该方法是浅拷贝,即如果源对象的某个属性值是对象,那么目标对象拷贝的是这个对象的引用,源对象的任何变化,都会反映到目标对象上。
1
2
3
4
5const target = {a: 1};
const source1 = {b: 2};
const source2 = {c: 3};
Object.assign(target, source1, source2);
target;//{ a: 1, b: 2, c: 3 }常见用途
为对象添加属性
1
2
3
4
5
6class Person{
constructor(name, age) {
Object.assign(this, {name, age});
}
}
new Person('lrh', 18);
- 为对象添加方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Person{
constructor(name, age) {
Object.assign(this, {name, age});
}
}
Object.assign(Person.prototype, {
getName() {
return this.name;
},
getAge() {
return this.age;
}
});
new Person('lrh', 18).getName();//lrh
//等同于
Person.prototype.getName = function() {
return this.name;
};
克隆对象
1
2
3
4
5
6
7const person = {
name: 'lrh',
age: 18
};
const p = Object.assign({}, person);//{ name: 'lrh', age: 18 }
Object.is(person, p);//false合并对象
1
2
3const source1 = {name: 'lrh'};
const source2 = {age: 18};
const p = Object.assign({}, source1, source2);//{ name: 'lrh', age: 18 }为属性指定默认值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17const options = {
container: '#wrap',
draggable: true,
resizable: true,
blinkTime: 4000
};
class Draggable{
constructor(options) {
const DEFAULT = {
container: '',
draggable: true,
resizable: false,
}
this.options = Object.assign({}, DEFAULT, options);
}
}
遍历属性
for…in遍历对象自身的和继承的可枚举属性,不包含Symbol属性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23class Person{
constructor(name, age) {
Object.assign(this, {name, age});
}
}
Person.prototype.type = 'Person';
const person = new Person('lrh', 18, 'male');
for (let p in person) {
console.log(p);
}
//name
//age
//gender
for (let p in person) {
if (person.hasOwnProperty(p)) {
console.log(p);
}
}
//name
//ageObject.keys(obj)返回一个数组,包含对象自身所有的可枚举属性,不包含继承的属性,不包含Symbol属性。
1
2
3
4
5
6
7const type = Symbol('type');
const person = {
name: 'lrh',
age: 18,
[type]: 'Student'
};
Object.keys(person);//['name', 'age']Object.getOwnPropertyNames(obj)返回一个数组,包含对象自身所有的可枚举属性和不可枚举属性,不包含Symbol属性。
1
2const arr = [1, 2, 3]
Object.getOwnPropertyNames(arr);//['0', '1', '2', 'length']Object.getOwnPropertySymbols(obj)返回一个数组,包含所有Symbol属性。
Reflect.ownKeys(obj)返回一个数组,包含所有可枚举属性,不可枚举属性,Symbol属性。
ES2015新增遍历法:Object.keys(), ES2017新增遍历方法:Object.values(), Object.entries()。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35const person = {
name: 'lrh',
age: 18
};
Object.keys(person);//[ 'name', 'age' ]
Object.values(person);//[ 'lrh', 18 ]
Object.entries(person);//[ [ 'name', 'lrh' ], [ 'age', 18 ] ]
//自己实现entries()方法
function* entries(obj) {
for (let key of Object.keys(obj)) {
yield [key, obj[key]];
}
}
let personEntries = entries(person);
for(let p of personEntries) {
console.log(p)
}
//[ 'name', 'lrh' ]
//[ 'age', 18 ]
//如果没有使用entries()方法,可以给Symbol.iterator配置默认的迭代器
Object.assign(person, {
* [Symbol.iterator]() {
for (let key of Object.keys(this)) {
yield [key, this[key]];
}
}
});
for (let entries of person) {
console.log(entries);
}
//[ 'name', 'lrh' ]
//[ 'age', 18 ]
使用扩展运算符
扩展运算符是用于操作数组的
ES2018将这个运算符引入到了对象中
用于取出参数对象的所有可遍历属性,拷贝到当前对象中,等同于使用Object.assign()。
1
2
3
4
5
6const person = {
name: 'lrh',
age: 18
};
const p = {...person, type: 'student'};
p;//{ name: 'lrh', age: 18, type: 'student' }