1、ES6允许直接写入变量和函数,作为对象的属性和方法。这种写法用于函数的返回值,将会非常方便。CommonJS模块输出变量,就非常合适使用简洁写法。
var ms = {}; function getItem (key) { return key in ms ? ms[key] : null; } function setItem (key, value) { ms[key] = value; } function clear () { ms = {}; } module.exports = { getItem, setItem, clear }; // 等同于 module.exports = { getItem: getItem, setItem: setItem, clear: clear };
2、ES6 允许字面量定义对象时,用表达式作为对象的属性名,即把表达式放在方括号内。
let propKey = 'foo'; let obj = { [propKey]: true, ['a' + 'bc']: 123 };
3、ES5比较两个值是否相等,只有两个运算符:相等运算符(==
)和严格相等运算符(===
)。它们都有缺点,前者会自动转换数据类型,后者的NaN
不等于自身,以及+0
等于-0
。
ES6提出“Same-value equality”(同值相等)算法,用来解决这个问题。Object.is
就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。
+0 === -0 //true NaN === NaN // false Object.is(+0, -0) // false Object.is(NaN, NaN) // true
4、Object.assign
方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
Object.assign
方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
对于这种嵌套的对象,一旦遇到同名属性,Object.assign
的处理方法是替换,而不是添加。
注意,Object.assign
可以用来处理数组,但是会把数组视为对象。
Object.assign([1, 2, 3], [4, 5]) // [4, 5, 3] //上面代码中,Object.assign把数组视为属性名为0、1、2的对象,因此源数组的0号属性4覆盖了目标数组的0号属性1。
5、ES5有三个操作会忽略enumerable
为false
的属性。
for...in
循环:只遍历对象自身的和继承的可枚举的属性Object.keys()
:返回对象自身的所有可枚举的属性的键名JSON.stringify()
:只串行化对象自身的可枚举的属性- ES6新增了一个操作
Object.assign()
,会忽略enumerable
为false
的属性,只拷贝对象自身的可枚举的属性。
总的来说,操作中引入继承的属性会让问题复杂化,大多数时候,我们只关心对象自身的属性。所以,尽量不要用for...in
循环,而用Object.keys()
代替。
6、属性的遍历:
- for...in——遍历对象自身的和继承的可枚举属性(不含Symbol属性)。
- Object.keys(obj)——返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)。
- Object.getOwnPropertyNames(obj)——返回一个数组,包含对象自身的所有属性(不含Symbol属性,但是包括不可枚举属性)。
- Object.getOwnPropertySymbols(obj)——返回一个数组,包含对象自身的所有Symbol属性。
- Reflect.ownKeys(obj)——返回一个数组,包含对象自身的所有属性,不管是属性名是Symbol或字符串,也不管是否可枚举。
以上的5种方法遍历对象的属性,都遵守同样的属性遍历的次序规则。
- 首先遍历所有属性名为数值的属性,按照数字排序。
- 其次遍历所有属性名为字符串的属性,按照生成时间排序。
- 最后遍历所有属性名为Symbol值的属性,按照生成时间排序。
7、ES5 引入了Object.keys
方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。ES2017 引入了跟Object.keys
配套的Object.values
和Object.entries
,作为遍历一个对象的补充手段,供for...of
循环使用。
Object.values
只返回对象自身的可遍历属性。
var obj = Object.create({}, {p: {value: 42}}); Object.values(obj) // []
上面代码中,Object.create
方法的第二个参数添加的对象属性(属性p
),如果不显式声明,默认是不可遍历的,因为p
的属性描述对象的enumerable
默认是false
,Object.values
不会返回这个属性。只要把enumerable
改成true
,Object.values
就会返回属性p
的值。
8、现在有一个提案,引入了“Null 传导运算符”(null propagation operator)?.
“Null 传导运算符”有四种用法。
obj?.prop
// 读取对象属性obj?.[expr]
// 同上func?.(...args)
// 函数或对象方法的调用new C?.(...args)
// 构造函数的调用
?.
运算符,只要其中一个返回null
或undefined
,就不再往下运算,而是返回undefined
。