在 JavaScript 中通过引用传递变量

发布于 2024-12-10 02:39:37 字数 326 浏览 0 评论 0原文

如何在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(18

年华零落成诗 2024-12-17 02:39:37

JavaScript 中没有可用的“按引用传递”。您可以传递一个对象(也就是说,您可以按值传递对对象的引用),然后使用函数修改对象内容:

function alterObject(obj) {
  obj.foo = "goodbye";
}

var myObj = { foo: "hello world" };

alterObject(myObj);

alert(myObj.foo); // "goodbye" instead of "hello world"

您可以使用数字索引迭代数组的属性并修改每个属性如果需要的话,可以是数组的单元格。

var arr = [1, 2, 3];

for (var i = 0; i < arr.length; i++) { 
    arr[i] = arr[i] + 1; 
}

值得注意的是,“按引用传递”是一个非常具体的术语。它并不简单地意味着可以传递对可修改对象的引用。相反,它意味着可以传递一个简单的变量,以允许函数在调用上下文中修改该值。所以:

 function swap(a, b) {
   var tmp = a;
   a = b;
   b = tmp; //assign tmp to b
 }

 var x = 1, y = 2;
 swap(x, y);

 alert("x is " + x + ", y is " + y); // "x is 1, y is 2"

在像 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:

function alterObject(obj) {
  obj.foo = "goodbye";
}

var myObj = { foo: "hello world" };

alterObject(myObj);

alert(myObj.foo); // "goodbye" instead of "hello world"

You can iterate over the properties of an array with a numeric index and modify each cell of the array, if you want.

var arr = [1, 2, 3];

for (var i = 0; i < arr.length; i++) { 
    arr[i] = arr[i] + 1; 
}

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:

 function swap(a, b) {
   var tmp = a;
   a = b;
   b = tmp; //assign tmp to b
 }

 var x = 1, y = 2;
 swap(x, y);

 alert("x is " + x + ", y is " + y); // "x is 1, y is 2"

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.

edithere 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.)

爱的那么颓废 2024-12-17 02:39:37
  1. 字符串和数字等基本类型变量始终按值传递。
  2. 数组和对象根据以下条件通过引用或值传递:
  • 如果要设置对象或数组的值,则为按值传递。

     object1 = { prop: "汽车" };
     数组1 = [1,2,3];
    
  • 如果要更改对象或数组的属性值,则为“按引用传递”。

     object1.prop = "汽车";
     数组1[0] = 9;
    

代码

function passVar(obj1, obj2, num) {
    obj1.prop = "laptop"; // will CHANGE original
    obj2 = { prop: "computer" }; //will NOT affect original
    num = num + 1; // will NOT affect original
}

var object1 = {
    prop: "car"
};
var object2 = {
    prop: "bike"
};
var number1 = 10;

passVar(object1, object2, number1);
console.log(object1); // output: Object { prop: "laptop" }
console.log(object2); // output: Object { prop: "bike" }
console.log(number1); // ouput: 10

  1. Primitive type variables like strings and numbers are always passed by value.
  2. Arrays and Objects are passed by reference or by value based on these conditions:
  • if you are setting the value of an object or array it is Pass by Value.

     object1 = { prop: "car" };
     array1 = [1,2,3];
    
  • if you are changing a property value of an object or array then it is Pass by Reference.

     object1.prop = "car";
     array1[0] = 9;
    

Code

function passVar(obj1, obj2, num) {
    obj1.prop = "laptop"; // will CHANGE original
    obj2 = { prop: "computer" }; //will NOT affect original
    num = num + 1; // will NOT affect original
}

var object1 = {
    prop: "car"
};
var object2 = {
    prop: "bike"
};
var number1 = 10;

passVar(object1, object2, number1);
console.log(object1); // output: Object { prop: "laptop" }
console.log(object2); // output: Object { prop: "bike" }
console.log(number1); // ouput: 10

樱花坊 2024-12-17 02:39:37

通过引用传递变量的解决方法:

var a = 1;
inc = function(variableName) {
  window[variableName] += 1;
};

inc('a');

alert(a); // 2

是的,实际上您可以在不访问全局变量的情况下完成此操作:

inc = (function () {
    var variableName = 0;

    var init = function () {
        variableName += 1;
        alert(variableName);
    }

    return init;
})();

inc();

Workaround to pass variable like by reference:

var a = 1;
inc = function(variableName) {
  window[variableName] += 1;
};

inc('a');

alert(a); // 2

And yup, actually you can do it without access a global variable:

