単一の変数を変更し、それを参照する他のオブジェクトに伝播できるように、文字列を作成して参照渡しします。
次の例をご覧ください。
function Report(a, b) {
this.ShowMe = function() { alert(a + " of " + b); }
}
var metric = new String("count");
var a = new Report(metric, "a");
var b = new Report(metric, "b");
var c = new Report(metric, "c");
a.ShowMe(); // outputs: "count of a";
b.ShowMe(); // outputs: "count of b";
c.ShowMe(); // outputs: "count of c";
私はこれを実現させたいです:
var metric = new String("count");
var a = new Report(metric, "a");
var b = new Report(metric, "b");
var c = new Report(metric, "c");
a.ShowMe(); // outputs: "count of a";
metric = new String("avg");
b.ShowMe(); // outputs: "avg of b";
c.ShowMe(); // outputs: "avg of c";
なぜこれが機能しないのですか?
文字列のMDC参照 は、メトリックがオブジェクトであることを示します。
私はこれを試しましたが、これは私が望むものではありませんが、非常に近いです:
var metric = {toString:function(){ return "count";}};
var a = new Report(metric, "a");
var b = new Report(metric, "b");
var c = new Report(metric, "c");
a.ShowMe(); // outputs: "count of a";
metric.toString = function(){ return "avg";}; // notice I had to change the function
b.ShowMe(); // outputs: "avg of b";
c.ShowMe(); // outputs: "avg of c";
alert(String(metric).charAt(1)); // notice I had to use the String constructor
// I want to be able to call this:
// metric.charAt(1)
ここで重要な点:
Javascriptの文字列はすでに「参照によって」渡されます。文字列を使用してプロシージャを呼び出す場合、文字列の内容をコピーする必要はありません。手元には2つの問題があります。
metric
は2つの完全に独立した文字列変数に適用されるラベルです。クロージャを使用してmetric
の動的スコープを実装する、目的を達成する1つの方法を次に示します。
function Report(a, b) {
this.ShowMe = function() { alert(a() + " of " + b); }
}
var metric = "count";
var metric_fnc = function() { return metric; }
var a = new Report(metric_fnc, "a");
var b = new Report(metric_fnc, "b");
a.ShowMe(); // outputs: "count of a";
metric = "avg";
b.ShowMe(); // outputs: "avg of b";
オブジェクトで文字列をラップし、文字列が格納されているフィールドを変更できます。これは、関数を変更する必要なく、最後の例で行っていることに似ています。
var metric = { str : "count" }
metric.str = "avg";
Metric.strに「avg」が含まれるようになりました
閉鎖?
var metric = new function() {
var _value = "count";
this.setValue = function(s) { _value = s; };
this.toString = function() { return _value; };
};
// snip ...
a.ShowMe();
metric.setValue("avg");
b.ShowMe();
c.ShowMe();
または、より一般的でパフォーマンスの高いものにします。
function RefString(s) {
this.value = s;
}
RefString.prototype.toString = function() { return this.value; }
RefString.prototype.charAt = String.prototype.charAt;
var metric = new RefString("count");
// snip ...
a.ShowMe();
metric.value = "avg";
b.ShowMe();
c.ShowMe();
目的の文字列変数を閉じない場合、@ John Millikinの答えのようにShowMe関数を変更するか、コードベースを再設計する以外の方法はないと思います。
オブジェクトはJavascriptで参照渡しされるため、変数をオブジェクトとして渡すと機能します。
http://sirdarckcat.blogspot.com/2007/07/passing-reference-to-javascript.html
function modifyVar(obj,newVal){
obj.value=newVal;
}
var m={value: 1};
alert(x);
modifyVar("x",321);
alert(x);
Jsfiddle: https://jsfiddle.net/ncwhmty7/1/
文字列プリミティブ(文字列リテラル)と文字列オブジェクトの両方は不変です。これは、関数内での文字列変数の内容の変更は、関数外で発生するものとは完全に分離されることを意味します。これを克服するためのオプションがいくつかあります。
1。変更された関数値を関数から返す
function concatenateString(stringA, stringB) {
return stringA + stringB;
}
alert(concatenateString("Hi", " there"));
2。文字列変数を真のオブジェクトに変換するには
function modifyVar(stringA, stringB) {
var result = stringA + stringB;
stringA.valueOf = stringA.toSource = stringA.toString = function() {
return result;
};
}
var stringA = Object('HI');
modifyVar(stringA, ' there');
alert(stringA);
その文字列がオブジェクトのプロパティである場合、オブジェクトのプロパティとstringKeyを送信できます。
this.modificationFunction = function(object, stringKey){
object[stringKey] = object[stringKey] + "bla bla bla";
}
myObject.myStringProperty = "She said: ";
this.modificationFunction(myObject, "myStringProperty");
// myObject.myStringProperty is now "She said: bla bla bla";
JavaScriptでは、文字列は不変です。 Report
インスタンスがハンドルを持っている文字列自体を変更することはできません。
あなたのソリューションは動作しますが、これはもっと簡単かもしれません:
function Report(a, b) {
this.showMe = function() { alert(a.str + " of " + b); }
}
var metric = {};
metric.str = "count";
a.Showme();
metric.str = "avg";
b.ShowMe();