小生愛

        /**
            * 对象的扩展
            
            * 属性名表达式与简洁表示法,不能同时使用,会报错
        */


        // 只写属性名 不写属性值 属性值等于属性名代表的变量
        function f(x, y){
          return {x, y};
        };
        // {x:1, y:2}
        f(1, 2);




        // 对象的方法简写
        let o = {
            method (){
                console.log('简写');
            }
        };
        o.method();




        // 方法 属性简写
        let bir = '2000';

        let Person = {
            name : '张三',

            // 相当于bir : bir
            bir,

            hello (){
                console.log(this.name, this.bir);
            }
        };
        Person.hello();




        function getPoint(){
            var x = 1;
            var y = 10;

            return {x, y};
        };
        // {x:1, y:10}
        getPoint();




        /** 
           属性名表达式
        */
        let pro = 'foo';
        let obj = {
            // 表达式定义属性名
            [pro] : 1,
            ['a' + 'bc'] : 2,
            // 表达式定义方法名
            ['m' + 'et'] (){
                return '表达式表示的方法名';
            }
        };
        console.log(obj.foo, obj.abc, obj.met());



        
        let propKey = 'foo' 
            
        let obj = {
          // propKey 如果是变量不要加 引号
          [propKey]: true,
          ['a' + 'bc']: 123
        }

        // propKey的值是foo 可以通过 obj.foo 获取值
        // 或者通过[propKey变量] 获取值
        // 或者通过 propKey的值foo obj['foo'] 获取值 括号内要加引号
        // propKey 是变量 不能通过 . 方式获取 obj.propKey 获取不到值
        log( obj.foo )
        log( obj['propKey'] )
        log( obj['foo'] )
        log( obj.abc )




        // 属性名表达式不能简写 否则报错
        var foo = 'bar';
        var bar = 'abc';
        let obj = {
          [foo]
        }




        // 属性名表达式如果是一个对象 默认会将对象转为字符串[object Object]
        // [keyA]和[keyB]得到的都是[object Object] 所以[keyB]会把[keyA]覆盖掉
        // 而myObject最后只有一个[object Object]属性
        const keyA = {a: 1}
        const keyB = {b: 2}

        const myObject = {
          [keyA]: 'valueA',
          [keyB]: 'valueB'
        }

        // 输出 {[object Object]: "valueB"}
        // keyA 被覆盖了
        log(myObject)




        let target = {a:1, b:1};
        let source1 = {a:2, c:2};
        let source2 = {c:3};

        // 合并对象 将源对象的所有可枚举属性赋值到目标对象 合并后源对象被改变
        // 第一个参数是目标对象 其余是源对象 相同属性会被后面的属性覆盖
        // 只拷贝源对象的自身属性 (不拷贝继承属性) 也不拷贝不可枚举的属性
        Object.assign(target, source1, source2);




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

        // assign 浅拷贝 修改源对象的值会影响目标对象
        obj1.a.b = 3;
        // 3
        console.log( obj2.a.b );




        // assign处理数组 会把数组当成对象
        // {0:1, 1:2} {0:4, 1:5} 合并时相同属性名会被覆盖
        // 输出[4, 5]
        let arg = Object.assign([1, 2], [4, 5]);




        // 创建一个新对象 目标对象用一个空对象
        let o1 = {a:1};
        let o2 = {b:2};

        let o3 = Object.assign({}, o1, o2);




        // 对象的属性表达式可以是一个函数
        const fn = () => 'abc'

        let obj = {
            [fn()]: '小生爱'
        }

        // 输出 小生爱
        obj[fn()]