2017-02-13 13 views
2

Скажем, у меня есть объект животного с speak функции:В чем разница между Object.assign и Object.setPrototypeOf в JavaScript?

function speak() { 
    console.log(this.sound) 
} 

let animal = { 
    speak 
} 

И у меня есть собака с sound:

let dog = { 
    sound: "Woof!" 
} 

Если я хочу dog наследовать speak от animal я могу использовать Object.assign или Object.setPrototypeOf. Похоже, что они дают одинаковые результаты:

let luke = Object.assign(dog, animal) 

luke.speak() // Woof! 

let bruno = Object.setPrototypeOf(dog, animal) 

bruno.speak() // Woof! 

В чем разница и в каком-то смысле рассматривается как «правильный» способ?

+1

Ну, одна большая разница в том, что вы никогда не должны использовать 'Object.setPrototypeOf'. Если вы хотите наследовать, используйте конструктор. – Ryan

+0

Главное отличие заключается в том, что Object.assign перезапишет свойства первого объекта со свойствами второго, где Object.setPrototypeOf создаст [[Prototype]] от первого объекта ко второму. – nem035

ответ

3

Объект. setPrototypeOf

function(obj, proto) { 
    obj.__proto__ = proto; 
    return obj; 
} 

Object.assign:

function(target, ...varArgs) { // .length of function is 2 
    'use strict'; 
    if (target == null) { // TypeError if undefined or null 
     throw new TypeError('Cannot convert undefined or null to object'); 
    } 

    var to = Object(target); 

    for (var index = 1; index < arguments.length; index++) { 
     var nextSource = arguments[index]; 

     if (nextSource != null) { // Skip over if undefined or null 
     for (var nextKey in nextSource) { 
      // Avoid bugs when hasOwnProperty is shadowed 
      if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { 
      to[nextKey] = nextSource[nextKey]; 
      } 
     } 
     } 
    } 
    return to; 
    }; 

Таким образом, setPrototypeOf просто присвоить __proto__ мишени к источнику Однако ключи, assign петли через аргумент (I) и переопределить его значения с помощью аргумента (i + 1) в соответствии с ключами.