在JavaScript中不使用Object.assign(ES6功能)而从另一个对象扩展

时间:2015-10-11 22:26:02

标签: javascript object

更新1:我之前没有提及,但我试图避免使用 new 关键字。 Polyfill应该也可以正常工作。我应该清楚我正在寻找是否有另一种编写类似代码的方法。

Chris Elliott撰写的文章'Common Misconceptions about Inheritance in JS'说明了使用闭包数据隐私的好方法,但使用ES6方法 Object.assign

他将其描述为:

  

Object.assign()是由Rick Waldron倡导的新ES6功能,之前已在几十个库中实现。您可能从jQuery知道它为$.extend()或从Underscore知道它为_.extend()。 Lodash有一个名为assign()的版本。传入目标对象和任意数量的源对象,用逗号分隔。

     

它将通过赋值复制所有可枚举的自有属性   源对象到具有last优先级的目标对象。   如果有任何属性名称冲突,则从最后一个版本开始   对象传递胜利。

如何使用ES6功能 Object.assign 编写此示例不带

let animal = {
  animalType: 'animal',

  describe () {
    return `An ${this.animalType} with ${this.furColor} fur, 
      ${this.legs} legs, and a ${this.tail} tail.`;
  }
};

let mouseFactory = function mouseFactory () {
  let secret = 'secret agent';

  return Object.assign(Object.create(animal), {
    animalType: 'mouse',
    furColor: 'brown',
    legs: 4,
    tail: 'long, skinny',
    profession () {
      return secret;
    }
  });
};

let james = mouseFactory();

2 个答案:

答案 0 :(得分:2)

编写自己的object.assign版本!

function assign(target, sources) {
    // for each object in source, iterate through properties
    // check has own property and add the property to the target 
    // object

    // or just modify in place, too many different ways to do this
    let newTarget = new target();


    for (let i = 0; i < sources.length; i++) {
      for (let key in sources[i]) {
        if (sources[i].hasOwnProperty(key)) {
          newTarget[key] = sources[i][key];
        }
      }
    }
    return newTarget;
}

编辑:你绝对不必使用新的 - 你也可以将它们添加到空对象中。

function assign(sources) {
    // for each object in source, iterate through properties
    // check has own property and add the property to the target 
    // object

    // this is not the important part
    let newTarget = {};


    for (let i = 0; i < sources.length; i++) {
      for (let key in sources[i]) {
        if (sources[i].hasOwnProperty(key)) {
          newTarget[key] = sources[i][key];
        }
      }
    }
    return newTarget;
}

答案 1 :(得分:1)

您实际上可以使用Object.create,这是ES5,如下所述:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

我已经用这种格式重写了你的代码,你去了:

var animal = {
  animalType: 'animal',

  describe: function() {
    return 'An ' + this.animalType + ' with ' + this.furColor + ' fur, ' 
      + this.legs + ' legs, and a ' + this.tail + ' tail.';
  }
};

var mouseFactory = function mouseFactory () {
  var secret = 'secret agent';

  return Object.create(animal, {
    animalType: {
        value: 'mouse',
        writable: true
    },
    furColor: {
        value: 'brown',
        writable: true
    },
    legs: {
        value: 4,
        writable: true        
    },
    tail: {
        value: 'long, skinny',
        writable: true        
    },
    profession: {
        value: function () {
          return secret;
        }
    }
  });
};

var james = mouseFactory();

var dave = mouseFactory();
dave.furColor = 'white';

console.log(james.describe());
// An mouse with brown fur, 4 legs, and a long, skinny tail.

console.log(dave.describe());
// An mouse with white fur, 4 legs, and a long, skinny tail.