• 深入理解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
     
  • 相关阅读:
    Hard Rock
    Codeforces Round #416 (Div. 2) B. Vladik and Complicated Book
    codeforces 793B. Igor and his way to work
    codeforces 1B Spreadsheets
    HDU 1069 Monkey and Banana
    codeforces 2B The least round way
    【机器学习】 通俗说拟合
    python-八皇后问题
    python-核心知识思维导图
    python-@property 属性
  • 原文地址:https://www.cnblogs.com/gdjlc/p/14528760.html
Copyright © 2020-2023  润新知