2015-02-22 4 views
5

В файле MDN page forObject.assign() пример polyfill сначала обертывает все источники и целевые параметры в Object() перед итерацией по свойствам. (то есть Object(target), Object(source1), Object(source2) ...).В чем цель `Object (target)` в `Object.assign()` polyfill

В тексте также упоминается, что дополнительные свойства добавляются непосредственно к цели перед возвратом цели. Однако обертка цели в Object() приводит к объекту, который отличается от просто увеличивающих свойств. (то есть Object(target).newProp !== target.newProp).

Все приведенные примеры имеют объекты как параметры для Object.assign(). Поэтому прецедент для объектных источников или целевых параметров не ясен.

A) Какова цель упаковки параметров в Object()? (У меня создается впечатление, что Object.keys(x) такой же, как Object.keys(Object(x))).

B) Какие возможные варианты использования Object.assign() с объектами не являются объектами? (Например, что-то вроде: Object.assign(1, 'b', [3], true, function(){}))

+2

'Объект (цель)' предает цель в объект. Например: 'Object (" 1234 ")' отличает это от [object String] {0: "1", 1: "2", 2: "3", 3: "4", length: 4} ' – Mouser

+5

Обычно лучше всего читать спецификацию в сочетании с polyfill, поскольку они часто пытаются воспроизвести поведение. Вы можете видеть из [* ed. 6 draft *] (https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign), что каждый аргумент передается * ToObject *. Поскольку собственный скрипт не может получить доступ к внутренним методам, вызов 'Object (target)' и 'Object (source)' является приближением (хотя и не совсем то же, особенно для * null * и * undefined *). – RobG

+0

@Mouser. Я понимаю, что делает Object(). Я не понимаю, почему вы когда-либо делали бы что-то вроде Object.assign ([], 'a', 3, function() {}) – Hurelu

ответ

2

Давайте разбить его:

тест, если объект существует, если не сделать его:

if (!Object.assign) { 

сделать метод с помощью Object.defineProperty и добавить его к Object

Object.defineProperty(Object, 'assign', { 
    enumerable: false, 
    configurable: true, 
    writable: true, 

Здесь фактическая функция устанавливается. Нужно указать минимальный целевой и один источник.

value: function(target, firstSource) { 
     'use strict'; 

Если цель не определена сгенерирует ошибку.

 if (target === undefined || target === null) { 
     throw new TypeError('Cannot convert first argument to object'); 
     } 

В ролях цель объекта формата. (Например, строка 1234 к [object String]{0: "1", 1: "2", 2: "3", 3: "4", length: 4}.

 var to = Object(target); 

Теперь цикл по всем источникам с помощью объекта аргументов функции. Start с 1, так как 0 является мишенью.

 for (var i = 1; i < arguments.length; i++) { 
     var nextSource = arguments[i]; //store the argument in a variable. 
     if (nextSource === undefined || nextSource === null) { 
      continue; //if the source is undefined continue. 
     } 

Затем нам нужны все (не только разоблаченные) перечислимые свойства исходного объекта, используйте Object.keys в сочетании с Object(source).

 var keysArray = Object.keys(Object(nextSource)); 

Итерация по клавишам:

 for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) { 
      var nextKey = keysArray[nextIndex]; //select the key from the index. 

getOwnPropertyDescriptor дает нам информацию о недвижимости в виде объекта.

  var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey); 

Если свойство не определено и перечисляемость затем установить это свойство как свойство to.

  if (desc !== undefined && desc.enumerable) { 
      to[nextKey] = nextSource[nextKey]; 
      } 
     } 
     } 
     return to; 
    } 
    }); 
} 

Наконец вернуться to с вновь добавленными (клонированных) свойствами.

+0

Приятно, но причина, по которой 'var to = Object (target);' выполняется, не так, чтобы «код мог перечислить свойства», а скорее, если цель не была объектом (например, «1») 't присваивать ему свойства. Не существует цикла для свойств цели для поддержки этой заявки. –

+0

Правда, это никогда не перечисляет их. Он только преобразуется в объект. – Mouser

+0

Извините, я до сих пор не понимаю. Бит в полиполке, который я не понимаю (отсюда и вопрос), является шагом «Передача цели в формат объекта». Я получаю тот же результат с 'Object.keys ('abcd')', как в 'Object.keys (Object ('abcd')), поэтому я предполагаю, что обертка предназначена для других целей, о которых я еще не могу вспомнить , – Hurelu