在Javascript中通过引用传递字符串

Jef*_*ang 42 javascript string pass-by-reference

我想创建一个字符串并通过引用传递它,以便我可以更改单个变量并将其传播到引用它的任何其他对象.

举个例子:

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";
Run Code Online (Sandbox Code Playgroud)

我希望能够实现这一目标:

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";
Run Code Online (Sandbox Code Playgroud)

为什么这不起作用?

关于字符串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)
Run Code Online (Sandbox Code Playgroud)

重要的一点是:

  1. 我希望能够使用公制,就像它是一个普通的字符串对象
  2. 我希望每个报告都引用同一个对象.

Joh*_*kin 55

Javascript中的字符串已经"通过引用"传递 - 使用字符串调用过程不涉及复制字符串的内容.手头有两个问题:

  • 字符串是不可变的.与C++字符串相反,一旦创建了JavaScript字符串,就无法对其进行修改.
  • 在JavaScript中,变量不是静态分配的插槽,就像在C++中一样.在您的代码中,metric是一个标签,它适用于两个完全独立的字符串变量.

这是实现所需内容的一种方法,使用闭包来实现动态范围metric:

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";
Run Code Online (Sandbox Code Playgroud)

  • 做得很好.我最喜欢这个,因为在Report中,我可以使用源中最小混乱的字符串,即a().charAt(1)比String(a)更漂亮.charAt(1) (2认同)

Mat*_*ela 34

您可以将字符串包装在对象中并修改存储字符串的字段.这与您在上一个示例中所做的类似,而无需更改函数.

var metric = { str : "count" } 
metric.str = "avg";
Run Code Online (Sandbox Code Playgroud)

现在metric.str将包含"avg"


cha*_*rit 10

关闭?

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();
Run Code Online (Sandbox Code Playgroud)

或者使它更具通用性和高性能:

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();
Run Code Online (Sandbox Code Playgroud)

如果你没有关闭所需的字符串变量,那么我认为唯一的另一种方法是修改ShowMe函数,如@John Millikin的答案或重新构建代码库.