zoukankan      html  css  js  c++  java
  • es6之对象扩展

    1.属性的简洁表示

    ES6允许直接写入变量和函数,作为对象的属性和方法。书写更加简洁。

    属性简写:

    ES6允许在对象之中,直接写变量。这时,属性名为变量名,属性值为变量的值。

    const foo = 'bar';
    const baz = {foo};  //等同于  const baz = {foo:foo}
    baz//{foo:'bar'}
    function f(x,y){
        return {x,y}
    }
    //等同于
    function f(x,y){
        return {x:x,y:y};
    }
    f(1,2)//{x:1,y:2}

    方法简写:

    const o ={
        method(){
            return 'Hello!'
        }
    }
    //等同于
    const o = {
        method:function(){
            return 'Hello!';
        }
    }
    let birth = '2000/01/01';
    const Person ={
        name:'法外狂徒张三',
        birth,   //等同于birth:birth
        hello(){  //等同于hello :function()....
            console.log('我的名字是',this.name) 
        }
    }

    2.属性名表达式

    es5定义对象的属性,有两种方法。

    //方法一
    obj.foo = true;
    //方法二
    obj['a'+'bc'] = 123;

    上面代码的方法一是直接用标识符作为属性名,方法二是用表达式作为属性名,这时将表达式放在方括号之内。
    但是,如果使用字面量定义对象(使用大括号),在ES5中只能使用方法一(标识符)定义属性。

    var obj ={
        foo:true,
        abc:123
    }

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

    let propKey = 'foo';
    let obj ={
        [propKey]:true,
        ['a'+'bc']:123
    }
    obj//{foo: true, abc: 123}

    表达式还可以用于定义方法名。

    let obj = {
        ['h'+'ello'](){
            return 'hi'
        }
    }
    obj.hello()//hi;
    1.属性名表达式与简洁表示法,不能同时使用,会报错。
    2.属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[object object]。
    const keyA = {a:1};
    const keyB = {b:2};
    const myObject = {
        [keyA]:'valueA',
        [keyB]:'valueB'
    };
    myObject;// {[object Object]: "valueB"}

    上面代码中,[keyA]和[keyB]得到的都是[object object],所以[keyB]会把[keyA]覆盖掉,所以myObject最后只有一个[object object]属性。

    3. 方法的name属性

    函数的name属性,返回函数名。对象方法也是函数,因此也有name属性。

    const person = {
      sayName() {
        console.log('hello!');
      },
    };
    
    person.sayName.name   // "sayName"

    4.super关键字

    this关键字作为对象方法时,指向函数所在的当前对象,ES6又新增了另一个类似的关键字super,指向当前对象的原型对象。

    const objproto = {
        foo:'hello'
    };
    const obj = {
        foo:'world',
        find(){
            return super.foo;
        }
    };
    Object.setPrototypeOf(obj,objproto); //将objproto设置为obj的原型
    obj.find();//hello

    注意:super关键字表示原型对象时,只能用在对象的方法之中,用在其他地方都会报错。

    5.对象的扩展运算符

    解构赋值
    对象的解构赋值用于从一个对象取值,相当于将目标对象自身的所有可遍历、但尚未被读取的属性,分配到指定的对象上面。所有的键和它们的值,都会拷贝到新对象上面。

    let{a,y,...z} = {x:1,y:2,a:3,b;4};
    a//3,
    y//2,
    z//{x:1,b:4}

    变量z是解构赋值所在的对象。它获取等号右边的所有尚未读取的键(x和b),将它们连同值一起拷贝过来。

    6.对象的新增方法

    1.Object.is()
    ES5比较两个值是否相等,只有两个运算符:相等运算符和严格相等运算符。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0。JavaScript缺乏一种运算,在所有环境中,只要两个值是一样的,它们就应该相等。
    ES6提出同值相等算法,用来解决这个问题。Object.is就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符的行为基本一致。(===)。

    Object.is('foo','foo'); //true
    Object.is({},{})  //false

    不同之处只有两个:一是+0不等于-0,二是NaN等于自身。

    +0 === -0 //true
    NaN === NaN // false
    
    Object.is(+0, -0) // false
    Object.is(NaN, NaN) // true

    2.Object.assign()
    Object.assign方法用于对象的合并,将源对象的所有可枚举属性,复制到目标对象。

    const target = {a:1};
    const source1 = {b:2};
    const source2 = {c:3};
    Object.assign(target,source1,source2);
    target//{a:1,b:2,c:3}

    Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。
    注意:如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
    如果只有一个参数,Object.assign会直接返回该参数。

    const obj = {a:1};
    Obejct.assign(obj) === obj//true

    如果该参数不是对象,则会先转成对象,然后返回

    let a=Object.assign(2);
    a// Number {2}

    由于undefined和null无法转成对象,所以如果它们作为第一个参数,就会报错

    如果非对象参数出现在源对象的位置(即非首参数),那么处理规则有所不同。首先,这些参数都会转成对象,如果无法转成对象,就会跳过。这意味着,如果undefined和null不在首参数,就不会报错。

    Object.assign(undefined) // 报错
    Object.assign(null) // 报错
    let obj = {a: 1};
    Object.assign(obj, undefined) === obj // true
    Object.assign(obj, null) === obj // true

    其它类型的值(即数值、字符串和布尔值)不在首参数,也不会报错。但是,除了字符串会以数组形式,拷贝入目标对象,其它值都不会产生效果。

    const v1 = 'abc';
    const v2 = true;
    const v3 = 10;
    
    const obj = Object.assign({}, v1, v2, v3);
    console.log(obj); // { "0": "a", "1": "b", "2": "c" }

    Object.assign拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable:false)。

    let a= Object.defineProperty({}, 'invisible', {
        enumerable: false,
        value: 'hello'
      });
    
    let b=Object.assign({b: 'c'},a)
    b//{b: "c"}

    Object.assign要拷贝的对象a只有一个不可枚举属性invisible,这个属性并没有被拷贝进去。


    属性名为Symbol值的属性,也会被Object.assign拷贝。

    let c=Object.assign({ a: 'b' }, { [Symbol('c')]: 'd' })
    c// {a: "b", Symbol(c): "d"}

    1)浅拷贝
    Object.assign方法实行的是浅拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。

    const obj1 = {a: {b: 1}};
    const obj2 = Object.assign({}, obj1);
    
    obj1.a.b = 2;
    obj2.a.b // 2

    (2)同名属性的替换
    一旦遇到同名属性,Obejct.assign的处理方法是替换,而不是添加。

    const target = { a: 'b' }
    const source = { a: 'd'}
    let c=Object.assign(target, source)
    c  //{a: "d"}

    (3)数组的处理
    Object.assign可以用来处理数组,但是会把数组是为对象。

    let d=Object.assign([1,2,3],[4,5]);
    d//[4,5,3]

    上面代码中,Oject.assign把数组视为属性名为0,1,2的对象,因此源数组的0号属性4覆盖了目标数组的0号属性1.

    (4)取值函数的处理
    Obejct.assign只能进行值的复制,如果要复制的值是一个取值函数,那么将求值后再复制。

    const source = {
      get foo() { return 1 }
    };
    const target = {};
    
    let e=Object.assign(target, source)
    e// { foo: 1 }

    source对象的foo属性是一个取值函数,Object.assign不会复制这个取值函数,只会拿到值以后,将这个值复制过去。

     3.

    Object.keys()、Object.values()、Object.entries()

    let person = {name:"张三",age:25,address:"深圳",getName:function(){}};
    let a=Object.keys(person);
    console.log(a); //["name", "age", "address", "getName"]
    let obj = {
        foo : "bar",
        baz : 20
    };
    console.log(Object.values(obj));  // ["bar", 20]
    const obj = {100 : "a", 2 : "b", 7 : "c"};
    console.log(Object.values(obj));   //["b", "c", "a"]
    var obj = { foo: 'bar', baz: 42 };
    console.log(Object.entries(obj));  //["foo", "bar"]   ["baz", 42]

    Object.keys()、Object.values、Object.entries只输出属性名非 Symbol 值的属性。

    const object1 = {
      a: 'somestring',
      b: 42
    };
    
    for (const [key, value] of Object.entries(object1)) {
      console.log(`${key}: ${value}`);
    }
    
    // expected output:
    // "a: somestring"
    // "b: 42"
    // order is not guaranteed
  • 相关阅读:
    rest framework 认证 权限 频率
    rest framework 视图,路由
    rest framework 序列化
    10.3 Vue 路由系统
    10.4 Vue 父子传值
    10.2 Vue 环境安装
    10.1 ES6 的新增特性以及简单语法
    Django 跨域请求处理
    20190827 On Java8 第十四章 流式编程
    20190825 On Java8 第十三章 函数式编程
  • 原文地址:https://www.cnblogs.com/sunmarvell/p/14375081.html
Copyright © 2011-2022 走看看