inc = (function () {
    var variableName = 0;

    var init = function () {
        variableName += 1;
        alert(variableName);
    }

    return init;
})();

inc();
陌路终见情 2024-12-17 02:39:37

简单对象

function foo(x) {
  // Function with other context
  // Modify `x` property, increasing the value
  x.value++;
}

// Initialize `ref` as object
var ref = {
  // The `value` is inside `ref` variable object
  // The initial value is `1`
  value: 1
};

// Call function with object value
foo(ref);
// Call function with object value again
foo(ref);

console.log(ref.value); // Prints "3"


自定义对象

rvar

/**
 * Aux function to create by-references variables
 */
function rvar(name, value, context) {
  // If `this` is a `rvar` instance
  if (this instanceof rvar) {
    // Inside `rvar` context...

    // Internal object value
    this.value = value;

    // Object `name` property
    Object.defineProperty(this, 'name', { value: name });

    // Object `hasValue` property
    Object.defineProperty(this, 'hasValue', {
      get: function () {
        // If the internal object value is not `undefined`
        return this.value !== undefined;
      }
    });

    // Copy value constructor for type-check
    if ((value !== undefined) && (value !== null)) {
      this.constructor = value.constructor;
    }

    // To String method
    this.toString = function () {
      // Convert the internal value to string
      return this.value + '';
    };
  } else {
    // Outside `rvar` context...

    // Initialice `rvar` object
    if (!rvar.refs) {
      rvar.refs = {};
    }

    // Initialize context if it is not defined
    if (!context) {
      context = this;
    }

    // Store variable
    rvar.refs[name] = new rvar(name, value, context);

    // Define variable at context
    Object.defineProperty(context, name, {
      // Getter
      get: function () { return rvar.refs[name]; },
      // Setter
      set: function (v) { rvar.refs[name].value = v; },
      // Can be overrided?
      configurable: true
    });

    // Return object reference
    return context[name];
  }
}

// Variable Declaration

// Declare `test_ref` variable
rvar('test_ref_1');

// Assign value `5`
test_ref_1 = 5;
// Or
test_ref_1.value = 5;

// Or declare and initialize with `5`:
rvar('test_ref_2', 5);

// ------------------------------
// Test Code

// Test Function
function Fn1(v) { v.value = 100; }

// Test
function test(fn) { console.log(fn.toString()); console.info(fn()); }

// Declare
rvar('test_ref_number');

// First assign
test_ref_number = 5;
test(() => test_ref_number.value === 5);

// Call function with reference
Fn1(test_ref_number);
test(() => test_ref_number.value === 100);

// Increase value
test_ref_number++;
test(() => test_ref_number.value === 101);

// Update value
test_ref_number = test_ref_number - 10;
test(() => test_ref_number.value === 91);

Simple Object

function foo(x) {
  // Function with other context
  // Modify `x` property, increasing the value
  x.value++;
}

// Initialize `ref` as object
var ref = {
  // The `value` is inside `ref` variable object
  // The initial value is `1`
  value: 1
};

// Call function with object value
foo(ref);
// Call function with object value again
foo(ref);

console.log(ref.value); // Prints "3"


Custom Object

Object rvar

/**
 * Aux function to create by-references variables
 */
function rvar(name, value, context) {
  // If `this` is a `rvar` instance
  if (this instanceof rvar) {
    // Inside `rvar` context...

    // Internal object value
    this.value = value;

    // Object `name` property
    Object.defineProperty(this, 'name', { value: name });

    // Object `hasValue` property
    Object.defineProperty(this, 'hasValue', {
      get: function () {
        // If the internal object value is not `undefined`
        return this.value !== undefined;
      }
    });

    // Copy value constructor for type-check
    if ((value !== undefined) && (value !== null)) {
      this.constructor = value.constructor;
    }

    // To String method
    this.toString = function () {
      // Convert the internal value to string
      return this.value + '';
    };
  } else {
    // Outside `rvar` context...

    // Initialice `rvar` object
    if (!rvar.refs) {
      rvar.refs = {};
    }

    // Initialize context if it is not defined
    if (!context) {
      context = this;
    }

    // Store variable
    rvar.refs[name] = new rvar(name, value, context);

    // Define variable at context
    Object.defineProperty(context, name, {
      // Getter
      get: function () { return rvar.refs[name]; },
      // Setter
      set: function (v) { rvar.refs[name].value = v; },
      // Can be overrided?
      configurable: true
    });

    // Return object reference
    return context[name];
  }
}

