2017-03-11 2 views
2
var x = undefined;String(x); // "undefined" 
var y = [x];String(y); // "" 

Warum über einen anderen Wert ausgeben?
Es verwirrt mich.JS String-Konstruktor-Prinzip


Warum String(undefined) kehrt undefined aber String([undefined]) kehrt ''?
Was macht die Ergebnisse aus?
Danke!

Antwort

0

Javascript ist ein bisschen lustig beim Casting.

Auf der ersten, werfen Sie einen undefinierten Wert. Alles was es tut, ist buchstäblich diesen Text zu schreiben.

Auf der zweiten, werfen Sie ein Array mit Werten. Daher ist der Prozess anders. Versuchen: var z = [x, x]; String(z); // returns ","

Gleiche passiert, wenn Sie tun: var x = null; String(x); var y = [x]; String(y);

Was Ihre Annahme ist, dass String ([undefined]) tun wird jeder Wert als String() gegossen, dann sie verketten. Zeichenfolgen sind jedoch grundsätzlich Zeichenfolgen. Wenn Sie ein Array mit nichts (d. H. Undefined, null) haben, wird nur eine leere Zeichenfolge erstellt.

Es gibt andere Beispiele von funny "Inkonsistenzen" wie folgt aus:

[] + {} // returns [object Object] 
{} + [] // returns 0 
+0

sry, ich Ihre Antwort gelesen haben, ist es vert clear.But, so scheint es, dass Sie immer noch, warum Unterschied nicht sagen, oder ich falsch verstanden? – radical

+1

Um Fabian's Antwort hinzuzufügen, sind Strings im Grunde Arrays von Zeichen. Wenn Sie ein Array mit nichts (d. H. "Undefined", "null") haben, wird nur eine leere Zeichenfolge erstellt. –

+1

@MatheusAvellar thx, ich habe es. – radical

0

Man konnte immer nur ECMA-262 lesen.

Wenn String als eine Funktion mit einem Wert aufgerufen wird, wird (mehr oder weniger) ToString(value) zurückgegeben.

Der Aufruf ToString(undefined) gibt den String "undefined" zurück, was das erste Ergebnis erklärt.

Ähnlich für den zweiten Fall, außer dass seit Arrays Objekte sind, ruft ToString(arrayInstance) erste Aufrufe ToPrimitive. Das ruft die toString method des Arrays auf, die effektiv array.join(',') ist.

Da nur das Array ein Mitglied, und sein Wert ist undefinierten, verbinden einen leeren String zurück. Versuchen Sie es:

console.log('"' + [undefined].toString() + '"');

3

Wenn Sie String([]) aufrufen, wird die Methode Array.prototype.toString schließlich genannt, und nach dem spec of Array.prototype.toString, sind die Schritte:

  1. Lassen Array das Ergebnis der Aufrufen von ToObject auf diesem Wert.
  2. Lassen Sie Func das Ergebnis des Aufrufs der internen Methode [[Get]] von Array mit Argument "Join" sein.
  3. Wenn IsCallable (func) false ist, dann sei func die integrierte Standardmethode Object.prototype.toString (15.2.4.2).
  4. Geben Sie das Ergebnis des Aufrufs der internen [[Call]] - Methode von func zurück, die Array als diesen Wert und eine leere Argumentliste bereitstellt.

Sie können herausfinden, dass es dann tatsächlich ruft Array.prototype.join und gibt sein Ergebnis zurück. Die spec of Array.prototype.join ist ein wenig länger, aber die step 8 ist die Ursache verwirrend Sie:

  1. Wenn element0 undefined oder null ist, sei R die leere Zeichenfolge sein; Andernfalls sei R ToString (element0).

Was bedeutet, wenn Array.prototype.join Iterierten alle Elemente, wann immer es trifft undefined oder null, sie es durch leere String ersetzen werden, und die Standardtrennzeichen von join ist ,. Deshalb String([undefined]) Sie "" gibt, weil es in dem Array nur ein Element und es ist undefined, wenn Sie String([undefined, null]) versuchen, werden Sie "," (zwei leere Zeichenkette joined von ,) erhalten, und String([null, undefined, 1]) geben Ihnen ",,1"

Etwas Schnipsel Array.prototype.toString zu beweisen, ruft Array.prototype.join:

console.log(String([undefined])) 
 
console.log(String([1,2,3])) 
 
console.log("----------Override Array.prototype.join--------") 
 
Array.prototype.join = function() { 
 
    return "I don't care what is in the original array"; 
 
} 
 

 
console.log(String([undefined])) 
 
console.log(String([1,2,3]))

BTW, es gibt eine awesome blog über die Konvertierung von Wert in String in Javascript, hoffe, es hilft.

Grüße :-)

+0

Gut zu sehen, Referenzen auf ECMA-262, aber ed 5.1 wurde durch ECMAScript 2015 und 2016 und ist es bis 2017 wieder vorbei. ;-) – RobG