简体   繁体   中英

Javascript function that takes variable number of arguments - changes their value - and then returns them

I am new to Javascript (and programming in general) and have been searching for a way to change the value of an arbitrary number of aguments using a Javascript function.

The answer here ( JavaScript variable number of arguments to function ) was quite helpful. I was able to use it to create the two of the functions I need, but I'm having trouble with the third.

Basically I would like to pass a variable number of objects (primitive or more complex ) into a function and have the function change the value of each object.

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);

Console outputs:

>pants;
 true

>house;
 true

>hair;
 Object

How can I formulate this function so the the result is:

>pants;
 false

>house;
 false

>hair;
 false

Any help would be greatly appreciated!

Edit:

To clarify things - I am trying to create a reusable helper function that changes the value of any object passed in to false instead of typing:

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

If I use mathec 's method - is it possible to 'parse' object so that it's properties overwrite the global variables of the same name, or am I stuck with typing it out explicitly each time?

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

Console Output:

>pants;
 false

>house;
 false

>hair;
 false 

When you pass variables in JavaScript you're passing a copy of a reference to a value if it's an object, but if it's a primitive (like a true/false) you're copying the actual value. This basically means, if you pass in an object and modify one of the object's properties, you'll be modifying the original object. But if you pass in a primitive like true/false, you'll just be modifying the copy, and not the original value. So if your goal is to modify the original values, one option is to store those values in an object and pass in the object instead. For example:

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

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

If you want to modify an arbitrary number of arguments, just remember that if you're passing in true/false you're copying those values. So if you change them inside the function you won't be modifying the original values.

A quick way to remember this is if you ever pass an object or an array, you're modifying the actual object. Anything else, you're modifying a copy.

Edit

So interpreting what you want to do literally, you could write this:

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");

But I can't think of a good reason to do this :-). I would use configuration objects to store flags and state variables, not global variables.

Unfortunately, this is not directly possible.

Javascript is a pass-by-value language, and in the case of object types, its a pass by value by reference (at least thats how Ive seen it referred to)

Is JavaScript a pass-by-reference or pass-by-value language?

goes pretty in depth to it, and https://stackoverflow.com/a/3638034/1093982 in particular has a great answer.

here is a jsfiddle demonstrating the example in the above answer:

http://jsfiddle.net/hjPHJ/

note how anything assigning to a parameter is not carried into the scope above.

You could try JavaScript's typeof() function, which should return "object", and then treat it differently in your code. As for changing the value of an object, I think you actually want to change the value of a property, but I am not sure I understand your question well enough.

To change an object property, you would do something like this.

hair.color = 'red';

If you want to unset the object, you can do this.

delete window.some_var; 

Javascript passes each argument as a reference by value, so when you change the value of a passed in reference it modifies the copied value.

However it does have something else which is very powerful and thats closure. In your example onFire already has access to pants , house , and hair through the closure scope and can modify them directly.

When you call a function in javascript, you are passing values and not references to the original object. There are a couple of ways that you can do what you want, but not directly by passing each value to change to the function.

First you can pass an array:

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

Another would be to pass an object, whose properties can be modified, you just can't change the value of the variable you pass as an argument:

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

Neither of these accomplishes just what you want, but if I knew the reason for doing what you are asking there might be a better way...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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