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.
- Creates a new object. Its type is
object
. - 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. - Executes the constructor function, using the new object whenever
this
is mentioned.
Regarding #2, we might have question like
- What is constructor function’s
prototype
object? - What is the
[[prototype]]
?
The answer are
- 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. - 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;