2013-12-19 12 views
5

Dies ist mehr darüber nachgedacht, wie Javascript funktioniert, als ein echtes Problem zu beheben. Im Falle einer Aussage wieAutomatische javascript type coercion

var str = 9 + " some words here"; 

Die resultierende str var würde den Wert "9 einige Wörter hier" enthalten. Meine Frage ist, welche Funktion Javascript verwendet, um das Number-Objekt '9' automatisch in eine Zeichenkette einzubinden, die mit dem String-Objekt 'einige Wörter hier' verkettet werden soll, und diese Funktion änderbar/ausschaltbar ist.

Dies begann von mir, die Ausgabe von einzelnen Ziffern mit einer vorhergehenden 0 auf einer Seite. Das war einfach genug, um mit einer schnellen Prototypfunktion auf der Anzahl Objekt

Number.prototype.SpecialFormat = function() { 
    if(this < 10) { 
    return "0" + this; 
    } 
    else { 
    return this.toString(); 
    } 
}; 

zu erreichen und es mit einem einfachen (9).SpecialFormat() + " words here";

nennt Aber das hat mich gefragt, ob ich die toString-Funktion auf einer Zahl mit einem überschreiben könnte

Number.prototype.toString = function() { 
    if(this < 10) { 
    return "0" + this; 
    } 
    else { 
    return this; 
    } 
}; 

und nur javascripts automatische Konvertierung es für mich behandeln lassen, so konnte ich einen Standard 9 + " words here"; zu bekommen das gleiche Ergebnis „09 Worte hier“ verwenden. Dies funktionierte nicht nur implizit, ich musste am Ende die .toString zu der 9 (9).toString() + " words here" hinzufügen (was bei näherer Betrachtung zu einigen Endlosschleifen geführt hätte).

Gibt es eine Möglichkeit, die eingebaute Funktionalität eines systemeigenen Javascript-Typs zu überschreiben?

* Anmerkung: Ich weiß, das ist wahrscheinlich eine 'schlechteste Idee jemals'

+3

See [der Additionsoperator] (http://www.ecma-international.org/ecma-262/5.1/#sec-11.6 .1) (Schritt 7), sowie [ToString] (http://www.ecma-international.org/ecma-262/5.1/#sec-9.8) und "[ToString angewendet auf den Zahlentyp] (http : //www.ecma-international.org/ecma-262/5.1/#sec-9.8.1) ". Es scheint, dass die abstrakte Operation "ToString (number)" niemals "Number.prototype.toString" verwendet (es ist in der Tat umgekehrt). – apsillers

+0

Ich vermute, das ist der Grund, warum ich die "Maximale Call-Stack-Größe überschritten" Fehler, wenn ich String (this) im toString-Prototyp verwendet. –

+0

Ich gehe davon aus, dass JavaScript in diesem Fall anders aufgebaut ist als andere objektorientierte Sprachen, in denen Sie Operatoren überschreiben können, die auf Objekte angewendet werden. Es scheint mir, dass String-Verkettung intern vom Interpreter ausgeführt wird, wobei alle überschriebenen Methoden ignoriert werden. – VisioN

Antwort

3

Die addition operator nötigt seine Argumente in Strings in Schritt 7:

  • Wenn Type (lprim) ist String oder Typ (Rprim) ist String, dann
  • Geben Sie die Zeichenfolge, die das Ergebnis der Verkettung ToString (Lprim), gefolgt von ToString (Rprim)

Die ToString operation hat spezielle Regeln für Zahlen, ausführlich unter "ToString Applied to the Number Type".

Es scheint, dass die abstrakte Operation ToString(number) niemals Number.prototype.toString verwendet. In der Tat ist ti umgekehrt: Die default Number.prototype.toString function verwendet den abstrakten numerischen ToString-Algorithmus. Daher ist es nicht möglich, das Standardverhalten für die Stringifizierung von Zahlen während der Typumwandlung in ECMAScript 5 zu überschreiben, da es keine Möglichkeit gibt, die sprachdefinierte ToString-Operation zu ändern.

ToString hat die toString Methode Ziel verwenden, wenn Objekte in Strings Nötigung, aber nicht primitiv Werte zählen.

3

(nicht unbedingt eine Antwort, aber ich brauche etwas Platz)

mit Art Zwang sehr vorsichtig sein, besonders wenn Urtyp mit bezwecken Pendants Kombination, weil:

var n = 9; 
typeof n; // "number" 
n instanceof Number; // false!! 

n = new Number(9); 
n instanceof Number; // true, oh thank God 
typeof n; // "object" what!! 

Auch toString auf Number funktioniert nicht:

Number.prototype.toString = function() { return "foo" + this; }; 
var n = new Number(9); 
"" + n; // "9", not "foo9" 

Ein Weg, um dieses Chaos zu vermeiden ist, indem:

var ns = { 
    number: { 
     specialFormat: function() /* .. */ } 
    } 
} 

ns.number.specialFormat(9); // "09" 
+0

'n = Nummer (9);' im ersten Codeblock sollte 'n = neue Nummer (9);' sein. Andernfalls rufen Sie einfach die Number-Funktion auf, um den Parameter in ein primitives Zahlenelement umzuwandeln, was es bereits ist. Daher werden die zwei Zeilen, die ihm folgen, die gleichen sein wie die zwei Zeilen davor. – Sam

Verwandte Themen