Diamo un'occhiata alle specifiche ECMAScript 5 per Array.prototype.sort :
Let obj be the result of calling ToObject passing the this value as the argument.
E quando esaminiamo ToObject , vediamo una voce familiare nella tabella :
Argument Type Result
============= ======
Undefined Throw a TypeError exception.
...
Object The result is the input argument (no conversion).
Questo suggerisce che l'invocazione di b() di Chrome ha un valore this che non è undefined , ma altri fanno passano un this di undefined , risultando in% % co_de.
Per prima cosa dobbiamo esaminare come viene impostato TypeError quando eseguiamo una chiamata a una funzione (che a EMCAScript si riferisce come CallExpression ):
- If Type(ref) is Reference, then
- If IsPropertyReference(ref) is
true, then
- Let thisValue be GetBase(ref).
- Else, the base of ref is an Environment Record
- Let thisValue be the result of calling the ImplicitThisValue concrete method of GetBase(ref).
- Else, Type(ref) is not Reference.
- Let thisValue be
undefined.
Poiché ImplicitThisValue del record ambiente di una funzione restituisce sempre this , l'unico caso in cui undefined è non this è durante l'accesso alla proprietà, ad esempio undefined . Pertanto, possiamo concludere che l'esecuzione di una invocazione di funzione "nuda" come foo.bar() utilizzerà sempre un valoreValore di b() .
Tuttavia, nella console di Chrome, undefined non è this per undefined . Per capire come questo potrebbe accadere (e come potrebbe differire tra i browser), dobbiamo esaminare il comportamento in modalità rigorosa in Sezione 10.4.3, Immissione del codice funzione :
The following steps are performed when control enters the execution context for function code contained in function object F, a caller provided thisArg, and a caller provided argumentsList:
If the function code is strict code, set the ThisBinding to thisArg.
Else if thisArg is null or undefined, set the ThisBinding to the global object.
dove " ThisBinding " è " Il valore associato al b() parola chiave all'interno del codice ECMAScript associato a questo contesto di esecuzione. "
Quindi, il codice non rigoroso sostituisce un this o null thisArg con l'oggetto globale, undefined . La modalità rigorosa, d'altra parte, non converte window o null nell'oggetto globale quando viene utilizzato per undefined . ( this restituisce l'oggetto sort ordinato, quindi this memorizza semplicemente l'oggetto globale restituito in c = b() .)
Pertanto , possiamo concludere che l'implementazione di Firefox della funzione c viene eseguita in modalità rigorosa, mentre l'implementazione di Chrome non lo fa.
Puoi vedere ulteriori prove di ciò in base a come Array.prototype.sort gestisce valori sort non oggetto. Se esegui this in vari browser, Chrome genererà typeof []["sort"].apply(5) , mentre Firefox emetterà "number" , dimostrando la modalità di autoboxing dell'oggetto che si verifica solo in modalità non rigida. La rigorosa funzione "object" di Firefox non boxa sort e restituisce la primitiva grezza.