// Variable Declaration

// Declare `test_ref` variable
rvar('test_ref_1');

// Assign value `5`
test_ref_1 = 5;
// Or
test_ref_1.value = 5;

// Or declare and initialize with `5`:
rvar('test_ref_2', 5);

// ------------------------------
// Test Code

// Test Function
function Fn1(v) { v.value = 100; }

// Test
function test(fn) { console.log(fn.toString()); console.info(fn()); }

// Declare
rvar('test_ref_number');

// First assign
test_ref_number = 5;
test(() => test_ref_number.value === 5);

// Call function with reference
Fn1(test_ref_number);
test(() => test_ref_number.value === 100);

// Increase value
test_ref_number++;
test(() => test_ref_number.value === 101);

// Update value
test_ref_number = test_ref_number - 10;
test(() => test_ref_number.value === 91);

温柔戏命师 2024-12-17 02:39:37

通过引用传递任何(本地、原始)变量的另一种方法是通过eval“即时”用闭包包装变量。这也适用于“use strict”。 (注意:请注意,eval 对 JavaScript 优化器不友好,并且变量名称周围缺少引号可能会导致不可预测的结果)

"use strict"

// Return text that will reference variable by name (by capturing that variable to closure)
function byRef(varName){
    return "({get value(){return "+varName+";}, set value(v){"+varName+"=v;}})";
}

// Demo

// Assign argument by reference
function modifyArgument(argRef, multiplier){
    argRef.value = argRef.value * multiplier;
}

(function(){
    var x = 10;

    alert("x before: " + x);
    modifyArgument(eval(byRef("x")), 42);
    alert("x after: " + x);
})()

实时示例: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 that eval is not friendly to JavaScript optimizers, and also missing quotes around variable name may cause unpredictive results)

"use strict"

// Return text that will reference variable by name (by capturing that variable to closure)
function byRef(varName){
    return "({get value(){return "+varName+";}, set value(v){"+varName+"=v;}})";
}

// Demo

// Assign argument by reference
function modifyArgument(argRef, multiplier){
    argRef.value = argRef.value * multiplier;
}

(function(){
    var x = 10;

    alert("x before: " + x);
    modifyArgument(eval(byRef("x")), 42);
    alert("x after: " + x);
})()

Live sample: https://jsfiddle.net/t3k4403w/

巾帼英雄 2024-12-17 02:39:37

我个人不喜欢各种编程语言提供的“按引用传递”功能。也许这是因为我刚刚发现函数式编程的概念,但当我看到导致副作用的函数(例如操作通过引用传递的参数)时,我总是会起鸡皮疙瘩。我个人强烈拥护“单一责任”原则。

恕我直言,函数应该使用 return 关键字仅返回一个结果/值。我不会修改参数/参数,而是返回修改后的参数/参数值,并将任何所需的重新分配留给调用代码。

但有时(希望很少),需要从同一函数返回两个或多个结果值。在这种情况下,我会选择将所有这些结果值包含在单个结构或对象中。同样,处理任何重新分配都应该由调用代码决定。

示例:

假设通过在参数列表中使用特殊关键字(如“ref”)来支持传递参数。我的代码可能看起来像这样:

//The Function
function doSomething(ref value) {
    value = "Bar";
}

//The Calling Code
var value = "Foo";
doSomething(value);
console.log(value); //Bar

相反,我实际上更喜欢这样做:

//The Function
function doSomething(value) {
    value = "Bar";
    return value;
}

//The Calling Code:
var value = "Foo";
value = doSomething(value); //Reassignment
console.log(value); //Bar

当我需要编写一个返回多个值的函数时,我也不会使用通过引用传递的参数。因此,我会避免这样的代码:

//The Function
function doSomething(ref value) {
    value = "Bar";

    //Do other work
    var otherValue = "Something else";

    return otherValue;
}

//The Calling Code
var value = "Foo";
var otherValue = doSomething(value);
console.log(value); //Bar
console.log(otherValue); //Something else

相反,我实际上更愿意在对象内返回两个新值,如下所示:

//The Function
function doSomething(value) {
    value = "Bar";

    //Do more work
    var otherValue = "Something else";

    return {
        value: value,
        otherValue: otherValue
    };
}

//The Calling Code:
var value = "Foo";
var result = doSomething(value);
value = result.value; //Reassignment
console.log(value); //Bar
console.log(result.otherValue);

这些代码示例非常简单,但它大致演示了我个人将如何处理此类内容。它帮助我将各种责任放在正确的位置。

