在 JavaScript 中通过引用传递变量
如何在 JavaScript 中通过引用传递变量?
我想要对三个变量执行多项操作,因此我想将它们放入 for 循环中并对每个变量执行操作。
伪代码:
myArray = new Array(var1, var2, var3);
for (var x = 0; x < myArray.length; x++){
// Do stuff to the array
makePretty(myArray[x]);
}
// Now do stuff to the updated variables
执行此操作的最佳方法是什么?
How do I pass variables by reference in JavaScript?
I have three variables that I want to perform several operations to, so I want to put them in a for loop and perform the operations to each one.
Pseudocode:
myArray = new Array(var1, var2, var3);
for (var x = 0; x < myArray.length; x++){
// Do stuff to the array
makePretty(myArray[x]);
}
// Now do stuff to the updated variables
What is the best way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(18)
JavaScript 中没有可用的“按引用传递”。您可以传递一个对象(也就是说,您可以按值传递对对象的引用),然后使用函数修改对象内容:
您可以使用数字索引迭代数组的属性并修改每个属性如果需要的话,可以是数组的单元格。
值得注意的是,“按引用传递”是一个非常具体的术语。它并不简单地意味着可以传递对可修改对象的引用。相反,它意味着可以传递一个简单的变量,以允许函数在调用上下文中修改该值。所以:
在像 C++ 这样的语言中,可以做到这一点,因为该语言确实(某种程度上)具有按引用传递。
编辑——最近(2015 年 3 月)这篇文章再次在 Reddit 上引起了轰动,因为一篇与我下面提到的类似的博客文章,不过这次是关于 Java 的。在阅读 Reddit 评论中的来回评论时,我突然想到,很大一部分混乱源于涉及“引用”一词的不幸冲突。术语“按引用传递”和“按值传递”早于在编程语言中使用“对象”的概念。这实际上根本与物体无关;它与物体有关。它与函数参数有关,特别是函数参数如何“连接”(或不连接)到调用环境。特别要注意的是,在真正的引用传递语言中(一种确实涉及对象的语言),人们仍然能够修改对象内容,并且它看起来几乎和 JavaScript 中的一样。然而,人们也能够在调用环境中修改对象引用,而这是在 JavaScript 中不能做的关键事情。引用传递语言不会传递引用本身,而是传递对引用的引用。
编辑 - 这里是关于该主题的博客文章。(请注意该文章的评论,该评论解释了 C++ 并没有真正具有引用传递。这是事实。但是,C++ 确实具有创建引用的能力到普通变量,或者明确地在函数调用点创建指针,或者隐式调用其参数类型签名要求完成的函数时,这些是 JavaScript 不支持的关键事情。)
There is no "pass by reference" available in JavaScript. You can pass an object (which is to say, you can pass-by-value a reference to an object) and then have a function modify the object contents:
You can iterate over the properties of an array with a numeric index and modify each cell of the array, if you want.
It's important to note that "pass-by-reference" is a very specific term. It does not mean simply that it's possible to pass a reference to a modifiable object. Instead, it means that it's possible to pass a simple variable in such a way as to allow a function to modify that value in the calling context. So:
In a language like C++, it's possible to do that because that language does (sort-of) have pass-by-reference.
edit — this recently (March 2015) blew up on Reddit again over a blog post similar to mine mentioned below, though in this case about Java. It occurred to me while reading the back-and-forth in the Reddit comments that a big part of the confusion stems from the unfortunate collision involving the word "reference". The terminology "pass by reference" and "pass by value" predates the concept of having "objects" to work with in programming languages. It's really not about objects at all; it's about function parameters, and specifically how function parameters are "connected" (or not) to the calling environment. In particular, note that in a true pass-by-reference language — one that does involve objects — one would still have the ability to modify object contents, and it would look pretty much exactly like it does in JavaScript. However, one would also be able to modify the object reference in the calling environment, and that's the key thing that you can't do in JavaScript. A pass-by-reference language would pass not the reference itself, but a reference to the reference.
edit — here is a blog post on the topic. (Note the comment to that post that explains that C++ doesn't really have pass-by-reference. That is true. What C++ does have, however, is the ability to create references to plain variables, either explicitly at the point of function invocation to create a pointer, or implicitly when calling functions whose argument type signature calls for that to be done. Those are the key things JavaScript doesn't support.)
如果要设置对象或数组的值,则为按值传递。
如果要更改对象或数组的属性值,则为“按引用传递”。
代码
if you are setting the value of an object or array it is Pass by Value.
if you are changing a property value of an object or array then it is Pass by Reference.
Code
通过引用传递变量的解决方法:
是的,实际上您可以在不访问全局变量的情况下完成此操作:
Workaround to pass variable like by reference:
And yup, actually you can do it without access a global variable:
简单对象
自定义对象
rvar
Simple Object
Custom Object
Object
rvar
通过引用传递任何(本地、原始)变量的另一种方法是通过
eval
“即时”用闭包包装变量。这也适用于“use strict”。 (注意:请注意,eval
对 JavaScript 优化器不友好,并且变量名称周围缺少引号可能会导致不可预测的结果)实时示例:https://jsfiddle.net/t3k4403w/
Yet another approach to pass any (local, primitive) variables by reference is by wrapping variable with closure "on the fly" by
eval
. This also works with "use strict". (Note: be aware thateval
is not friendly to JavaScript optimizers, and also missing quotes around variable name may cause unpredictive results)Live sample: https://jsfiddle.net/t3k4403w/
我个人不喜欢各种编程语言提供的“按引用传递”功能。也许这是因为我刚刚发现函数式编程的概念,但当我看到导致副作用的函数(例如操作通过引用传递的参数)时,我总是会起鸡皮疙瘩。我个人强烈拥护“单一责任”原则。
恕我直言,函数应该使用 return 关键字仅返回一个结果/值。我不会修改参数/参数,而是返回修改后的参数/参数值,并将任何所需的重新分配留给调用代码。
但有时(希望很少),需要从同一函数返回两个或多个结果值。在这种情况下,我会选择将所有这些结果值包含在单个结构或对象中。同样,处理任何重新分配都应该由调用代码决定。
示例:
假设通过在参数列表中使用特殊关键字(如“ref”)来支持传递参数。我的代码可能看起来像这样:
相反,我实际上更喜欢这样做:
当我需要编写一个返回多个值的函数时,我也不会使用通过引用传递的参数。因此,我会避免这样的代码:
相反,我实际上更愿意在对象内返回两个新值,如下所示:
这些代码示例非常简单,但它大致演示了我个人将如何处理此类内容。它帮助我将各种责任放在正确的位置。
快乐编码。 :)
I personally dislike the "pass by reference" functionality offered by various programming languages. Perhaps that's because I am just discovering the concepts of functional programming, but I always get goosebumps when I see functions that cause side effects (like manipulating parameters passed by reference). I personally strongly embrace the "single responsibility" principle.
IMHO, a function should return just one result/value using the return keyword. Instead of modifying a parameter/argument, I would just return the modified parameter/argument value and leave any desired reassignments up to the calling code.
But sometimes (hopefully very rarely), it is necessary to return two or more result values from the same function. In that case, I would opt to include all those resulting values in a single structure or object. Again, processing any reassignments should be up to the calling code.
Example:
Suppose passing parameters would be supported by using a special keyword like 'ref' in the argument list. My code might look something like this:
Instead, I would actually prefer to do something like this:
When I would need to write a function that returns multiple values, I would not use parameters passed by reference either. So I would avoid code like this:
Instead, I would actually prefer to return both new values inside an object, like this:
These code examples are quite simplified, but it roughly demonstrates how I personally would handle such stuff. It helps me to keep various responsibilities in the correct place.
Happy coding. :)
我一直在尝试使用语法来做这类事情,但它需要一些有点不寻常的助手。它首先根本不使用“var”,而是使用一个简单的“DECLARE”帮助器,该帮助器创建局部变量并通过匿名回调定义其范围。通过控制变量的声明方式,我们可以选择将它们包装到对象中,以便本质上它们始终可以通过引用传递。这与上面 Eduardo Cuomo 的答案之一类似,但下面的解决方案不需要使用字符串作为变量标识符。这里有一些最小的代码来展示这个概念。
I've been playing around with syntax to do this sort of thing, but it requires some helpers that are a little unusual. It starts with not using 'var' at all, but a simple 'DECLARE' helper that creates a local variable and defines a scope for it via an anonymous callback. By controlling how variables are declared, we can choose to wrap them into objects so that they can always be passed by reference, essentially. This is similar to one of the Eduardo Cuomo's answer above, but the solution below does not require using strings as variable identifiers. Here's some minimal code to show the concept.
其实有一个很好的解决方案:
There's actually a pretty sollution:
事实上这真的很容易。问题是要理解,一旦传递经典参数,您就会进入另一个只读区域。
解决方案是使用 JavaScript 的面向对象设计来传递参数。它与将参数放入全局/作用域变量中相同,但更好...
您还可以承诺填充以享受众所周知的链:
这就是整个事情,具有类似承诺的结构
或者更好......
Actually it is really easy. The problem is understanding that once passing classic arguments, you are scoped into another, read-only zone.
The solution is to pass the arguments using JavaScript's object-oriented design. It is the same as putting the arguments in a global/scoped variable, but better...
You can also promise stuff up to enjoy the well-known chain:
Here is the whole thing, with promise-like structure
Or better yet...
JavaScript 可以修改函数内的数组项(它作为对象/数组的引用传递)。
这是另一个例子:
JavaScript can modify array items inside a function (it is passed as a reference to the object/array).
Here's another example:
由于我们在 JavaScript 中没有通过引用传递功能,因此唯一的方法是让函数返回值并让调用者分配它:
所以
应该是
这样,以防万一您需要在函数内部进行分配,只要突变是必要的,然后传递对象并对其进行突变就足够了
As we don't have pass by reference functionality in JavaScript, the only way to do this is to make the function return the value and let the caller assign it:
So
should be
This is in case you need assignment inside the function, if only mutation is necessary, then passing the object and mutating it should be enough
抛开引用传递讨论不谈,那些仍在寻找上述问题解决方案的人可以使用:
Putting aside the pass-by-reference discussion, those still looking for a solution to the stated question could use:
我完全明白你的意思。同样的事情在 Swift 中不会有问题。最重要的是使用
let
,而不是var
。事实上,原语是按值传递的,但迭代时 var i 的值没有复制到匿名函数中这一事实至少可以说是相当令人惊讶的。
I know exactly what you mean. The same thing in Swift will be no problem. The bottom line is use
let
, notvar
.The fact that primitives are passed by value, but the fact that the value of
var i
at the point of iteration is not copied into the anonymous function is quite surprising to say the least.如果您想通过引用传递变量,更好的方法是在对象中传递参数,然后使用
window
开始更改值:示例:
If you want to pass variables by reference, a better way to do that is by passing your arguments in an object and then start changing the value by using
window
:Example:
我喜欢解决 JavaScript 中缺乏通过引用的问题,就像这个例子所示。
其本质是您不要尝试通过引用创建。相反,您可以使用返回功能并使其能够返回多个值。因此无需将值插入数组或对象中。
I like to solve the lack of by reference in JavaScript like this example shows.
The essence of this is that you don't try to create a by reference. You instead use the return functionality and make it able to return multiple values. So there isn't any need to insert your values in arrays or objects.
使用 解构 这是我的一个例子有3个变量,并且在每个变量上我执行多个操作:
Using Destructuring here is an example where I have 3 variables, and on each I do the multiple operations:
这可能无法回答所述的确切问题,但对于许多出现主题的情况,更实用的设计是一条富有成效的途径,它实际上降低了复杂性,而不是增加复杂性:
This might not answer the exact question as stated, but for many cases where topic comes up, a more functional design is a fruitful avenue that actually reduces complexity in stead of adding it:
咱们简单点吧!!
它不需要这么多代码来为您的问题提供正确的答案。
引用或按值传递。
myArray
的第'x'th ELEMENT的数据类型。makePretty
。myArray
是引用类型。Let's be simple!!
It does not require this much code to provide the proper answer to your question.
makePretty(myArray[x]);
nobody can tell it passes byreference or passes by value.
myArray
.makePretty
.myArray
is reference type.