Javascript Mutable Parameter?

4.3k views Asked by At

This is just a technical question about javascript. In javascript, one member of my group found something odd with javascript object creation. For some reason, the parameters in the object are already treated as members without assigning them to any member variables created in the constructor of the object. The parameters are mutable also as seen in the code block below.

Here's the code to show the testing we have being doing.

function NamedItem(name)
{
    name = 5;

    this.getName = function ()
    {
        return name;
    }
}


document.write(namedItem.getName() + "\n");  //5

Is this legitimate? Is it dangerous?

2

There are 2 answers

4
SLaks On BEST ANSWER

That's called a closure.
Nested functions can access variables from their parent function and extend the variables' lifetimes beyond the execution of the parent function.

It has nothing to do with objects.

0
Jamund Ferguson On

Just to be clear there are some potentially silly things about what you're doing. Let me explain a few principles.

  1. If you declare a variable or variables as arguments to a function such as function(arg1, arg2), in terms of the variables themselves (and not their values) it is essentially the same as saying at the top of your function var arg1; var arg2;. The are declared for you automatically. Even if you try and redeclare them, they'll still work with the passed in arguments!

  2. Functions are objects. Objects can have properties. Therefore functions can have properties, such as this.getName = function().

  3. Like the @SLaks pointed out you're creating a closure in your version of the getName method. A closure captures the state of things above it when it's created. Therefore if there is a name variable in its scope when it's created, it will have access to that name variable in it's scope. It's a very normal practice in JavaScript and you've managed to create a private property (name) with a public accessor function (getName). Well done.

  4. I assume you're using creating instances of NamedItem with the new keyword like this. var item = new NamedItem("javascripter"). Another way (and one that uses less memory than what you are doing is to add the getName() function to the prototype for NamedItem like I show below. The drawback to the prototype approach is that you could just as easily access _name directly. There are no private properties in the traditional sense in JavaScript, but some people use the underscore prefix to indicate to people that they're private and not to use them. This approach (prototypes) use less memory than your approach because if you create multiple instances of NamedItem they all share a single prototype.

Using the prototypes instead:

function NamedItem(name) {
    this._name = name
}

NamedItem.prototype.getName = function() {
    return this._name
}

Hope that gives you some things to think about!

J