快乐编码。 :)

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:

//The Function
function doSomething(ref value) {
    value = "Bar";
}

//The Calling Code
var value = "Foo";
doSomething(value);
console.log(value); //Bar

Instead, I would actually prefer to do something like this:

//The Function
function doSomething(value) {
    value = "Bar";
    return value;
}

//The Calling Code:
var value = "Foo";
value = doSomething(value); //Reassignment
console.log(value); //Bar

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:

//The Function
function doSomething(ref value) {
    value = "Bar";

    //Do other work
    var otherValue = "Something else";

    return otherValue;
}

//The Calling Code
var value = "Foo";
var otherValue = doSomething(value);
console.log(value); //Bar
console.log(otherValue); //Something else

Instead, I would actually prefer to return both new values inside an object, like this:

//The Function
function doSomething(value) {
    value = "Bar";

    //Do more work
    var otherValue = "Something else";

    return {
        value: value,
        otherValue: otherValue
    };
}

//The Calling Code:
var value = "Foo";
var result = doSomething(value);
value = result.value; //Reassignment
console.log(value); //Bar
console.log(result.otherValue);

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. :)

邮友 2024-12-17 02:39:37

我一直在尝试使用语法来做这类事情,但它需要一些有点不寻常的助手。它首先根本不使用“var”,而是使用一个简单的“DECLARE”帮助器,该帮助器创建局部变量并通过匿名回调定义其范围。通过控制变量的声明方式,我们可以选择将它们包装到对象中,以便本质上它们始终可以通过引用传递。这与上面 Eduardo Cuomo 的答案之一类似,但下面的解决方案不需要使用字符串作为变量标识符。这里有一些最小的代码来展示这个概念。

function Wrapper(val){
    this.VAL = val;
}
Wrapper.prototype.toString = function(){
    return this.VAL.toString();
}

function DECLARE(val, callback){
    var valWrapped = new Wrapper(val);    
    callback(valWrapped);
}

function INC(ref){
    if(ref && ref.hasOwnProperty('VAL')){
        ref.VAL++; 
    }
    else{
        ref++;//or maybe throw here instead?
    }

    return ref;
}

DECLARE(5, function(five){ //consider this line the same as 'let five = 5'
console.log("five is now " + five);
INC(five); // increment
console.log("five is incremented to " + five);
});

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.

function Wrapper(val){
    this.VAL = val;
}
Wrapper.prototype.toString = function(){
    return this.VAL.toString();
}

function DECLARE(val, callback){
    var valWrapped = new Wrapper(val);    
    callback(valWrapped);
}

function INC(ref){
    if(ref && ref.hasOwnProperty('VAL')){
        ref.VAL++; 
    }
    else{
        ref++;//or maybe throw here instead?
    }

    return ref;
}

DECLARE(5, function(five){ //consider this line the same as 'let five = 5'
console.log("five is now " + five);
INC(five); // increment
console.log("five is incremented to " + five);
});
腹黑女流氓 2024-12-17 02:39:37

其实有一个很好的解决方案:

function updateArray(context, targetName, callback) {
    context[targetName] = context[targetName].map(callback);
}

var myArray = ['a', 'b', 'c'];
updateArray(this, 'myArray', item => {return '_' + item});

console.log(myArray); //(3) ["_a", "_b", "_c"]

There's actually a pretty sollution:

function updateArray(context, targetName, callback) {
    context[targetName] = context[targetName].map(callback);
}

var myArray = ['a', 'b', 'c'];
updateArray(this, 'myArray', item => {return '_' + item});

console.log(myArray); //(3) ["_a", "_b", "_c"]
请持续率性 2024-12-17 02:39:37

事实上这真的很容易。问题是要理解,一旦传递经典参数,您就会进入另一个只读区域。

解决方案是使用 JavaScript 的面向对象设计来传递参数。它与将参数放入全局/作用域变量中相同,但更好...

function action(){
  /* Process this.arg, modification allowed */
}

action.arg = [["empty-array"], "some string", 0x100, "last argument"];
action();

您还可以承诺填充以享受众所周知的链:
这就是整个事情,具有类似承诺的结构

function action(){
  /* Process this.arg, modification allowed */
  this.arg = ["a", "b"];
}

action.setArg = function(){this.arg = arguments; return this;}

action.setArg(["empty-array"], "some string", 0x100, "last argument")()

或者更好......

action.setArg(["empty-array"],"some string",0x100,"last argument").call()

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...

