3

I created a simple class as follows:

var Class = function() {};
Class.prototype.testObj = {a:2, b:3};

Now if I do console.log(Class.testObj) I get undefined. But if i create instance of that Class as follows:

var instance = new Class();
console.log(instance.testObj)

I get expected output.

In my understanding, all variables are treated as Objects and have prototype property. When some key is not found in the object, prototype chain is traversed to look for the key-value pair. But in case of Class, it is not traversing the prototype chain.

What am I missing? What additional does new keyword do such that property is accessible?

jsist
  • 5,223
  • 3
  • 28
  • 43
  • 1
    `Class.prototype` isn't part of the `Class` object's prototype chain. It's in the prototype chain of any objects created using `new Class()`. – JLRishe Aug 18 '14 at 12:49
  • So far I understand that setting prototype property of constructor function do not set those properties in prototype chain of that function. Is there any way to set properties in prototype chain explicitly? – jsist Aug 19 '14 at 08:16
  • `Class`' prototype chain consists of `Function.prototype` and `Object.prototype`, so you would need to modify one of those. I recommend against doing so unless you have a really good reason for it. Some JS engines will allow you to access `Class.__proto__` which is the prototype that `Class` inherits from, but this is not part of the ES spec and is also discouraged. – JLRishe Aug 21 '14 at 06:16

5 Answers5

2
  1. You must be clear that Class() is your constructor, not an instance object. so Class.testObject will return undefined because Class doesn't have that property.

  2. You can think of a prototype as a recipe for an object. Almost every function has a prototype property that is used during the creation of new instances and that prototype is shared among all of the object instances

  3. A constructor is simply a function that is used with new to create an object

  4. When you do this var instance = new Class(); It means you are creating an instance object of Class, hence instance will inherit prototype properties of Class.

  5. Test:

    console.log(instance instanceof Class); // => true
    
    console.log(instance.constructor === Class); // => true
    
    console.log(Object.prototype.isPrototypeOf(Class)); // => true
    
    console.log(Class.prototype.isPrototypeOf(instance)); // => true
    
babygau
  • 1,551
  • 18
  • 27
1

Whenever you create an object, such as a function, it inherits from the Object constructor, so this

var Class = function() {};

is an object, and it has it's own prototype property that can be accessed with

Class.prototype

and you can create new properties on the prototype object with

Class.prototype.testObj = {a:2, b:3};

if you wanted to access that, you would actually have to do

console.log(Class.prototype.testObj)

as that's where it is, a property added to the prototype property of Class.

When you use the new keyword some magic happens, a whole new object is created (called an instance), and that object inherits from Class.prototype, from the docs

When the code new Class(...) is executed, the following things happen:

  1. A new object is created, inheriting from Class.prototype.

  2. The constructor function Class is called with the specified arguments and this bound to the newly created object. new Class is equivalent to new Class(), i.e. if no argument list is specified, Class is called without arguments.

  3. The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)

adeneo
  • 312,895
  • 29
  • 395
  • 388
1

You have misunderstood the relationship between Class and Class.prototype.

Class is a constructor. Strictly speaking, JavaScript does not differentiate between constructors and general purpose functions, but that's not important right now. Class.prototype is the prototype of instances of Class. That is to say, when you instantiate the class - var x = new Class() - Class.prototype is attached to x as a delegate object.

What this means is that lookups to x will propagate up the delegate chain, and reference variables on that prototype instance.

In my understanding, all variables are treated as Objects and have prototype property.

This is incorrect. JavaScript has many primitive types, and only functions have a property named 'prototype'. Prototypical delegates are only attached to reference types (objects, arrays, and functions) when they are created using new with a constructor or the ECMAScript 5 object.create() notation.

Incidentally, Class does have a prototype delegate, as it's an instance of Function(). One instance of a delegate function method is apply().

Jimmy Breck-McKye
  • 2,923
  • 1
  • 22
  • 32
1

Simply put, Class is not an instance of Class, it's an instance of Function, so why would it inherit Class.prototype? The first link in Class's prototype chain is Function.prototype.

We can see that if we pick a function from Function.prototype, such as call, it exists on Class.

typeof Class.call; //function

Object instances have their prototype chain setup with their constructor's prototype. Therefore, nnly objects that are instances of Class will have their prototype chain setup with Class.prototype.

plalx
  • 42,889
  • 6
  • 74
  • 90
0

You added the object to the prototype,
If you did console.log(Class.prototype), you would see the object.

The new keyword instantiates the object, which brings out properties attached to its prototype as properties of the instantiated object.
Because the newly instantiated object is actually inheriting the prototype of the parent object, not the parent object itself.

ekhaled
  • 2,930
  • 20
  • 24