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

IT技术 javascript string pass-by-reference
2021-01-29 02:20:54

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

拿这个例子:

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 参考说 metric 是一个对象。

我试过这个,这不是我想要的,但非常接近:

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)

这里的要点:

  1. 我希望能够使用普通字符串对象一样使用度量
  2. 我希望每个报告都引用同一个对象。
6个回答

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";
这并没有演示按值传递。这样做只是简单地更改指标值,当然它会记录新值!var obj = { a: "a" }; var b = obj.a; 控制台日志(obj.a);// ab = "b"; 控制台日志(obj.a);// 一个
2021-03-29 02:20:54
做得很好。我最喜欢这个,因为在 Report 中,我可以使用源代码中最少混乱的字符串,即 a().charAt(1) 比 String(a).charAt(1) 漂亮得多
2021-03-31 02:20:54
“闭包是一个代码块,可以通过访问封闭范围的变量来引用(和传递)。” 来自stackoverflow.com/a/5444581/483588
2021-04-03 02:20:54

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

var metric = { str : "count" } 
metric.str = "avg";

现在 metric.str 将包含“avg”

这就是我在访问此页面时所想象的答案。它或多或少是“Closure?”的最佳简写。也在这个列表中回答。w3schools.com/js/js_objects.asp
2021-03-19 02:20:54
不是闭包(本身),而是度量是一个像 OP 所期望的那样的对象——唯一的失败是额外的属性引用。JavaScript 字符串是不可变的,但度量对象是可变的,并且该度量对象以可以共享度量对象引用的方式提供了一个间接级别。
2021-03-24 02:20:54

关闭?

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();

如果您没有关闭所需的字符串变量,那么我想唯一的其他方法是修改 ShowMe 函数,如@John Millikin 的回答或重新构建代码库。

好的。但是我想避免使用 setter ......并且在调用所有本地 String 方法(如 charAt)而不手动设置它们时,它不能很好地扩展。
2021-04-07 02:20:54

如果您将变量作为对象传递,它将起作用,因为对象在 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);
是的,这就是我上一个例子所展示的。它是一个覆盖 object.toString 函数的对象。
2021-03-23 02:20:54
更一般的用法是function modifyVar(parent,obj,newValue){ parent[obj]=newValue; }……使用窗口?如果没有其他父母
2021-04-10 02:20:54

jsfiddle:https ://jsfiddle.net/ncwhmty7/1/

字符串原语 (String Literal) 和 String 对象都是不可变的。这意味着在函数中对字符串变量内容的任何更改都与函数外发生的任何事情完全分开。有几个选项可以克服这个问题:

1.从函数返回修改后的函数值

function concatenateString(stringA, stringB) {
    return stringA + stringB;
}
alert(concatenateString("Hi", " there"));

2.将字符串变量转换为真正的Object 

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);