David,
Perhaps we will both need a whiskey and discuss it offline. Its a very complicated subject, that's for sure.
What we are trying to do, in Sebastian's example, is to put the functions on the prototype of his Person constructor. We want to do this so that when we create a lot of person objects using the constructor, we are not consuming memory by having a copy of the functions in every object we create. So, in the example we have as follows:
- Code: Select all
// The constructor
function Person (firstName, lastName, title){
this.firstName = firstName;
this.lastName = lastName;
this.title = title;
}
Next we add the functions to the prototype like this:
- Code: Select all
// Adding to the prototype
var Person_proto = function(){
Person.prototype = {
fullName : function(){
return this.firstName + " " + this.lastName;
},
fullNameTitle : function(){
return this.fullName() + ", " + this.title;
}
}
}();
Then we create a new person object using the Person constructor like this:
- Code: Select all
var person = new Person('Some','Buddy','JavaScript Servoy Blogger');
application.output(person.fullNameTitle()); //Some Buddy, JavaScript Servoy Blogger
Now Servoy gives us a JSDoc warning at the application.output() statement; it does not see the method "fullNameTitle()" because it is on the prototype of the Person constructor (no code completion for it either). However, look what we see if we do a breakpoint at this line:
Notice that Person, the constructor, has the prototype with the two functions, and that person, the object we created, does not. This is what we want. When we create 10,000 person objects using the Person constructor, there is only one copy of the two functions in memory, and every person object has access to it. This is classical inheritance and what Sebastian wanted to do in his scenario.
On the other hand, the link (
https://wiki.servoy.com/display/SERV61/Function) to the docs shows something different, I believe.
I can try to re-write the prototype in Sebastian's example using the suggested approach there:
- Code: Select all
function Person_proto(firstName, lastName, title){
this.fullName = function(){
return this.firstName + " " + this.lastName;
};
this.fullNameTitle = function(){
return this.fullName() + ", " + this.title;
};
Person.apply(this, arguments);
}
Person_proto.prototype = new Person();
and then do this:
- Code: Select all
var oPerson2 = new Person_proto('SomeOther','Buddy','JavaScript Servoy Blogger');
application.output(oPerson2.fullNameTitle()); //SomeOther Buddy, JavaScript Servoy Blogger
It looks the same on the surface (I get the same output), but look at what I see if I set a breakpoint again:
<edit> Forgot to mention that this approach works great with code completion and no JSDoc warnings (just like the final approach shown at the end)
Now the functions are on the person object we created and not on the Person constructor. That means you have 10,000 copies of the functions in memory, definitely not what Sebastian wanted. The functions are not on the Person constructor, but rather on the Person_proto. All this approach is doing is prototype chaining; its copying the Person constructor and making a new constructor called Person_proto, augmenting it with two functions, and preserving the prototype chain back to Person. It looks identical to just doing this:
- Code: Select all
function Person (firstName, lastName, title){
this.firstName = firstName;
this.lastName = lastName;
this.title = title;
this.fullName = function(){
return this.firstName + " " + this.lastName;
};
this.fullNameTitle = function(){
return this.fullName() + ", " + this.title;
};
}
Anyway, I still don't know how to get Servoy to see the prototype functions using the classical inheritance approach (first image). Clearly it is there in the Expressions tab, but only when I am running in the client and pause at a breakpoint. I think most editors look for the "prototype" keyword and the resolve it that way.
Again, I think we should probably take this offline. It could be we are misunderstanding each other and really need that drink first.