简体   繁体   English

Javascript:如何创建一个函数 1. 接受一个全局变量作为参数 2. 改变该全局变量的值?

[英]Javascript: How can I create a function that 1. accepts a global variable as a parameter 2. alters the value of that global variable?

I'm trying to create a function that accepts a global variable as a parameter and changes the value of that global variable.我正在尝试创建一个函数,该函数接受一个全局变量作为参数并更改该全局变量的值。 Here's a simple example that illustrates what I'm trying to do:这是一个简单的例子,说明了我正在尝试做的事情:

var number = 20;
function setnew(num) {
  num += 1;
};

setnew(number);
console.log(number) //-> 20
                    //I want this to return 21

Even after the setnew function is invoked, number remains unchanged.即使在调用setnew函数之后, number保持不变。 Can someone explain why number remains unchanged and suggest another way to achieve my intended goal?有人可以解释为什么number保持不变并提出另一种实现我预期目标的方法吗?

Since Javascript does not support true reference passing where you can change the original variable, you can't directly do what you're asking.由于 Javascript 不支持真正的引用传递,您可以在其中更改原始变量,因此您无法直接执行您所要求的操作。 The usual work-around is to wrap the global in an object.通常的解决方法是将全局包装在一个对象中。

var myGlobal = {
     counter: 0;
};

function increment(obj, prop) {
  ++obj[prop];
}

increment(myGlobal, "counter");
increment(myGlobal, "counter");

console.log(myGlobal.counter);   // 2

Or, if the property name is already known, you can just do this:或者,如果属性名称已知,您可以这样做:

var myGlobal = {
     counter: 0;
};

function incrementCnt(obj) {
  ++obj.counter;
}

incrementCnt(myGlobal);
incrementCnt(myGlobal);

console.log(myGlobal.counter);   // 2

This works because when you pass an object to a function, what is passed is a pointer to that same object (the object is not copied).这是有效的,因为当您将对象传递给函数时,传递的是指向同一对象的指针(该对象未被复制)。 So, if you modify any property on that object, there is only one copy of the object so you are modifying the property on that one copy of the object and everyone who has a reference to that object will see the property change.因此,如果您修改该对象上的任何属性,则该对象只有一个副本,因此您正在修改该对象副本上的属性,并且每个拥有该对象引用的人都会看到该属性更改。

Primitives like numbers and booleans are passed by value which works like a copy was made so the original can never be affected from the function.像数字和布尔值这样的原语是按值传递的,这就像制作副本一样,因此原始版本永远不会受到函数的影响。


Can someone explain why number remains unchanged and suggest another way to achieve my intended goal?有人可以解释为什么number保持不变并提出另一种实现我预期目标的方法吗?

When passing a number to a function, the value of the number is copied to a new variable which is the argument to the function.将数字传递给函数时,数字的值被复制到作为函数参数的新变量中。 Changing the value of that argument to the function ONLY affects that argument - it has no connection at all to the original variable.将该参数的值更改为函数只会影响该参数 - 它与原始变量完全没有联系。 This is because in Javascript primitives are passed by value, not by reference.这是因为在 Javascript 中原语是按值传递的,而不是按引用传递的。 So, no reference is maintained at all to where the value came from.因此,根本没有保留对值来自何处的引用。 When you receive it in the function, it is a new variable that stands on its own.当您在函数中接收它时,它是一个独立的新变量。


Another possible work-around is to just return the modified value from your function and allow the caller to assign that modified value to whatever they want:另一种可能的解决方法是从您的函数返回修改后的值,并允许调用者将该修改后的值分配给他们想要的任何值:

var counter = 0;

function increment(val) {
  return val + 10;
}

counter = increment(counter);

console.log(counter);   // 10

If you were to pass in a object instead of a primitive, you would be able to update it.如果您要传入一个对象而不是一个原语,您将能够更新它。

For example:例如:

var number = { value: 20 };
function setnew(num) {
  num.value += 1;
};

setnew(number);
console.log(number.value) //-> 21

Basically when you pass in an object, javascript is actually only passing a reference to the variable, while when you pass an integer, it is going to pass a copy of the value.基本上,当您传入一个对象时,javascript 实际上只传递对变量的引用,而当您传递一个整数时,它将传递该值的副本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM