Clarification on FunctionTemplate / Function / PrototypeTemplate

59 views
Skip to first unread message

Ron Prestenback

unread,
Jan 14, 2021, 3:42:40 PM1/14/21
to v8-users
Hello everyone,

I've read a lot of information about FunctionTemplate / Function / PrototypeTemplate / InstanceTemplate, but some details are still not clicking for me.  I feel like maybe there is a gap in the documentation that I hope the answers to these questions can help fill:

(FWIW, I'm creating a two-way association between C++ and javascript objects)

  1. The documentation for FunctionTemplate.PrototypeTemplate says it's the "template used to create the prototype object of the function created by this template".  But what is the role of a "prototype object" for a function?  I understand the concept of a "prototype" for an object, but not a function.  From what I understand, the new object will already inherit all properties/methods defined on the Function and FunctionTemplate, so what's the prototype object needed for?  And if there's only one prototype object, why do we need a template for it?
  2. What is the difference between a prototype template and an instance template?
  3. What is the difference if I put a property on the FunctionTemplate, the Function, the PrototypeTemplate or the InstanceTemplate?  What should I be taking into account when deciding where to put the property?
  4. Should I use the same logic for functions/methods as well?  Or are there different considerations for functions?
  5. If I have a constructor function that I want to run when the new objects of the class are created, where should that go?
  6. Depending on the answers to the previous 3, this question may be moot, but: Is there any reason to have the same function or property on two or more of these "entities"?  FunctionTemplate and Function?  Or Function and PrototypeTemplate? etc.  For example, I have some existing code that is first setting a property (via Set) on the PrototypeTemplate of the FunctionTemplate, then it also sets that same property (with same value) on the FunctionTemplate.  What might be the intent here?
  7. I've seen code that calls RemovePrototype on the FunctionTemplate (or maybe the Function....I'm not sure).  For what reason would you do this?

Thanks in advance for any help!  :)

Ben Noordhuis

unread,
Jan 14, 2021, 5:25:54 PM1/14/21
to v8-users
Replies inline, hope it's useful to you. I'll assume you're familiar
with prototypical inheritance in JS but let me know if you need more
details.

On Thu, Jan 14, 2021 at 9:42 PM Ron Prestenback
<ronpres...@gmail.com> wrote:
>
> Hello everyone,
>
> I've read a lot of information about FunctionTemplate / Function / PrototypeTemplate / InstanceTemplate, but some details are still not clicking for me. I feel like maybe there is a gap in the documentation that I hope the answers to these questions can help fill:
>
> (FWIW, I'm creating a two-way association between C++ and javascript objects)
>
> The documentation for FunctionTemplate.PrototypeTemplate says it's the "template used to create the prototype object of the function created by this template". But what is the role of a "prototype object" for a function? I understand the concept of a "prototype" for an object, but not a function. From what I understand, the new object will already inherit all properties/methods defined on the Function and FunctionTemplate, so what's the prototype object needed for? And if there's only one prototype object, why do we need a template for it?

- JS functions can be invoked as constructors with the `new` keyword

- Constructors return an object

- The prototype template is used to configure that object's prototype

> What is the difference between a prototype template and an instance template?

It's the difference between `this` and `this.__proto__`, or:

function F() {
this.x = 42;
}
F.prototype.y = 1337;

> What is the difference if I put a property on the FunctionTemplate, the Function, the PrototypeTemplate or the InstanceTemplate? What should I be taking into account when deciding where to put the property?

Setting properties on the first two is like setting properties on the
JS function object:

function f() {}
f.x = 42;

The last two are for construct calls: new F()

> Should I use the same logic for functions/methods as well? Or are there different considerations for functions?

I don't understand the question, I'm afraid.

> If I have a constructor function that I want to run when the new objects of the class are created, where should that go?

FunctionTemplate. Methods are set with FunctionTemplate::PrototypeTemplate().

(Technically you can also set them on the instance template but that's
kind of pointless.)

> Depending on the answers to the previous 3, this question may be moot, but: Is there any reason to have the same function or property on two or more of these "entities"? FunctionTemplate and Function? Or Function and PrototypeTemplate? etc. For example, I have some existing code that is first setting a property (via Set) on the PrototypeTemplate of the FunctionTemplate, then it also sets that same property (with same value) on the FunctionTemplate. What might be the intent here?

Probably to make it available as both a method and a class method:
o.m() and F.m()

> I've seen code that calls RemovePrototype on the FunctionTemplate (or maybe the Function....I'm not sure). For what reason would you do this?

For the same reason you create prototype-less objects with `{
__proto__: null }` or `Object.create(null)` - usually to avoid
prototype pollution / being able to use objects as plain dictionaries.

HTH!

Ron Prestenback

unread,
Jan 14, 2021, 7:48:33 PM1/14/21
to v8-users
Hi Ben, thanks for the reply!  I have worked with C++ for many years but this is my first exposure to javascript.  I'm using the web editor for replying to this, so apologies if the formatting gets messed up :)  I'll try to do inline quotes as well but not sure how that will turn out, so I'll try to space them out to help readability.

I have read over the doc on prototypal inheritance here: https://javascript.info/prototype-inheritance and https://javascript.info/function-prototype  I assume that covers all the important stuff?

- Constructors return an object 
- The prototype template is used to configure that object's prototype 

Why wouldn't the object's prototype be the instance template?  The object returned by the constructor is an instance, right?  And the object's prototype would the "template" the instance was configured from, no?   I'm starting to suspect that "prototype" and "template" have completely different meanings in v8, whereas in standard usage these terms are synonyms.  This is where I get confused, I guess....



