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 :