function action(){
  /* Process this.arg, modification allowed */
}

action.arg = [["empty-array"], "some string", 0x100, "last argument"];
action();

You can also promise stuff up to enjoy the well-known chain:
Here is the whole thing, with promise-like structure

function action(){
  /* Process this.arg, modification allowed */
  this.arg = ["a", "b"];
}

action.setArg = function(){this.arg = arguments; return this;}

action.setArg(["empty-array"], "some string", 0x100, "last argument")()

Or better yet...

action.setArg(["empty-array"],"some string",0x100,"last argument").call()
心碎无痕… 2024-12-17 02:39:37

JavaScript 可以修改函数内的数组项(它作为对象/数组的引用传递)。

function makeAllPretty(items) {
   for (var x = 0; x < myArray.length; x++){
      // Do stuff to the array
      items[x] = makePretty(items[x]);
   }
}

myArray = new Array(var1, var2, var3);
makeAllPretty(myArray);

这是另一个例子:

function inc(items) {
  for (let i=0; i < items.length; i++) {
    items[i]++;
  }
}

let values = [1,2,3];
inc(values);
console.log(values);
// Prints [2,3,4]

JavaScript can modify array items inside a function (it is passed as a reference to the object/array).

function makeAllPretty(items) {
   for (var x = 0; x < myArray.length; x++){
      // Do stuff to the array
      items[x] = makePretty(items[x]);
   }
}

myArray = new Array(var1, var2, var3);
makeAllPretty(myArray);

Here's another example:

function inc(items) {
  for (let i=0; i < items.length; i++) {
    items[i]++;
  }
}

let values = [1,2,3];
inc(values);
console.log(values);
// Prints [2,3,4]
蔚蓝源自深海 2024-12-17 02:39:37

由于我们在 JavaScript 中没有通过引用传递功能,因此唯一的方法是让函数返回值并让调用者分配它:

所以

makePretty(myArray[x]);

应该是

myArray[x] = makePretty(myArray[x]);

这样,以防万一您需要在函数内部进行分配,只要突变是必要的,然后传递对象并对其进行突变就足够了

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

makePretty(myArray[x]);

should be

myArray[x] = makePretty(myArray[x]);

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

江南烟雨〆相思醉 2024-12-17 02:39:37

抛开引用传递讨论不谈,那些仍在寻找上述问题解决方案的人可以使用:

const myArray = new Array(var1, var2, var3);
myArray.forEach(var => var = makePretty(var));

Putting aside the pass-by-reference discussion, those still looking for a solution to the stated question could use:

const myArray = new Array(var1, var2, var3);
myArray.forEach(var => var = makePretty(var));
携君以终年 2024-12-17 02:39:37

我完全明白你的意思。同样的事情在 Swift 中不会有问题。最重要的是使用 let,而不是 var

事实上,原语是按值传递的,但迭代时 var i 的值没有复制到匿名函数中这一事实至少可以说是相当令人惊讶的。

for (let i = 0; i < boxArray.length; i++) {
  boxArray[i].onclick = function() { console.log(i) }; // Correctly prints the index
}

I know exactly what you mean. The same thing in Swift will be no problem. The bottom line is use let, not var.

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.

for (let i = 0; i < boxArray.length; i++) {
  boxArray[i].onclick = function() { console.log(i) }; // Correctly prints the index
}
裂开嘴轻声笑有多痛 2024-12-17 02:39:37

如果您想通过引用传递变量,更好的方法是在对象中传递参数,然后使用 window 开始更改值:

window["varName"] = value;

示例:

// Variables with first values
var x = 1, b = 0, f = 15;


function asByReference (
    argumentHasVars = {},   // Passing variables in object
    newValues = [])         // Pass new values in array
{
    let VarsNames = [];

    // Getting variables names one by one
    for(let name in argumentHasVars)
        VarsNames.push(name);

    // Accessing variables by using window one by one
    for(let i = 0; i < VarsNames.length; i += 1)
        window[VarsNames[i]] = newValues[i]; // Set new value
}

console.log(x, b, f); // Output with first values

asByReference({x, b, f}, [5, 5, 5]); // Passing as by reference

console.log(x, b, f); // Output after changing values

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:

window["varName"] = value;

Example:

// Variables with first values
var x = 1, b = 0, f = 15;


function asByReference (
    argumentHasVars = {},   // Passing variables in object
    newValues = [])         // Pass new values in array
{
    let VarsNames = [];

    // Getting variables names one by one
    for(let name in argumentHasVars)
        VarsNames.push(name);

    // Accessing variables by using window one by one
    for(let i = 0; i < VarsNames.length; i += 1)
        window[VarsNames[i]] = newValues[i]; // Set new value
}

