I have been going through Javascript Koans when I hit upon the part about inheritance. I became deeply fascinated and spent the entire morning researching how inheritance works in JS.
I understand that a function can be used to execute code which is declared in its code body, and a function can also serve the purpose as a constructor for objects which inherent from that functions prototype object.
It seems as though functions have two purposes that are not at all related- the ability to create objects , and the ability to execute it's declared code . Is there any relationship between these two abilities?
An attempt at a simple answer (with some approximations to try and keep it simple)
You could see a "class" function both as the constructor of the underlying object and the place where its methods are defined.
The new
operator will create an empty object whose type will reference the function and bind it to this
, then call the function.
The function may set some properties of this
, which will become values for the new instance properties.
In JavaScript almost everything, notably functions, can have properties. Among these, the conventionally named prototype
property is the container of all class methods (and possibly other property values).
function Guy (name) { this.name = name; }
Guy.prototype = {
sayHello: function () { console.log ("Hello, I'm "+this.name; }
}
the Guy
method sayHello
is literally the property Guy.prototype.sayHello
, which happens to be a function.
You could just as well add values instead of functions to the prototype
property, which would act as class variables (of sorts).
So let's create an object Bob
from the function/class Guy
:
var Bob = new Guy("Bob");
Bob.sayHello();
when you invoke Bob.sayHello()
, the virtual machine will first look for a Bob.sayHello
property (which usually does not exist), then for a Guy.prototype.sayHello
(and would go up the inheritance chain or die trying, but that's another subject), then bind this
to Bob
and call Guy.prototype.sayHello
, which will be able to access the Bob
instance through this
.
As an illustration of the mechanism, you can break the prototype chain for a given object instance:
Bob.sayHello = function () { console.log ("my real name is Robert"); }
The duality you're describing doesn't in fact exist. Functions exist to be executed. But, in JavaScript, functions are also objects, so they can have properties such as prototype
. (You can add other properties to your function and use them from its body as a means of making it "stateful".) From the function's point of view, prototype
is just another ordinary property.
Object construction is the domain of the new
operator. What it does, is this:
prototype
whenever a property doesn't exist on the object itself, this
points to it during that function's execution), and undefined
) or the return value of the provided function. (The {}
notation for creating objects is just a shortcut for new Object()
.)
Additional note on prototypal inheritance (that is used in JavaScript): The second step in the above sequence has an important result. Any object in JavaScript has a constructor ( {}
has Object
as constructor), so setting an object as the value of prototype
property of your function doesn't just create a single binding. It transitively creates a "prototype chain". Any property is then looked up first on the object, then on its constructor's prototype, then on it's constructor's prototype's constructor's prototype, etc.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.