Question

I am learning about JS Prototype.

If I set a prototype of a constructor(A) from an instance of some other constructor(B), Is that instance (of B) would introduced shared properties in A?

Example 1

function A(){ 
    var private = '';

    this.getPrivate = function(){ 
        return private
    }; 

    this.setPrivate = function(_private){ 
        private = _private; 
    }; 
}

function B(){};

B.prototype = new A();

b1 = new B();
b2 = new B();

b1.setPrivate(new Date());
b2.getPrivate(); // Here `private` is behaving as singleton property. Why?

Example 2

function A(){ 
    var private = '';
}

A.prototype.getPrivate = function(){ 
    return this.private
}; 

A.prototype.setPrivate = function(_private){ 
    this.private = _private; 
}; 

function B(){};

B.prototype = new A();

b1 = new B();
b2 = new B();

b1.setPrivate(new Date());
b2.getPrivate(); // This time private is not singleton property.

I discovered this new aspect of prototype while playing with it.

  • In example 1, why private property is shared among different instances of B?
  • In example 2, why private property has independent presence in both instances? However original property is unchanged but the getter/setter are defined via prototype.
  • Can example 1 be considered an implementation of singleton properties?
  • Prototyping via instance and prototyping via prototype, What are the difference? e.g.
    B.prototype = new A();
    B.prototype = (new A()).constructor.prototype
  • What are the complete secrets of prototyping?
Was it helpful?

Solution

  1. Because you are inheriting a specific instance locked down to specific closures. The data is owned by the closures and not the object. There is a huge difference between variables and properties of object.

  2. The var private is not used here at all. When you setPrivate() the property is created at that point.

  3. No it's just accidental because of misunderstanding between closures and object model. You can do the same in a much more deliberate and clearer way: by using a simple object literal.

  4. The difference is that in first one you get a new object, where as in second one you have A.prototype === B.prototype so modifying one will modify the other since they reference the same object.

  5. Objects inherit from other objects

Here's a good resource https://developer.mozilla.org/en/JavaScript/Guide/Details_of_the_Object_Model

OTHER TIPS

The secret of prototyping (which explains all of this) is that every instance of B shares the same prototype, i.e. prototype is not copied to new instances of B. When you fire a prototype function of any instance of B, you are actually running the same function all the time. That's why "private" variable is copied (actually it is not copied, you are just referencing the same variable all the time). "Nonprivate" variables behave the same, with the exception that the keyword this refers to the current "holder" of the function. That's why calling this in prototype gives us an illusion of prototype method being actually a method of an object. It is not.

Prototyping via instances is considered bad practice, because instances may have more or less properties depending on when they are called and when you are prototyping. Prototypes are mostly defined via literal object creation or extending prototypes of other objects.

And finally: in some sence prototyping may be interpreted as singleton.

In example 1, why private property is shared among different instances of B?

Yes they do

In example 2, why private property has independent presence in both instances? However original property is unchanged but the getter/setter are defined via prototype.

Because each instance is independent of others. If that's not what you want use object literal notation to create your class.

Can example 1 be considered an implementation of singleton properties?

No because singleton always returns the same object instance. This relates to your second question where each instance is independent. One can create many instances of that class from your first example. To create singleton, there exists singleton or module pattern which uses self-invoking function with grouping operator eg wrapping function in ().

Prototyping via instance and prototyping via prototype, What are the difference? e.g.

With constructor, you make sure that there is no confusion between your child class constructor and parent class. It is same concept when extending parent class, in child class you construct parent class in child class's constructor function.

What are the complete secrets of prototyping?

Going through good articles on various JS Ninja blogs. I love:

Here is good article:

In Example 1, you are using closure scope to refer to an private. Since A is only instantiated once, one instance of it is defined.

In Example 2, this.private does not refer to the instance of private in function A. In fact, since you use the word "this" it refers to the "this" of the object. Therefore, this.private either means b1.private or b2.private depending on the function. In Example 2, the private defined in Function A is lost to the closure scope and it's as if it was never defined.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top