通过文本别名引用JavaScript变量

5

有没有可能通过文本别名引用JavaScript变量?例如:

var x = 2;
var y = convertToVariableRef("x");

调用上述函数后: “y将成为与x相同的引用,而不仅仅是将x的值复制到y”。

在JavaScript中有eval()函数,它会评估x并将值赋给y - Grijesh Chauhan
1
可能是JavaScript变量引用/别名的重复问题。 - Ashoka Mondal
6个回答

4
如果您在没有任何函数作用域的情况下声明一个对象,它将成为window对象的属性,因此您可以像这样获取它的引用:
function convertToVariableRef (ref) {
  return window[ref];
}

var x = 2;
var y = convertToVariableRef("x");

但它只是复制原始类型的值,而对于非原始类型则只是复制引用。

数组、对象等都是非原始类型。

var x = [1];
var y = convertToVariableRef("x");
y[0] = 2;

// log: x -->  [2]

3

引用基本变量(如整数)是不可能的。如果您确实想要使用这样的引用,您可以添加一些额外的复杂填充(例如AngularJS等框架)来观察值的更改。

但事实上,更简单的方法是将您的值包装为一个可引用的对象,即:

var x = {value: 2};
var y = x;

只需要使用 x.valuey.value

3

您可以直接创建一个对象反射并给它分配属性。

var reflect = new Object();
reflect.x = 2;
var y = reflect["x"];

Fiddle: http://jsfiddle.net/wE4Ft/


2
这绝对是最简单、最优美的方法。它非常适用于需要间接引用嵌入在 HTML 中并由 jQuery 提取的变量的情况。 - Johann
2
这个不起作用。var y = reflect["x"]; 复制的是值,而不是引用。请参见 http://jsfiddle.net/wE4Ft/1/。 - JustAPoring
@JustAPoring: 你可以使用这个Hack: Fiddle。这不是一个好的解决方案,但这取决于你的用途。 - Re Captcha

3
调用上述函数后,y将成为与x相同的引用,而不仅仅是将x的值复制到y中。
不,JavaScript没有那种对变量的引用。
最好使用对象和属性:
var obj = {x: 2};
var yobj = obj;
consoel.log(yobj.x); // 2
< p > 在上面的例子中,yobjobj 都指向同一个内存中的对象,并且这个对象有一个 x 属性。因此,通过任何一个引用修改 x 将会更新这个对象。


我之前说 JavaScript 没有对变量的引用 在那个意义上:JavaScript 的闭包隐式地接收一个指向隐藏对象的变量绑定对象的引用,而该隐藏对象又引用了变量。因此,在某种意义上,JavaScript 有对变量的引用(间接地,通过一个隐藏对象)。但你无法获得对该隐藏对象的引用,因此它并没有助于你所描述的问题。


1
在 eval 中,“y 是否与 x 引用相同”?这就是我没有发布答案的原因。 - Grijesh Chauhan
@GrijeshChauhan:谢谢。这就是在我完全清醒之前回答问题的结果。我已经纠正了它。 - T.J. Crowder
嗯,这取决于你如何看待它。JavaScript 中的所有变量都是引用(除了那些引用原始值的变量)。 - Jakob
@Jakob:变量不是引用; 变量包含值,在对象引用的情况下,该值是对对象的引用。但这与具有对变量的引用*不同。 - T.J. Crowder
@T.J.Crowder:没错,表述得更好!不过我认为没有人要求“引用变量”的参考。问题是如何使“y成为与x相同的引用”,这正是每当您执行y = x时发生的情况(只要右侧不是原始类型)。 - Jakob
@Jakob:非常确定原帖作者正在寻找一个变量的引用,尤其是由于问题的示例涉及一个原始类型。 - T.J. Crowder

2

对于对象和数组,两个变量可以指向同一个对象或数组,但对于像数字或布尔值这样的简单值,在 JavaScript 中没有办法有两个变量指向相同的原始值。

您可以将原始值包装到对象中以解决此问题。

var x = {val: 2};
var y = x;  // now both y and x point to the same object

x.val = 3;
console.log(x.val);   // 3
console.log(y.val);   // 3 (same value)

使用属性名称,你也可以像以下这样使用字符串名称访问属性:

var x = {val: 2};
var y = x;  // now both y and x point to the same object

console.log(y["val"]);   // 2   

2

1)如果变量的值是原始类型(数字,布尔,字符串),你不能得到它的引用。你只能复制它。

2)即使变量不是原始类型,但附加到当前作用域(例如,在您的示例中使用var声明),也是不可能的(有两个例外情况)。

唯一有效的情况是非原始类型,且属于当前作用域以外的其他对象。就像这样:

 var obj = { a: [1,2,3], b: 42 };

 var copyOfA = obj.a;

 // do something to copyOfA
 copyOfA.splice(1);

 // now this has changed!
 console.log(obj.a);

有两个例外:

  • 使用eval(这不是很常规的做法)
  • 如果当前作用域是全局作用域(通常不是这样,因为你不会让所有东西都变成全局的,对吧?)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接