简体   繁体   中英

Is there any relationship between a functions code body and it's prototype?

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.

Construction

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.

Methods

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:

  1. it creates an empty object,
  2. it creates a hidden, non-modifiable binding between the created object and its constructor, which is then used to look-up a property value on its prototype whenever a property doesn't exist on the object itself,
  3. it executes the provided function in context of that object ( this points to it during that function's execution), and
  4. it returns either the created object (if the provided function returned 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM