前言
本系列主要整理前端面试中需要掌握的知识点。本节介绍ES6中对象新增的扩展 。
一、属性的简写
- 对象键名和对应值名相等的时候,可以简写;
const baz = {foo:foo}
// 等同于
const baz = {foo}
- 方法可以简写。但是简写的对象方法不能用作构造函数,否则会报错
const o = {
method() {
return "Hello!";
}
};
// 等同于
const o = {
method: function() {
return "Hello!";
}
}
二、属性名表达式
- ES6允许字面量定义对象时,将表达式放在括号里
let lastWord = 'last word';
const a = {
'first word': 'hello',
[lastWord]: 'world'
};
a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"
- 表达式还可以用于定义方法名
let obj = {
['h' + 'ello']() {
return 'hi';
}
};
obj.hello() // hi
- 属性名表达式与简洁表示法,不能同时使用,会报错
// 错误
const foo = 'bar';
const bar = 'abc';
const baz = {[foo]}; //Uncaught SyntaxError: Unexpected token '['
//正确
const foo = 'bar';
const bar = 'abc';
const baz = {[foo]:'abc'}
console.log(baz);
- 属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[object Object]
const keyA = {a: 1};
const keyB = {b: 2};
const myObject = {
[keyA]: 'valueA',
[keyB]: 'valueB'
};
myObject // Object {[object Object]: "valueB"}
三、super关键字
this关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象
const proto = {
foo:'hello'
};
const obj = {
foo:'world',
find(){
return super.foo;
}
}
Object.setPrototypeOf(obj,proto)
console.log(obj.find());
四、扩展运算符的应用
- 在解构赋值中,未被读取的可遍历的属性,分配到指定的对象上面
- 解构赋值必须是最后一个参数,否则会报错
- 解构赋值是浅拷贝
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }
五、属性的遍历
ES6一共有5种方法可以遍历对象的属性。
方法 | 作用 |
---|---|
for…in | 循环遍历对象自身的和继承的可枚举属性(不含Symbol属性) |
Object.keys(obj) | 返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名 |
Object.getOwnPropertyNames(obj) | 回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名 |
Object.getOwnPropertySymbols(obj) | 返回一个数组,包含对象自身的所有 Symbol 属性的键名 |
Reflect.ownKeys(obj) | 返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举 |
let obj1 = {
'name':'Marry',
'age':'18',
'sex':'girl',
'school':'collage',
[Symbol()]:0
};
// way1
for(o in obj1){
console.log(o);
}
// way2
console.log(Object.keys(obj1)); //['name', 'age', 'sex', 'school']
// way3
console.log(Object.getOwnPropertyNames(obj1)); //['name', 'age', 'sex', 'school']
// way4
console.log(Object.getOwnPropertySymbols(obj1)); // [Symbol()]
// way5
console.log(Reflect.ownKeys(obj1)); //['name', 'age', 'sex', 'school', Symbol()]
六、对象新增的方法
方法 | 作用 |
---|---|
Object.is() | 严格判断两个值是否相等,与严格比较运算符(===)的行为基本一致,不同之处只有两个:一是+0不等于-0,二是NaN等于自身 |
Object.assign() | Object.assign()方法用于对象的合并,将源对象source的所有可枚举属性,复制到目标对象target |
Object.getOwnPropertyDescriptors() | 返回指定对象所有自身属性(非继承属性)的描述对象 |
Object.setPrototypeOf() | 设置一个对象的原型对象 |
Object.getPrototypeOf() | 读取一个对象的原型对象 |
Object.keys() | 返回自身的(不含继承的)所有可遍历(enumerable)属性的键名的数组 |
Object.values() | 返回自身的(不含继承的)所有可遍历(enumerable)属性的键对应值的数组 |
Object.entries() | 返回一个对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对的数组 |
Object.fromEntries() | 将一个键值对数组转为对象 |
let obj = {
'name':'Marry',
'age':'18',
'sex':'girl',
'school':'collage',
[Symbol()]:0
};
// 1
console.log(Object.is(+0,-0));
console.log(Object.is(NaN,NaN));
// 2
const target = {a:1,b:1};
const source1 = {b:2,c:2};
const source2 = {c:3};
Object.assign(target,source1,source2)
console.log(target);
// 3
console.log(Object.getOwnPropertyDescriptors(obj));
// age: {value: '18', writable: true, enumerable: true, configurable: true}
// name: {value: 'Marry', writable: true, enumerable: true, configurable: true}
// school: {value: 'collage', writable: true, enumerable: true, configurable: true}
// sex: {value: 'girl', writable: true, enumerable: true, configurable: true}
// Symbol(): {value: 0, writable: true, enumerable: true, configurable: true}
// [[Prototype]]: Object
// 4
const proto = {
foo:'hello'
};
const obj1 = {
foo:'world',
find(){
return super.foo;
}
}
Object.setPrototypeOf(obj1,proto)
// 5
console.log(Object.getPrototypeOf(obj));
// 6
console.log(Object.keys(obj));
// 7
console.log(Object.values(obj));
// 8
console.log(Object.entries(obj));
// 9
let obj2 = Object.fromEntries([
['foo','bar']
])
console.log(obj2);