UP | HOME

Confused Constructor Javascript

1. Introduction

I can not quite remember what happened when invoking new over a function. While I’m looking at function init at jQuery source, the concern comes to me again.

Fortunately I think the answer at this1 thread turns out to be a quite clear explanation.

Just three things according to that answer.

  1. Creates a new object. Its type is object.
  2. Sets this new object’s internal, inaccessible, [[prototype]] property to be the constructor function’s external, accessible, prototype object. Refer to line 11 at sample.
  3. Executes the constructor function, using the new object whenever this is mentioned.

Regarding #2, we might have question like

  1. What is constructor function’s prototype object?
  2. What is the [[prototype]]?

The answer are

  1. Function’s prototype property is automatically created which in turn has a constructor property pointing back to the function. Refer to line 4 at sample.
  2. Basically [[prototype]] is used for prototype chain. Find details at here2 and Ecma-2623.

Therefore if we change the prototype property of the function before new, the [[prototype]] of instances afterwards is vary accordingly. Refer to line 19 at sample.

2. Sample

  • Tested at google chrome 18 and pay close attention to comments.
 1: 
 2:   var fn1 = function () { this.name = "fn1"; }
 3: 
 4:   fn1.prototype          // Object { constructor: function () { this.name = "fn1"; }
 5:                          //        , __proto__: Object }
 6: 
 7:   fn1.__proto__          // function Empty() {}
 8: 
 9: 
10:   var x1 = new fn1();
11:   x1.__proto__ === fn1.prototype  // True
12: 
13:   x1.__proto__           // Object { constructor: function () { this.name = "fn1"; }
14:                          //        , __proto__: Object }
15:   x1.constructor         // function () { this.name = "fn1"; }
16: 
17: 
18:   fn1.prototype = {'location': 'sea'}
19: 
20:   var y1 = new fn1();
21:   x1.__proto__ === fn1.prototype  // True
22: 
23:   y1.__proto__;          // Object { location: "sea"
24:                          //        ,__proto__: Object }
25:   y1.constructor;        // function Object() { [native code] }
  • Quiz: Why y1.constructor is not same as x1.constructor?

3. JQuery.fn.init

  • jQuery is declared as
  var jQuery = function( selector, context ) {
          // The jQuery object is actually just the init constructor 'enhanced'
          return new jQuery.fn.init( selector, context, rootjQuery );
      },
  • jQuery.fn is just a object as
  jQuery.fn = {
      constructor: jQuery,
      init: function( selector, context, rootjQuery ) {
              var match, elem, ret, doc;
              ... ...
            },
      ... ... // many API declaration.
  }
  • Function chain

Since jQuery is just a function, we are able to do with a selector like jQuery('div.navigator').addClass('nav').

Actually in order to use jQuery API like addClass, there must exists following something which of course can be found at around line 322 of jQuery.1.7.1.css4.

  jQuery.fn.init.prototype = jQuery.fn;

Footnotes: