You seem to be mixing the prototype
property of functions with the internal [[proto]]
property of all objects (including functions). They are two distinct things.
Mutating the internal [[proto]]
property of an object is discouraged. This can be done either via setPrototypeOf
or via the __proto__
accessor, which is inherited from Object.prototype
:
var a = {}; // `a` inherits directly from `Object.prototype`
var b = {}; // `b` inherits directly from `Object.prototype`
a.__proto__ = b; // `a` now inherits directly from `b`
// or
Object.setPrototypeOf(a, b); // `a` now inherits directly from `b`
This is what is discouraged, mutating the internal [[proto]]
property of an object after it has been created. However, it should be noted that while the object is being created it's alright to assign any object as its internal [[proto]]
property.
For example, many JavaScript programmers wish to create functions which inherit from some object other than Function.prototype
. This is currently only possible by mutating the internal [[proto]]
property of a function after it has been created. However, in ES6 you will be able to assign the internal [[proto]]
property of an object when it is created (thus avoiding the problem of mutating the internal [[proto]]
property of the object).
For example, consider this bad code:
var callbackFunctionPrototype = {
describe: function () {
alert("This is a callback.");
}
};
var callback = function () {
alert("Hello World!");
};
callback.__proto__ = callbackFunctionPrototype; // mutating [[proto]]
callback.describe();
It can be rewritten in ES6 as follows:
var callbackFunctionPrototype = {
describe: function () {
alert("This is a callback.");
}
};
// assigning [[proto]] at the time of creation, no mutation
var callback = callbackFunctionPrototype <| function () {
alert("Hello World!");
};
callback.describe();
So, mutating the internal [[proto]]
property of an object (using either setPrototypeOf
or the __proto__
accessor) is bad. However, modifying the prototype
property of a function is fine.
The prototype
property of a function (let's call the function F
) only affects the objects created by new F
. For example:
var myPrototype = {
describe: function () {
alert("My own prototype.");
}
};
function F() {}
var a = new F; // inherits from the default `F.prototype`
alert(a.constructor === F); // true - inherited from `F.prototype`
F.prototype = myPrototype; // not mutating the `[[proto]]` of any object
var b = new F; // inherits from the new `F.prototype` (i.e. `myPrototype`)
b.describe();
To know more about inheritance in JavaScript read the answer to the following question:
JavaScript inheritance and the constructor property
Hope that helps.