2015-02-22 21 views
5

Nello MDN page forObject.assign() l'esempio polyfill esegue il wrapping di tutte le origini e dei parametri di destinazione in Object() prima di iterare sulle proprietà. (ad esempio Object(target), Object(source1), Object(source2) ...).Qual è lo scopo di `Object (target)` nel polyfill `Object.assign()`

Il testo indica anche che le proprietà aggiuntive vengono aggiunte direttamente al target prima di restituire il target. Tuttavia, il wrapping del target in Object() ha come risultato un oggetto diverso dalle semplici proprietà di conversione. (ad esempio Object(target).newProp !== target.newProp).

Tutti gli esempi forniti hanno oggetti come parametri su Object.assign(). Il caso d'uso per i parametri di origine o di destinazione non oggetto non è quindi chiaro.

A) Qual è lo scopo del wrapping dei parametri in Object()? (Ho l'impressione che lo Object.keys(x) sia lo stesso di Object.keys(Object(x))).

B) Quali sono i possibili casi di utilizzo per l'utilizzo di Object.assign() con non oggetti, c'è? (Per esempio qualcosa come: Object.assign(1, 'b', [3], true, function(){}))

+2

'Oggetto (destinazione)' lancia la mira in un oggetto. Ad esempio: 'Object (" 1234 ")' lo trasmette a '[object String] {0:" 1 ", 1:" 2 ", 2:" 3 ", 3:" 4 ", lunghezza: 4}' – Mouser

+5

Di solito è meglio leggere le specifiche insieme al polyfill, poiché spesso cercano di replicare il comportamento. Puoi vedere dal [* ed. 6 bozza *] (https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign), che ogni argomento è passato a * ToObject *. Poiché lo script nativo non può accedere ai metodi interni, chiamare 'Object (target)' e 'Object (source)' è un'approssimazione (sebbene non esattamente la stessa, specialmente per * null * e * undefined *). – RobG

+0

@Mouser. Capisco cosa fa Object(). Quello che non capisco è perché mai fare qualcosa come Object.assign ([], 'a', 3, function() {}) – Hurelu

risposta

2

Diamo scomposizione:

Verifica se l'oggetto esiste, se non ce la fa:

if (!Object.assign) { 

rendere il metodo tramite Object.defineProperty e aggiungilo a Object

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

Qui viene impostata la funzione effettiva. Uno ha bisogno di fornire un obiettivo e un minimo di fonte.

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

Se il bersaglio non è definita genera un errore.

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

Cast l'obiettivo di oggetto formato. (Es String 1234 a [object String]{0: "1", 1: "2", 2: "3", 3: "4", length: 4}.

 var to = Object(target); 

Ora ciclo attraverso tutte le fonti utilizzando l'oggetto argomenti della funzione. Inizia con 1, poiché 0 è la porta.

 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. 
     } 

Quindi abbiamo bisogno di tutte (non solo quelle esposte) le proprietà enumerabili dall'oggetto sorgente, utilizzare Object.keys in combinazione con Object(source).

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

scandire le chiavi:

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

getOwnPropertyDescriptor ci dà informazioni sulla proprietà sotto forma di un oggetto.

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

Se la proprietà non è definito ed è enumerabile quindi impostare questa proprietà come una proprietà da to.

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

ritorno Infine to con i (clonati) Proprietà appena aggiunti.

+0

Bello, ma il motivo per cui 'var to = Object (target);' non è fatto in modo che "il codice possa enumerare sulle proprietà", ma se il target non fosse un oggetto (ad esempio '1') non si potrebbe Assegnare le proprietà ad esso. Non esiste un ciclo sulle proprietà del target per supportare tale affermazione. –

+0

È vero, non li enumera mai. Converte solo in un oggetto. – Mouser

+0

Mi spiace ancora non capisco. Il bit nel polyfill che non capisco (da qui la domanda) è il passo "Cast the target to Object format". Ottengo lo stesso risultato con 'Object.keys ('abcd')' come in 'Object.keys (Object ('abcd'))' quindi suppongo che il wrapping sia per altri usi a cui non riesco ancora a pensare . – Hurelu