2

我是 Javascript(和一般编程)的新手,并且一直在寻找一种方法来使用 Javascript 函数更改任意数量的 aguments 的值。

这里的答案(JavaScript variable number of arguments to function)非常有帮助。我能够使用它来创建我需要的两个功能,但我在使用第三个时遇到了麻烦。

基本上我想将可变数量的对象(原始或更复杂)传递给一个函数,并让函数改变每个对象的值。

var pants = true;
var house = true;
var hair = {/* lots of stuff */};

var onFire = function() {
        for (var i = 0; i < arguments.length; i++) {
            arguments[i] = false;
        }
};

onFire(pants, house, hair);

控制台输出:

>pants;
 true

>house;
 true

>hair;
 Object

我怎样才能制定这个函数,所以结果是:

>pants;
 false

>house;
 false

>hair;
 false

任何帮助将不胜感激!

编辑:

为了澄清事情-我正在尝试创建一个可重用的辅助函数,该函数可以更改传入的任何对象的值,false而不是键入:

var a1 = false;
var a2 = false;
...
var a+n = false;

如果我使用mathec的方法 - 是否可以“解析”object以便它的属性覆盖同名的全局变量,还是我每次都坚持明确地输入它?

var object = {
    pants: {/* lots of stuff */},
    house: {/* lots of stuff */},
    hair: {/* lots of stuff */}
};

function modifyObject(obj) {
    obj.pants = false;
    obj.house = false;
    obj.hair = false;
}

function someMagic(object){
    // wand waves...
    // rabbit exits hat....
}

控制台输出:

>pants;
 false

>house;
 false

>hair;
 false 
4

5 回答 5

5

当你在 JavaScript 中传递变量时,如果它是一个对象,你传递的是对一个值的引用的副本,但如果它是一个原始值(如真/假),你是在复制实际值。这基本上意味着,如果您传入一个对象并修改该对象的属性之一,您将修改原始对象。但是如果你传入一个像真/假这样的原语,你只会修改副本,而不是原始值。因此,如果您的目标是修改原始值,一种选择是将这些值存储在一个对象中,然后传入该对象。例如:

var object = {
    pants: true,
    house: true,
    hair: {}
};

function modifyObject(obj) {
    obj.pants = true;
    obj.house = true;
    obj.hair = true;
}

如果您想修改任意数量的参数,请记住,如果您传入 true/false,您就是在复制这些值。因此,如果您在函数内部更改它们,您将不会修改原始值。

记住这一点的一种快速方法是,如果您曾经传递一个对象或数组,那么您就是在修改实际的对象。其他任何事情,您都在修改副本。

编辑

所以从字面上解释你想要做什么,你可以这样写:

var a = true,
    b = true;

/* pass in variable names */
function makeFalse() {
   var i, len;

   for (i = 0, len = arguments.length; i < len; ++i) {
     window[arguments[i]] = false;
   }
 }

 makeFalse("a", "b");

但我想不出这样做的充分理由:-)。我会使用配置对象来存储标志和状态变量,而不是全局变量。

于 2012-05-11T02:12:32.670 回答
1

不幸的是,这不是直接可能的。

Javascript 是一种按值传递的语言,在对象类型的情况下,它是按值传递的引用(至少我看到它是这样引用的)

JavaScript 是按引用传递还是按值传递语言?

对此进行了深入研究,尤其是https://stackoverflow.com/a/3638034/1093982有一个很好的答案。

这是一个 jsfiddle,演示了上述答案中的示例:

http://jsfiddle.net/hjPHJ/

请注意分配给参数的任何内容如何包含在上述范围内。

于 2012-05-11T02:06:43.553 回答
0

你可以尝试 JavaScript 的 typeof() 函数,它应该返回“object”,然后在你的代码中以不同的方式对待它。至于更改对象的值,我认为您实际上想更改属性的值,但我不确定我是否足够了解您的问题。

要更改对象属性,您可以执行以下操作。

hair.color = 'red';

如果要取消设置对象,可以执行此操作。

delete window.some_var; 
于 2012-05-11T02:11:17.673 回答
0

Javascript 按值将每个参数作为引用传递,因此当您更改传入引用的值时,它会修改复制的值。

然而,它确实有其他非常强大的东西,那就是关闭。在您的示例中,onFire已经可以通过闭包范围访问 、 和 ,并且可以直接修改pants它们househair

于 2012-05-11T02:13:11.627 回答
0

当您在 javascript 中调用函数时,您传递的是值而不是对原始对象的引用。有几种方法可以做你想做的事,但不能直接通过传递每个值来更改函数。

首先你可以传递一个数组:

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

arr = [true, true, {}];
onFire(arr); // arr[0] through arr[2] are now false

另一种方法是传递一个可以修改其属性的对象,您只是不能更改作为参数传递的变量的值:

function onFire(obj) {
    obj.pants = false;
    obj.house = false;
    obj.hair = false;
}

onFire( { pants: true, house: true, hair: { } } );
// obj.pants, obj.house and obj.hair are now false

这些都不能满足您的要求,但是如果我知道这样做的原因,可能会有更好的方法...

于 2012-05-11T02:20:22.170 回答