深入理解ES6读书笔记4:扩展的对象功能

一、对象字面量语法的扩展

1、属性初始化器的简写
ES6中函数的属性名和参数名相同时,可以省略属性名后面的冒号和值。
因为当对象字面量中的属性只有名称时,JS 引擎会在周边作用域查找同名变量。

//ES5及更早版本
function createPerson1(name, age){
    return{
        name: name,
        age: age
    };
}
var person1 = createPerson1('张三', 20);
console.log(person1.name, person1.age);//张三 20

//ES6版本
function createPerson2(name, age){
    return{
        name,
        age
    };
}
var person2 = createPerson2('李四', 21);
console.log(person2.name, person2.age);//李四 21

2、方法简写
ES6对象字面量中方法名后面的冒号和function关键字可以省略。

//ES5及更早版本
var person1 = {
    name: "张三",
    sayName: function() {
        console.log(this.name);
    }
};
person1.sayName();//张三

//ES6版本
var person2 = {
    name: "李四",
    sayName() {
        console.log(this.name);
    }
};
person2.sayName();//李四

3、需计算属性名
需计算属性名是对象字面量语法的一部分,用方括号表示法

var suffix = " name";
var person = {
    ["first" + suffix]: "Nicholas",
    ["last" + suffix]: "Zakas",
    age: 20
};
//属性名包含空格,无法用小数点表示法来引用
console.log(person["first name"]); // "Nicholas"
console.log(person["last name"]); // "Zakas"
console.log(person["age"]);//20
console.log(person.age);//20

二、新的方法

1、Object.is() 方法
比较两个值时,有相等运算符( == )和严格相等运算符( ===)。为了避免在比较时发生强制类型转换,一般使用后者。
但严格相等运算符也并不完全准确,例如,它认为 +0 与 -0 相等,即使这两者在 JS 引擎中有不同的表示;另外 NaN === NaN 会返回 false,因此有必要使用 isNaN() 函数来正确检测 NaN。
ES6引入的Object.is()方法要求二者类型相同并且值也相等。在许多情况下,Object.is() 的结果与 === 算符是相同的,仅有的例外是:
+0 与 -0 不相等,NaN 等于 NaN。

console.log(+0 == -0); // true
console.log(+0 === -0); // true
console.log(Object.is(+0, -0)); // false

console.log(NaN == NaN); // false
console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // true

console.log(5 == 5); // true
console.log(5 == "5"); // true
console.log(5 === 5); // true
console.log(5 === "5"); // false
console.log(Object.is(5, 5)); // true
console.log(Object.is(5, "5")); // false

2、Object.assign() 方法
混入( Mixin )模式是指在一次混入中,一个对象会从另一个对象中接收属性与方法。

function mixin(receiver, supplier) {
    Object.keys(supplier).forEach(function(key) {
        receiver[key] = supplier[key];
    });
    return receiver;
}

function EventTarget() { /*...*/ }
EventTarget.prototype = {
    constructor: EventTarget,
    emit: function() { /*...*/ },
    on: function() { /*...*/ }
};
var myObject = {};
mixin(myObject, EventTarget.prototype);
myObject.emit("somethingChanged");

mixin() 函数在 supplier 对象的自有属性上进行迭代,并将这些属性复制到 receiver 对象(浅复制,当属性值为对象时,仅复制其引用)。这样 receiver 对象就能获得新的属性而无须使用继承。
myObject 对象接收了 EventTarget.prototype 对象的行为,这给了它分别使用 emit()与 on() 方法来发布事件与订阅事件的能力。
ES6的 Object.assign() 方法来完成同样的行为。
上面代码可以改为

Object.assign(myObject, EventTarget.prototype);

三、重复的对象字面量属性

当存在重复属性时,ES5 严格模式下会报语法错误,但ES6 中排在后面的属性的值会成为该属性的实际值。

"use strict";

var person = {
    name: "Nicholas",
    name: "Greg" // 在 ES6 严格模式中不会出错
};
console.log(person.name);//Greg

四、自有属性的枚举顺序

ES5 没有定义对象属性的枚举顺序,而是把该问题留给了 JS 引擎厂商。
ES6 定义了对象自有属性在被枚举时返回的顺序。影响了Object.getOwnPropertyNames()与Reflect.ownKeys的返回属性,还同样影响了Object.assign() 处理属性的顺序。
自有属性枚举时基本顺序如下:
1. 所有的数字类型键,按升序排列。
2. 所有的字符串类型键,按被添加到对象的顺序排列。
3. 所有的符号类型键,也按添加顺序排列。

var obj = {
a: 1,
0: 1,
c: 1,
2: 1,
b: 1,
1: 1
};
obj.d = 1;
console.log(Object.getOwnPropertyNames(obj).join("")); // "012acbd"

五、更强大的原型

1、修改对象的原型
ES5,对象的原型在初始化完成后会保持不变。
ES6 通过添加 Object.setPrototypeOf() 方法,允许修改任意指定对象的原型。

let person = {
    getGreeting() {
        return "Hello";
    }
};
let dog = {
    getGreeting() {
        return "Woof";
    }
};
// 原型为 person
let friend = Object.create(person);
console.log(friend.getGreeting()); // "Hello"
console.log(Object.getPrototypeOf(friend) === person); // true
// 将原型设置为 dog
Object.setPrototypeOf(friend, dog);
console.log(friend.getGreeting()); // "Woof"
console.log(Object.getPrototypeOf(friend) === dog); // true

2、使用 super 引用的简单原型访问

let person = {
    getGreeting() {
        return "Hello";
    }
};
let dog = {
    getGreeting() {
        return "Woof";
    }
};
let friend = {
    getGreeting() {
        //旧的用法
        //return Object.getPrototypeOf(this).getGreeting.call(this) + ", hi!";
        //新的用法
        return super.getGreeting() + ", hi!";
    }
};
// 将原型设置为 person
Object.setPrototypeOf(friend, person);
console.log(friend.getGreeting()); // "Hello, hi!"
console.log(Object.getPrototypeOf(friend) === person); // true
// 将原型设置为 dog
Object.setPrototypeOf(friend, dog);
console.log(friend.getGreeting()); // "Woof, hi!"
console.log(Object.getPrototypeOf(friend) === dog); // true
 
原文地址:https://www.cnblogs.com/gdjlc/p/14528760.html