zoukankan      html  css  js  c++  java
  • 深入理解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
     
  • 相关阅读:
    【LeetCode】119. Pascal's Triangle II
    随机梯度下降(Stochastic gradient descent)和 批量梯度下降(Batch gradient descent )的公式对比、实现对比[转]
    linux下一些可用库
    malloc分配的内存空间是连续的吗
    语言模型训练网站
    relocation 错误
    undefined reference to `dlopen'
    静态库之间有依赖关系顺序很重要
    C++引用详解
    malloc原理和内存碎片[转]
  • 原文地址:https://www.cnblogs.com/gdjlc/p/14528760.html
Copyright © 2011-2022 走看看