美文网首页
Object.create和Object.assign

Object.create和Object.assign

作者: komallqh | 来源:发表于2020-07-21 23:16 被阅读0次

    Object.create和Object.assign的区别:

    • obj1.create(obj2)将obj1的原型指向obj2
    • obj1 = Object.assign(obj2,obj3,obj4)

    Object.create()

    • Object.create(proto[, propertiesObject])
    • 作用
      Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的proto
    • 常见例子
    const person = {
      isHuman: false,
      printIntroduction: function () {
        console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
      }
    };
    
    const me = Object.create(person);
    
    me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
    me.isHuman = true; // inherited properties can be overwritten
    
    me.printIntroduction();
    // expected output: "My name is Matthew. Am I human? true"
    
    • 不常用例子
    o = Object.create(Object.prototype, {
      // foo会成为所创建对象的数据属性
      foo: { 
        writable:true,
        configurable:true,
        value: "hello" 
      },
      // bar会成为所创建对象的访问器属性
      bar: {
        configurable: false,
        get: function() { return 10 },
        set: function(value) {
          console.log("Setting `o.bar` to", value);
        }
      }
    });
    
    // 创建一个以另一个空对象为原型,且拥有一个属性p的对象
    o = Object.create({}, { p: { value: 42 } })
    
    // 省略了的属性特性默认为false,所以属性p是不可写,不可枚举,不可配置的:
    o.p = 24
    o.p
    //42
    
    //创建一个可写的,可枚举的,可配置的属性p
    o2 = Object.create({}, {
      p: {
        value: 42, 
        writable: true,
        enumerable: true,
        configurable: true 
      } 
    });
    

    Object.assign()

    • Object.assign(target, ...sources)
    • 用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
    • 常见特性:
      相同的键,会被覆盖;
      String类型和 Symbol 类型的属性都会被拷贝;
      在出现错误的情况下,例如,如果属性不可写,会引发TypeError,如果在引发错误之前添加了任何属性,则可以更改target对象;
      Object.assign 不会在那些source对象值为 null 或 undefined 的时候抛出错误。
    • 常见例子
    const target = { a: 1, b: 2 };
    const source = { b: 4, c: 5 };
    
    const returnedTarget = Object.assign(target, source);
    
    console.log(target);
    // expected output: Object { a: 1, b: 4, c: 5 }
    
    console.log(returnedTarget);
    // expected output: Object { a: 1, b: 4, c: 5 }
    
    
    const obj = { a: 1 };
    const copy = Object.assign({}, obj);
    console.log(copy); // { a: 1 }
    
    //对象深拷贝
    let obj1 = { a: 0 , b: { c: 0}}; 
    let obj2 = Object.assign({}, obj1); 
    console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}} 
    
    obj1.a = 1; 
    console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}} 
    console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}} 
    
    obj2.a = 2; 
    console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}} 
    console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 0}}
     
    obj2.b.c = 3; 
    console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 3}} 
    console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 3}} 
    
    // Deep Clone 
    obj1 = { a: 0 , b: { c: 0}}; 
    let obj3 = JSON.parse(JSON.stringify(obj1)); 
    obj1.a = 4; 
    obj1.b.c = 4; 
    console.log(JSON.stringify(obj3)); // { a: 0, b: { c: 0}}
    
    //合并对象
    const o1 = { a: 1 };
    const o2 = { b: 2 };
    const o3 = { c: 3 };
    
    const obj = Object.assign(o1, o2, o3);
    console.log(obj); // { a: 1, b: 2, c: 3 }
    console.log(o1);  // { a: 1, b: 2, c: 3 }, 注意目标对象自身也会改变
    
    //合并具有相同属性的对象
    const o1 = { a: 1, b: 1, c: 1 };
    const o2 = { b: 2, c: 2 };
    const o3 = { c: 3 };
    
    const obj = Object.assign({}, o1, o2, o3);
    console.log(obj); // { a: 1, b: 2, c: 3 }
    
    //拷贝 symbol 类型的属性
    const o1 = { a: 1 };
    const o2 = { [Symbol('foo')]: 2 };
    
    const obj = Object.assign({}, o1, o2);
    console.log(obj); // { a : 1, [Symbol("foo")]: 2 } (cf. bug 1207182 on Firefox)
    Object.getOwnPropertySymbols(obj); // [Symbol(foo)]
    
    //继承属性和不可枚举属性是不能拷贝的
    const obj = Object.create({foo: 1}, { // foo 是个继承属性。
        bar: {
            value: 2  // bar 是个不可枚举属性。
        },
        baz: {
            value: 3,
            enumerable: true  // baz 是个自身可枚举属性。
        }
    });
    
    const copy = Object.assign({}, obj);
    console.log(copy); // { baz: 3 }
    
    //原始类型会被包装为对象
    const v1 = "abc";
    const v2 = true;
    const v3 = 10;
    const v4 = Symbol("foo")
    
    const obj = Object.assign({}, v1, null, v2, undefined, v3, v4); 
    // 原始类型会被包装,null 和 undefined 会被忽略。
    // 注意,只有字符串的包装对象才可能有自身可枚举属性。
    console.log(obj); // { "0": "a", "1": "b", "2": "c" }
    
    
    //异常会打断后续拷贝任务
    const target = Object.defineProperty({}, "foo", {
        value: 1,
        writable: false
    }); // target 的 foo 属性是个只读属性。
    
    Object.assign(target, {bar: 2}, {foo2: 3, foo: 3, foo3: 3}, {baz: 4});
    // TypeError: "foo" is read-only
    // 注意这个异常是在拷贝第二个源对象的第二个属性时发生的。
    
    console.log(target.bar);  // 2,说明第一个源对象拷贝成功了。
    console.log(target.foo2); // 3,说明第二个源对象的第一个属性也拷贝成功了。
    console.log(target.foo);  // 1,只读属性不能被覆盖,所以第二个源对象的第二个属性拷贝失败了。
    console.log(target.foo3); // undefined,异常之后 assign 方法就退出了,第三个属性是不会被拷贝到的。
    console.log(target.baz);  // undefined,第三个源对象更是不会被拷贝到的。
    

    Object.defineProperty()

    Object.defineProperty(obj, prop, descriptor)
    参考连接:
    Object.create:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create
    Object.assign:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

    相关文章

      网友评论

          本文标题:Object.create和Object.assign

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