2016-03-25 4 views
1

Das utopische Ziel:Getter auf die Instanz einer JavaScript-Funktion selbst, um Docstrings zu aktivieren. Ist es möglich?

str = "hello" 
str.doc = "this is a string" 
console.log(str) //prints 'hello' 
console.log(str.doc) //should prints the docstring 

jedoch Strings sind unveränderlich und diese oben ist nicht möglich.

Wie ich zu umgehen versucht:

str = new String("hello") 
str.doc = "this is a string" 
console.log(str) //prints the string object but not 'hello' 
console.log(""+str) //prints "hello" 
console.log(str.doc) //correctly prints the docstring 

Wie Sie nur, wenn .valueOf() oder .toString() sehen kann, genannt Sie den rohen String bekommen. Das Ziel ist, die Zeichenfolge zu erhalten, wenn sie direkt aufgerufen wird.

Eine weitere verleiten der Problemumgehung (in Coffeescript, für Kürze: 3 Linien vs ~ 15)

class Configuration 
    constructor: (@value, @doc) -> 
    @::valueOf = -> @value 

Dies zu new String() ziemlich ähnlich ist. Es prototypiert nur die valueOf()-Methode für das Objekt. Das Problem ist das gleiche wie oben. Sie können nicht direkt console.log(str) den rohen String druckt und beide verwenden console.log(str.doc)

Die Frage:

Ist es in irgendeiner Weise möglich, dies zu erreichen, ohne meine ganze Code-Basis haben Refactoring?

+0

Dies ist eine sehr interessante Frage. Was ist der Anwendungsfall? – woozyking

+0

Für die Konfiguration meiner eckigen App. Ich speichere die öffentlichen Umgebungsvariablen (wie die Rest-Backend-URL) in einer env-spezifischen Datei und definiere sie in einem Singleton, die ich später überall verwenden kann. –

+0

Kannst du ein Beispiel teilen, wie du diese Strings verwendest? Da für alle praktischen Zwecke 'new String()' Ihr Problem lösen sollte. – gurvinder372

Antwort

0

Wie in den Kommentaren erwähnt, werde ich für ein wenig Refactoring gehen die Variablen wie str mit str + "" ersetzen und so mit new String(), nicht wirklich sauber, aber scheint die einzige schnelle Abhilfe zu sein. In der Tat wäre die optimale Lösung einfach einen Singleton zu verwenden, wie folgt aus:

config = { 
    mySetting: { 
     value: "settingValue", 
     docstring: "my doc string" 
    } 
} 

Und bei Bedarf Gebrauch mit: config.mySetting.value aber das würde eine Menge Refactoring einer komplexen App zu tun, nicht ein Priorität für jetzt. Vielen Dank für Ihre Antworten!

0

ich duldet das nicht, aber man konnte console.log außer Kraft setzen, so dass es valueOf auf jedem String Argumente ruft:

var oldConsoleLog = console.log; 
console.log = function () { 
    oldConsoleLog.apply(console, [].map.call(arguments, function (arg) { return arg instanceof String ? arg.valueOf() : arg; })); 
}; 
2

Sie können String Prototyp. Siehe fiddle

// String.prototype.__defineGetter__("doc", function() { return "test" }); //deprecated 

Object.defineProperty(String.prototype, "doc", { 
    get: function doc() { 
    return "this is a string"; 
    } 
}); 
console.log("this is a string".doc); 
+0

die nicht veraltete Methode wird in ES5-Browsern unterstützt – sniels

+0

Ihre Lösung funktioniert tatsächlich: D aber Prototyping alle Strings sind nicht gerade sauber und generell vermeide ich es, native Objekte zu "verschmutzen" –

Verwandte Themen