美文网首页
ES6学习系列之- 对象的扩展

ES6学习系列之- 对象的扩展

作者: 尤小小 | 来源:发表于2017-09-21 01:09 被阅读11次

    Part4 对象的扩展

    4.1 对象的简洁表示法

    es6允许在对象之中,直接写变量, 属性和方法都可以。

    {
        let a = 1; 
        let b = 2;
        let fun = () => 'es6';
    
        let foo = {
            a, 
            b,
            fun,
            method() {
                return 'h5!'
            }
        };
    
        console.log(foo);  
        // {a: 1, b: 2, fun: ƒ, method: ƒ}
    }
    
    // 等同于
    
    {
        var a = 1;
        var b = 2;
        var fun = function() {
            return 'es6'
        }
    
        var foo = {
            a: a,
            b: b,
            fun: fun,
            method: function() {
                return 'h5!'
            }
        };
    
        let x = {a: a, b: b};
        console.log(foo);  
        // {a: 1, b: 2, fun: ƒ, method: ƒ}
    }
    

    在CommonJs规范中,模块输出变量通过 module.exports 将定义好的方法,一个个导出。主站中的将所有方法都写在obj对象下,module.exports时,只需要导出obj对象,我认为咱们主站的方法,更简洁。

    // init, handleChange定义好的方法
    {
        module.exports = { init, handleChange };
        // 等同于
        module.exports = { init: init, handleChange: handleChange}
    }
    

    4.2 属性名表达式【计算属性名称】

    es6 允许字面量定义对象时,用 表达式 作为对象的属性名和方法名,即把表达式放在方括号内。

    {
      let obj = {
        ['h' + '5']: 'h5',
        ['es' + '6']() {
          console.log('es6');
        }
      };
      
      obj; // {h5: "h5", es6: ƒ}
      console.log(obj.h5); // h5
      console.log(obj.es6()); // es6
    }
    
    {
      // 注意:属性名表达式与简洁表示法,不能同时使用,会报错
      let foo = 'bar';
      let bar = 'abc';
      let baz = { [foo + 'str'] };
    }
    

    4.3 Object.js()

    es6提出同值相等算法,用来解决ES5 == 会自动转化数组类型,=== 存在NaN不等于自身,以及+0不等于-0的问题。

    • 相等运算符(==)的缺点:弱类型转化
    {
        1 == '1'
        // true
    }
    
    • 严格相等运算符(===))的缺点:不能很好的处理NaN、-0、+0的相等比较
    {
        NaN === NaN 
        // false
    
        +0 === -0
        // true
    }
    
    • 同值相等算法 Object.is()解决了以上问题
    {
        Object.is(NaN, NaN);
        // true
    
        Object.is(+0, -0);
        // false
    }
    

    Object.is方法是在 === 的基础上,又特别处理了NaN、-0、+0,保证了NaN和NaN相等,-0和+0不再相同。

    4.4 Object.assign()

    Object.assign() 方法用于将所有可枚举的属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

    // 合并 objects
    {
      let o1 = { a: 1 };
      let o2 = { b: 2 };
      let o3 = { c: 3 };
    
      let obj = Object.assign(o1, o2, o3);
      console.log(obj); // { a: 1, b: 2, c: 3 }
      console.log(o1);  // { a: 1, b: 2, c: 3 }, 注意目标对象自身也会改变。
    }
    

    这里我们需要强调的两点是:

    1. 自身所有可被枚举的属性
    2. 自有属性
    

    拷贝过程中将调用源对象的getter方法,并在target对象上使用setter方法实现目标对象的拷贝。

    // 注意: 只有字符串的包装对象才可能有自身可枚举属性。
    let v1 = "abc";
    let v2 = true;
    let v3 = 10;
    let v4 = [1, 2, 3];
    
    console.log(Object.assign({}, v1)); // {0: "a", 1: "b", 2: "c"}
    console.log(Object.assign({}, v2)); // {}
    console.log(Object.assign({}, v3)); // {}
    console.log(Object.assign({}, v4)); // {0: 1, 1: 2, 2: 3}
    console.log(Object.assign({}, null)); // {}
    console.log(Object.assign({}, undefined)); // {}
    

    Object.assign() 方法只会拷贝源对象自身的并且可枚举的属性到目标对象身上,原始类型会被包装,null 和 undefined 会被忽略。

    在vue项目中Object.assign()的一个应用场景:

    export default {
      data(){
          ...
      },
      methods:{
          ...
          getList(param){
            let _param = this.status == '0' ? {type: 'patient'} : {type: 'patient', state:this.status};
                _param = Object.assign(_param, param);
            this.$store.dispatch('getLists', _param); 
          }
      },
      components:{
          ...
      },
      created(){ // 实例构造完之后的钩子函数
          this.getList();
      }
    }
    

    这里是一个获取列表的公共请求方法getList(),会根据不同的操作请求不同的列表数据,它们的请求有一些公共的参数放在param对象里。根据不同的状态,会有一些不同的参数放在一个_param中,通过 Object.assign(_param, param), 将公共的参数的对象param合并到特有参数的对象_param上。

    4.5 对象的扩展运算符和解构赋值在对象中的应用

    扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。

    {
        // 变量表示解构赋值所在的对象,它获取等号右边所有没有读取的键一起拷过来。
        let {a, ...b } = {x: 3, y: 4, a: 1};
    
        console.log(a); // 1
        console.log(b); // {x: 3, y: 4}
    }
    

    对象的解构赋值在我们主站中一个简单使用:

    const { utils, tracking, weixinshare } = qscModule; 
    
    // 等同于
    
    var utils = qscModule.utils;
    var tracking = qscModule.tracking;
    var weixinshare = qscModule.weixinshare;
    

    很明显对象的解构赋值,可读性、可维护性都更好。推荐大家使用这种写法。

    4.6 Object.keys(), Object.values(), Object.entries()

    引入 方法 遍历 返回值
    es5 Object.keys() 属性名 数组
    es6 Object.values() 属性值 数组
    es6 Object.entries() 键值对 数组

    这三个方法只返回对象自身的可遍历属性。

    {
      let obj = { foo: 'bar', baz: 42 };
      
      console.log(Object.keys(obj)); // ["foo", "baz"]
      console.log(Object.values(obj)); // ["bar", 42]
      console.log(Object.entries(obj)); // [["foo", "bar"],  ["baz", 42]]
    }
    

    小结

    • 对象属性和方法的简洁表示法
    • Object.is() 是否严格相等
    • Object.assign() 对象的合并
    • 对象的解构赋值的应用:const { utils, tracking, weixinshare } = qscModule;
    • Object.keys(), Object.values(), Object.entries() 属性名数组、属性值数组和键值对数组

    相关文章

      网友评论

          本文标题:ES6学习系列之- 对象的扩展

          本文链接:https://www.haomeiwen.com/subject/eiwasxtx.html