console.log(x, b, f); // Output with first values

asByReference({x, b, f}, [5, 5, 5]); // Passing as by reference

console.log(x, b, f); // Output after changing values
欢你一世 2024-12-17 02:39:37

我喜欢解决 JavaScript 中缺乏通过引用的问题,就像这个例子所示。

其本质是您不要尝试通过引用创建。相反,您可以使用返回功能并使其能够返回多个值。因此无需将值插入数组或对象中。

var x = "First";
var y = "Second";
var z = "Third";

log('Before call:',x,y,z);
with (myFunc(x, y, z)) {x = a; y = b; z = c;} // <-- Way to call it
log('After call :',x,y,z);


function myFunc(a, b, c) {
  a = "Changed first parameter";
  b = "Changed second parameter";
  c = "Changed third parameter";
  return {a:a, b:b, c:c}; // <-- Return multiple values
}

function log(txt,p1,p2,p3) {
  document.getElementById('msg').innerHTML += txt + '<br>' + p1 + '<br>' + p2 + '<br>' + p3 + '<br><br>'
}
<div id='msg'></div>

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.

var x = "First";
var y = "Second";
var z = "Third";

log('Before call:',x,y,z);
with (myFunc(x, y, z)) {x = a; y = b; z = c;} // <-- Way to call it
log('After call :',x,y,z);


function myFunc(a, b, c) {
  a = "Changed first parameter";
  b = "Changed second parameter";
  c = "Changed third parameter";
  return {a:a, b:b, c:c}; // <-- Return multiple values
}

function log(txt,p1,p2,p3) {
  document.getElementById('msg').innerHTML += txt + '<br>' + p1 + '<br>' + p2 + '<br>' + p3 + '<br><br>'
}
<div id='msg'></div>

眼泪淡了忧伤 2024-12-17 02:39:37

使用 解构 这是我的一个例子有3个变量,并且在每个变量上我执行多个操作:

  • 如果值小于0则更改为0,
  • 如果大于255则更改为1,
  • 否则将数字除以255进行转换从 0-255 范围到 0-1 范围。
let a = 52.4, b = -25.1, c = 534.5;
[a, b, c] = [a, b, c].map(n => n < 0 ? 0 : n > 255 ? 1 : n / 255);
console.log(a, b, c); // 0.20549019607843136 0 1

Using Destructuring here is an example where I have 3 variables, and on each I do the multiple operations:

  • If value is less than 0 then change to 0,
  • If greater than 255 then change to 1,
  • Otherwise dived the number by 255 to convert from a range of 0-255 to a range of 0-1.
let a = 52.4, b = -25.1, c = 534.5;
[a, b, c] = [a, b, c].map(n => n < 0 ? 0 : n > 255 ? 1 : n / 255);
console.log(a, b, c); // 0.20549019607843136 0 1
意中人 2024-12-17 02:39:37

这可能无法回答所述的确切问题,但对于许多出现主题的情况,更实用的设计是一条富有成效的途径,它实际上降低了复杂性,而不是增加复杂性:

result = new Array(var1, var2, var3)
    .map(makePretty)

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:

result = new Array(var1, var2, var3)
    .map(makePretty)
陌上青苔 2024-12-17 02:39:37

咱们简单点吧!!

它不需要这么多代码来为您的问题提供正确的答案。

  1. 当你调用 makePretty(myArray[x]); 时,没有人能告诉它经过
    引用或按值传递。
  2. 因为您没有指定myArray第'x'th ELEMENT的数据类型。
  3. 如果该元素是int(或任何按值传递的数据类型),它将将该值传递给函数makePretty
  4. 如果该元素是按引用传递类型,它将按引用传递。
  5. 当然,您的 myArray 是引用类型。
  6. 但我在这里讨论的是元素的数据类型。不是整个数组

Let's be simple!!

It does not require this much code to provide the proper answer to your question.

  1. when you call makePretty(myArray[x]); nobody can tell it passes by
    reference or passes by value.
  2. Because you don't have specified the data type of the 'x'th ELEMENT of myArray.
  3. If that element is a int (or any data type passes by value) it will pass by the value to the function makePretty.
  4. If that element is a pass by reference type it will pass by reference.
  5. Of course your myArray is reference type.
  6. But I'm talking here about the data type of the element. Not the whole array.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文