> What is the difference between a prototype template and an instance template? 
It's the difference between `this` and `this.__proto__`, or: 
  function F() { 
    this.x = 42; 
  } 
  F.prototype.y = 1337; 
 
Sorry I'm really trying but I'm not sure how to apply your answer to my question.  In your example, F.prototype would be the same as the __proto__ object for all instances of 'F', right?  If I'm understanding correctly (which is doubtful), in v8 parlance that makes F.prototype the instance template of F, right? If not, which thing is the instance template? 



> If I have a constructor function that I want to run when the new objects of the class are created, where should that go? 
FunctionTemplate. Methods are set with FunctionTemplate::PrototypeTemplate(). 
(Technically you can also set them on the instance template but that's 
kind of pointless.) 

Oh, why would it be pointless to set a method on an InstanceTemplate?



> Depending on the answers to the previous 3, this question may be moot, but: Is there any reason to have the same function or property on two or more of these "entities"?  FunctionTemplate and Function?  Or Function and PrototypeTemplate? etc.  For example, I have some existing code that is first setting a property (via Set) on the PrototypeTemplate of the FunctionTemplate, then it also sets that same property (with same value) on the FunctionTemplate.  What might be the intent here? 
Probably to make it available as both a method and a class method: 
o.m() and F.m() 

OK, that makes sense.  What would the difference be if I set that property on the InstanceTemplate instead?  Or to put another way, why would I ever set something on an InstanceTemplate instead of a PrototypeTemplate?

Ben Noordhuis

unread,
Jan 15, 2021, 6:23:04 AM1/15/21
to v8-users
On Fri, Jan 15, 2021 at 1:48 AM Ron Prestenback
<ronpres...@gmail.com> wrote:
>
> Hi Ben, thanks for the reply! I have worked with C++ for many years but this is my first exposure to javascript. I'm using the web editor for replying to this, so apologies if the formatting gets messed up :) I'll try to do inline quotes as well but not sure how that will turn out, so I'll try to space them out to help readability.
>
> I have read over the doc on prototypal inheritance here: https://javascript.info/prototype-inheritance and https://javascript.info/function-prototype I assume that covers all the important stuff?
>
>> - Constructors return an object
>> - The prototype template is used to configure that object's prototype
>
>
> Why wouldn't the object's prototype be the instance template? The object returned by the constructor is an instance, right? And the object's prototype would the "template" the instance was configured from, no? I'm starting to suspect that "prototype" and "template" have completely different meanings in v8, whereas in standard usage these terms are synonyms. This is where I get confused, I guess....

"Prototype" has a very specific meaning in JS - it's the chain of
objects that are searched to resolve properties that don't exist in
the instance.

Example: var x = o.x;

If o looks like { x: 42 }, then o.x is an instance property, but
otherwise the prototype of o is searched, then the prototoype of the
prototype, and so on. To illustrate:

var A = { x: 42 };
var B = { __proto__: A };
var o = { __proto__: B, y: 1337 };
var x = o.x; // Searches the chain until it finds A.x
var y = o.y; // But this lives in the instance

"Template" is just V8 parlance. The template describes the "shape" of
the prototype or instance object.

One way to think about templates is that they're an optimization that
lets V8 allocate the needed space for an object (or prototype)
upfront.

>
>> > What is the difference between a prototype template and an instance template?
>> It's the difference between `this` and `this.__proto__`, or:
>> function F() {
>> this.x = 42;
>> }
>> F.prototype.y = 1337;
>
>
> Sorry I'm really trying but I'm not sure how to apply your answer to my question. In your example, F.prototype would be the same as the __proto__ object for all instances of 'F', right?

Correct.

> If I'm understanding correctly (which is doubtful), in v8 parlance that makes F.prototype the instance template of F, right? If not, which thing is the instance template?

The body of F (the line that sets `this.x = 42`) corresponds with the
instance template.

>> > If I have a constructor function that I want to run when the new objects of the class are created, where should that go?
>> FunctionTemplate. Methods are set with FunctionTemplate::PrototypeTemplate().
>> (Technically you can also set them on the instance template but that's
>> kind of pointless.)
>
>
> Oh, why would it be pointless to set a method on an InstanceTemplate?

Because you use the InstanceTemplate for values that are likely
different between different instances of the same class (think: a
Point class with x and y coordinates).

Methods on the other hand don't normally change so those belong on the
prototype.

>> > Depending on the answers to the previous 3, this question may be moot, but: Is there any reason to have the same function or property on two or more of these "entities"? FunctionTemplate and Function? Or Function and PrototypeTemplate? etc. For example, I have some existing code that is first setting a property (via Set) on the PrototypeTemplate of the FunctionTemplate, then it also sets that same property (with same value) on the FunctionTemplate. What might be the intent here?
>> Probably to make it available as both a method and a class method:
>> o.m() and F.m()
>
>
> OK, that makes sense. What would the difference be if I set that property on the InstanceTemplate instead? Or to put another way, why would I ever set something on an InstanceTemplate instead of a PrototypeTemplate?

See above. :-)

Ron Prestenback

unread,
Jan 22, 2021, 7:37:11 PM1/22/21
to v8-users
Hi Ben,

Thanks for the help.  I wanted to give it a week to soak in before I replied again  :) 


The final piece clicked into place when I realized (for the second time, since I definitely learned this then forgot, heh) was that FunctionTemplate is per-isolate, but a Function is per-context.  Whatever I add to a FunctionTemplate will exist in all contexts (because FunctionTemplate is per-isolate), while whatever I add to a Function returned from FunctionTemplate::GetFunction will only exist in the context I specified in the call to GetFunction (or whichever context is the current one in the isolate).
Reply all
Reply to author
Forward
0 new messages