ES6 对象
简洁的表达方式
- 直接在对象下写属性
const foo = 'bar';
const baz = { foo };
baz // {foo: "bar"}
// 等同于
const baz = { foo: foo };
- 可以在对象下直接写方法
const o = {
method() {
return "Hello!";
}
}
// 等同于
const o = {
method: function () {
return "Hello!";
}
}
简单使用:
- 函数的返回值
CommonJS
模块输出一组变量
// 直接输出变量
function getPoint() {
const x = 1;
const y = 10;
return { x, y };
}
getPoint(); // {x:1, y:10}
// CommonJS 的导出
let ms = {};
function getItem (key) {
return key in ms ? ms[key] : null;
}
module.exports = { getItem };
属性名表达式
在 ES5
中定义对象的属性,有以下两种形式:
// 方法一:直接命名
obj.foo = true;
// 方法二:使用变量
obj['a' + 'bc'] = 123;
如果直接实例化的对象,在 ES5
中只能用方法一定义属性。
var obj = {
foo: true,
abc: 123
};
而在 ES6
中直接实例化的对象,也能使用方法二了。
let propKey = 'foo';
let obj = {
[propKey]: true,
['a' + 'bc']: 123
};
Object.is
效果基本与 ===
一致,仅仅有两点区别:
+0 === -0 // true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
Object.assign()
对象的合并,仅仅执行浅拷贝。将之后的对象下的属性链接到第一个对象下。注意是链接,所以是引用赋值。
Object.assign
拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性( enumerable: false
)。
const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a: 1, b: 2, c: 3}
注:
- 浅拷贝。
- 同名属性替换。
- 把数组当做普通对象,也就是数组的索引会被认为是对象下的
key
。 - 对于函数的处理:会直接取函数的返回值。
- 永远都是值拷贝,所以不能正确处理用
definePropertie(s)
添加的数据。
可枚举性
通过 getOwnPropertyDescriptor
方法获取对象下,对应属性的描述信息。
let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo');
// {
// value: 123,
// writable: true,
// enumerable: true,
// configurable: true
// }
四个会忽略 enumerable
为 false
的属性的操作
for...in
: 遍历对象自身和继承的可枚举属性Object.keys()
: 返回对象自身的所有可枚举属性的键名JSON.stringify()
: 串行化对象自身的可枚举属性Object.assign()
: 仅拷贝对象自身的可枚举属性
属性的遍历
for...in
: 遍历对象自身和继承的可枚举属性(不含Symbol
属性)。Object.keys(obj)
: 返回数组,仅包含对象自身属性(不含Symbol
属性)的键名。Reflect.ownKeys(obj)
: 返回数组,包含对象自身的所有键名(包含Symbol
和不可枚举属性)。Object.getOwnPropertyNames(obj)
: 返回数组,包含对象自身所有属性(不含Symbol
属性,但包含不可枚举属性))的键名。Object.getOwnPropertySymbol(obj)
: 返回数组,包含对象所有Symbol
属性的键名。
遍历顺序
- 数字升序
- 字符串按加入时间升序
Symbol
按加入时间升序
原型链
// es5 的写法
const obj = {
method: function() { ... }
};
obj.__proto__ = someOtherObj;
// es6 的写法
var obj = Object.create(someOtherObj);
obj.method = function() { ... };
ES6
规范了原型链的使用以及创建,ES5
中直接使用 __proto__
来实现原型链,在 ES6
中,使用 create/getPrototypeOf/setPrototypeOf
来实现原型,并且 __proto__
应该仅仅存在于浏览器上,所以之后应该用 ES6
的方式实现原型。
3个对象遍历器
Object.keys
、Object.values
、Object.entries
,分别获取到对象的键名、键值和键值对,供 for...of
使用。
成员是参数对象自身的(不含继承的)所有可枚举(enumerable
)属性的键名。
对象的扩展运算符
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }
和数组类似, ...
运算符也只能出现在最后。
let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }