You should add this line Element.call(this, n) into Select. It's quite hard to explain and I feel grumpy because I don't like fake private properties in javascript, but well, I must provide some details in order for you to understand what you are currently doing, otherwise I will not be able to get to sleep.
So, doing new Element() creates a new context where name can live without disturbing anyone. Additionally, two new functions called setName and getName are created, and bound to the prototype object of Select.
From now on, if you create a new instance of Select, you can call these functions since they are available in the prototype of the instance. This actually happens doing new Select("element1"). Indeed, n is defined, so, setName is called from this, which refers to the instance.
But most importantly, calling setName with n set to "element1" will also set name to "element1". Then, if you create a second instance of Select, without defining n, setName is not called, so, name remains set to "element1", for both instances.
Why for both instances? Because both instances share the same setName method, the one bound to the prototype, and this method refers to a unique name variable - remember that Element was called only once.
Finally, why this new line Element.call(this, n) prevents name from being shared? Because each call to Element creates a new context, that is to say, a new name, a new setName and a new getName, and binds these two methods to the newly created instance.
Well, hope this is the morning for you, I would be sorry if you get into sleeping disorders by my fault...
As mentionned by Bergi and HMR, this way of creating the prototype - Child.prototype = new Parent - is out of fashion and will lead you to a dead end. Keep in mind that the prototype is kind of a template for creating instances. Knowing this and considering your code, we can make at least two observations :
- As you know, a constructor is intended to initialize instances. In your case, the initialization process - what's inside
Element - is unnecessarily executed since the goal is currently to set the template upon which instances will be created.
- Let's say that
name is required in new Element(name), otherwise your program crashes. What kind of name would you give to the prototype? This question is obviously useless, since you would not want to give a name to a template.
To bypass these problems you need a middleman as shown in the below code (copied from the link shared by Bergi). As you can see, the creation of the prototype is delegated to a "dummy" constructor which is empty. Doing so allows to resolve the two problems raised above.
function Dummy () {}
Dummy.prototype = Element.prototype;
Select.prototype = new Dummy();
Select.prototype.constructor = Select;
Alternatively, you could use the built-in Object.create() :
Select.prototype = Object.create(Element.prototype);
Select.prototype.constructor = Select;
Further reading :