inheritance - JavaScript: Object inheriting from Function.prototype -
i testing out james shore's object playground, , see methods inherit function.prototype, including methods on global object.prototype. how work? isn't kinda circular? mean... doesn't function.prototype "itself" inherent object.prototype? how object inherent function.prototype? isn't function sub-type of object? shouldn't object inherently contain these behaviors anyway? why need inheritance?
tl;dr
object.prototype last in prototype chain , doesn't inherit anything. object constructor 1 inherits function.prototype because it's function; it's function instance.
long version
since question general one, i'll try describe few subjects , answer own question. here subjects i'll try cover:
- two ways use word "prototype".
- how classes created in javascript.
- how function & object constructors relate.
note: can hard , @ times confusing explain how javascript works. hope you'll out of though.
two ways use word "prototype"
the word "prototype" can little confusing in javascript. that's because there @ least 2 ways use word depending on context:
1) "the prototype object of object"
the prototype object of object talked "internal prototype", denoted [[prototype]], or __proto__
; mean same thing. example let's take array: nums = [9, 8, 7];
. nums
array... why?
- we it's array because instance of
array
constructor (constructors functions, except use them new keyword). - we it's array because its prototype object (a.k.a. "internal prototype") object contained inside of
array.prototype
property.
2) "the prototype property of constructor function"
continuing nums
array example, array constructor function has property named prototype
, , can access this: array.prototype
. property "internal prototype" of array instances, , provides methods we're used calling on arrays - e.g. foreach
, push
, pop
, join
, , on.
so, along same lines, internal prototype of function foo()
, or other function, object that's contained inside of function.prototype
property; in other words, function.prototype
function's "internal prototype" object. also, can function constructor has prototype property, "internal prototype" of functions.
where i'm getting @ speak of 1 thing (the prototype) in 2 different ways. in first way say: "the prototype/internal prototype" of object, , in second way say: "the constructor's prototype" property.
how classes created in javascript
in javascript constructor functions classes in other programming languages. well, not quite. actually, resemble classes, javascript uses combination of constructor function , object called prototype. every javascript function acquires prototype property automatically because function can used constructor or function. when function isn't used constructor, prototype property isn't used , it's dangling there useless property.
in classical languages, class contains both instance variables , instance methods, in javascript, constructor function contains instance variables , prototype object contains instance methods.
instance variables unique particular instance of constructor function (they contain instance specific data), , instance methods shared instances. in other words, instances can execute instance methods cannot access variables of each other.
so, objects in javascript instances of respective constructor functions. example, array such [1,2,3]
instance of function array() {}
constructor. objects such {key: 'value'}
instances of function object() {}
constructor. javascript functions such alert()
instances of function function() {}
constructor... , on.
again, constructor functions in javascript have prototype
property, , property includes methods instances of constructor inherit.
example:
// person constructor create people instances function person(name, age) { // every instance has own "instance variables", a.k.a. properties. this.name = name; this.age = age; } // "instance methods" person.prototype = { greet: function() { return 'hello ' + this.name; }, //... }; // joe instance of `person` constructor, , joe's "prototype" // `person.prototype` object. call joe's "prototype" // "internal prototype". var joe = new person('joe doe', 44); joe.name; //=> joe doe joe.greet(); //=> hello joe doe
how function & object constructors relate
the object
constructor.
the object constructor person constructor above, except creates object instances instead of person instances.
the function
constructor.
the function constructor person & object constructors above, except creates function instances, in other words creates functions.
all constructors in javascript person
, object
, array
, function
, string
, boolean
, , on, functions. since functions, means created new function
internally in language, , function methods call()
, apply()
come function.prototype. in other words, function.prototype "prototype/internal prototype" object of functions, including constructors , function function
itself.
conclusion:
don't confuse constructor's prototype
property, includes methods future instances use, internal prototype of constructor itself.
however, keep in mind constructor's prototype
property internal [[prototype]] of constructor's instances. example, function.prototype
internal [[prototype]] object
constructor, , makes sense since object
constructor function (a function
instance).
for code conclusion take @ how object & function constructors created internally in javascript:
// object constructor // ============================================== function object() { /* ... */ } // object.keys() // object.observe() // ... // `object.__proto__` (internal [[prototype]]) // ----------------------------------------------- // since `object` function, inherits of function's // instance methods (the ones inside of function.prototype). // // in other words `object` constructor can use methods // `apply()`, `call()`, `bind()`, , more. // // can object's prototype // `function.prototype` object. object.__proto__ = function.prototype; // `object.prototype` (instance methods) // ----------------------------------------------- // object's `prototype` property totally different // `__proto__` property. `prototype` property includes // methods javascript objects inherit. object // literal `var obj = {}` or array `var arr = []` // or function `alert` can use these methods. object.prototype = { constructor: object, hasownproperty: function() {}, isprototypeof: function() {}, //... }; // function constructor // ============================================== function function() { /* ... */ } // function.call() // function.apply() // ... // [[prototype]] + instance methods // ----------------------------------------------- // since `function` function , @ same time // constructor other javascript functions, internal // [[prototype]] , `prototype` property point same // exact object. function.__proto__ = function.prototype = { apply: function() {}, call: function() {}, bind: function() {}, //... // object literal, inherits // object's instance methods. __proto__: object.prototype };
further resources
- https://developer.mozilla.org/en-us/docs/web/javascript/guide/details_of_the_object_model#determining_instance_relationships
- https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/object/prototype
- https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/object/proto
- https://es5.github.io/#x15.3.4
- http://people.mozilla.org/~jorendorff/es5.1-final.html#sec-15.3.2.1; a prototype property automatically created every function, provide possibility function used constructor.
- https://www.quora.com/in-javascript-what-is-the-logic-behind-the-data-structure-of-function-prototype-proto-and-constructor?share=1