[关闭]
@Dale-Lin 2018-11-25T17:22:18.000000Z 字数 2905 阅读 651

ES6 扩展对象的功能性

深入理解ES6


对象字面量语法扩展

属性初始值的简写

当对象字面量里只有一个属性名而没有属性值时,js引擎会在可访问作用域中查找同名变量;如果找到,则该变量的值被赋予对象字面量的同名属性:

  1. function createPerson(name, age) {
  2. return {
  3. name,
  4. age
  5. };
  6. }

对象方法的简写语法

为对象添加方法,不必使用冒号和另外的 function 关键字:

  1. var person = {
  2. name: "Nicholas",
  3. sayName() {
  4. console.log(this.name);
  5. }
  6. };

可计算属性名(Computed Property Name)

ES6 中,可在对象字面量中使用可计算属性名称,其语法与引用对象实例的可计算属性名称相同,也是使用方括号:

  1. let lastName = "last name";
  2. let person = {
  3. "first name": "Nicholas",
  4. [lastName]: "Zakas"
  5. };
  6. console.log(person["first name"]); //"Nicholas"
  7. console.log(person[lastName]); //"Zakas"

新增方法

ES6 在全局 Object 对象上引入了一些新方法:

Object.is()

Object.is() 方法在大部分情况下与 === 运算符相同,唯一区别在于 +0 和 -0 被识别为不相等,且 NaN 与 NaN 等价。

Object.assign()

许多 js 库中有一个 mixin 方法,用来让一个对象接受另一个对象的属性和方法:

  1. function mixin(receiver, supplier) {
  2. Object.keys(supplier).forEach(function(key) {
  3. receiver[key] = supplier[key];
  4. });
  5. return receiver;
  6. }

注意是浅复制;当属性值是引用对象时只复制引用。

这样一来,不通过继承就可以获得新属性:

  1. function EventTarget(){
  2. /*...*/
  3. }
  4. EventTarget.prototype = {
  5. constructor: EventTarget,
  6. func1: function() {/*..*/},
  7. func2: function() {/*...*/}
  8. };
  9. var myObject = {};
  10. mixin(myObject, EventTarget.prototype);
  11. myObject.func1("some argements");

myObject 对象接受了 EventTarget.prototype 的所有行为。

由于这种混合模式的流行,ES6 添加了 Object.assign() 方法,该方法接收一个接收对象和任意数量的源对象,最终返回接收对象。

任何使用 mixin() 方法的地方都可以直接使用 Object.assign() 方法替换:

  1. var receiver = {};
  2. Object.assign(receiver,
  3. {
  4. type: "js",
  5. name: "file.js"
  6. },
  7. {
  8. type: "css"
  9. }
  10. };
  11. console.log(receiver.type); //"css"
  12. console.log(receiver.name); //"file.js"

Object.assign() 方法可以接受任意数量的源对象,并按指定顺序将属性复制到接收对象中。
如果多个源对象具有同名属性,则排位靠后的源对象会覆盖排位靠前的。

切记,Object.assign() 或 mixin() 方法都不能将提供者的访问器属性(getter)复制到接收对象中。

由于 mixin() 方法使用 = 赋值,访问器属性将不被添加。
Object.assign() 方法则会将访问器属性转变成接收对象中的一个数据属性:

  1. var receiver = {},
  2. supplier = {
  3. get name() {
  4. return "file.js"
  5. }
  6. };
  7. Object.assign(receiver, supplier);
  8. console.log(receiver); //{name: "file.js"}

重复的对象字面量属性

ES6 中,如果在一个对象字面量中声明同名属性,后者会覆盖前者而不是报错。

自有属性枚举属性

ES6 规定了对象的自有属性在几个方法中枚举时返回的顺序:

  1. var obj = {
  2. a: 1,
  3. 0: 1,
  4. c: 1,
  5. 2: 1,
  6. b: 1,
  7. 1: 1
  8. };
  9. obj.b = 1;
  10. console.log(Object.getOwnPropertyNames(obj).join("")); //"012acbd"

对于常用的 for-in 循环、Object.keys() 方法、JSON.stringify() 方法的枚举顺序依然不确定。

增强对象原型

Object.getPrototypeOf()

该方法返回任意指定对象的原型。

Object.setPrototypeOf()

该方法可以改变任意指定对象的原型。它接受两个参数,被改变原型的对象及替代第一个参数原型的对象:

  1. let person = {
  2. getGreeting() {
  3. return "Hello";
  4. }
  5. };
  6. let dog = {
  7. getGreeting() {
  8. return "Woof";
  9. }
  10. };
  11. //以person为原型
  12. let friend = Object.create(person);
  13. console.log(friend.getGreeting()); //"Hello"
  14. console.log(Object.getPrototypeOf(friend) === person); //true
  15. //将原型设置为dog
  16. Object.setPrototypeOf(friend, dog);
  17. console.log(friend.getGreeting()); //"Woof"
  18. console.log(Object.getPrototypeOf(friend) === dog); //true

简化原型访问的 Super 访问

对象内部的 Super 引用相当于指向对象原型的指针,实际上就是 Object.getPrototypeOf(this) 的值。

Super 引用在多重继承的情况下非常有用,能避免 Object.getPrototypeOf() 方法的一些问题

正式的方法定义

作为对象属性的函数称为方法,ES6 有一个内部的 [[HomeObject]] 属性来容纳这个方法从属的对象:

  1. let person = {
  2. //是方法
  3. getGreeting() {
  4. return "Hello";
  5. }
  6. };
  7. //不是方法
  8. function shareGreeting() {
  9. return "Hi!";
  10. }

Super 的所有引用都通过 [[HomeObject]] 属性来确定后续的运行过程。第一步是在 [[HomeObjct]] 属性上调用 Object.getPrototypeOf() 方法来检索原型的引用;然后搜索原型找到同名函数;最后设置 this 绑定并且调用相应的方法

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注