What are virtual functions in javascript? - javascript

According to one definition of virtual functions:
In object-oriented programming, in languages such as C++, a virtual
function or virtual method is an inheritable and overridable function
or method for which dynamic dispatch is facilitated.
How would this look for functions in javascript?

How would this look for functions in javascript?
The concept largely doesn't apply to JavaScript.
The concept of virtual and non-virtual functions (methods, really) requires the concept of a type of reference to an object, as distinct from what the object is. For instance, you might have a BaseFoo type with a bar method, and a DerivedFoo type that derives from it and overrides bar. Later, if you have a BaseFoo-typed variable b referring to a DerivedFoo object, when you call b.bar(), you'll get DerivedFoo's bar if bar is virtual, but BaseFoo's bar if bar is non-virtual. But if you have a DerivedFoo-typed variable d referring to a DerivedFoo object, d.bar() always calls bar whether it's virtual or not. The type of the variable you're using to refer to the object determines what method gets called if the method is non-virtual.
None of that exists in JavaScript. References to objects are untyped. When you call o.bar(), you get the property bar from that object and call the function it refers to.
If you wanted to stretch a point, given JavaScript's prototypical inheritance mechanism, you could say that in some sense, all JavaScript "methods" are virtual, if we very loosely say a "method" is a function attached to an object property (although in ES2015+, "method" has a more specific meaning in JavaScript than that, but still fits that definition). That's because when you look up a property on an object, if it has its own property with that name, that's the one you get; you only get the one from its prototype if it doesn't have its own. But that's probably stretching a point, perhaps too far.

Related

Is there a way to programmatically determine that a function is actually an object in Javascript?

In Javascript, functions are objects. Yet typeof of a function returns function instead of object for ECMAScript compatibility reasons.
Is this function type actually some kind of wrapper for object that can be determined somehow? Or in Javascript, is a function actually fundamentally different from objects?
I do understand that functions are effectively and practically objects. But are they by definition actually completely separate from Objects in Javascript, or is there a way to programmatically reveal the Object that the Function is made of?
As the spec says:
an object is a member of the built-in type Object; and a function is a callable object
So
Or in Javascript, is a function actually fundamentally different from objects?
Not really, except for the fact that a function is callable - more precisely, that it has a [[Call]] internal method.
Functions inherit from objects in a very similar way that objects inherit from objects. For example, for a given function:
function foo(){}
foo.a = 'a';
There is:
The foo function, which is an object, and has a [[Call]] internal method, as well as an a property, and a few other properties that functions have (like name)
The foo function inherits from Function.prototype
Function.prototype inherits from Object.prototype
Object.prototype inherits from nothing - that's the start of the prototype chain
is there a way to programmatically reveal the Object that the Function is made of?
That's not really how it is - the function itself is an object. If the function object has properties, it'll be visible directly on the function. For example, above, referencing foo.a will give you the string 'a'. The a property isn't separate from the function - it's directly on the function object.

What does binding mean in Javascript?

I'm reading this great book called Eloquent JavaScript but I'm confused by the use of the word "binding" in this example:
It is possible to include symbol properties in object expressions and
classes by using square brackets around the property name. That causes
the property name to be evaluated, much like the square bracket
property access notation, which allows us to refer to a binding that
holds the symbol.
let stringObject = {
[toStringSymbol]() { return "a jute rope"; }
};
console.log(stringObject[toStringSymbol]());
// → a jute rope
As I understand it (so far in my JS journey), "binding" relates to specifying which this or object context in which a function operates. See here.. Binding is perhaps something related to context. That is why we have .bind().
But in this example we are binding something else (a method whose key is a symbol). Does binding just mean attaching a property (primitive or method) to an object?
Does binding just mean attaching a property (primitive or method) to an object?
No
Your previous paragraph provides a better explanation:
"binding" relates to specifying which this or object context
Sort of
Everything tracked by JavaScript is bound. In fact, the definition of undefined means JavaScript cannot find a bound identifier.
Answer
Binding something in JavaScript means recording that identifier in a specific Environment Record. Each Environment Record is related to a specific Execution Context - and that binds the identifier (variable or function name) to the this keyword for that execution context.
Reference
https://www.ecma-international.org/ecma-262/5.1/#sec-10.5
Less Formally
Think of Environment Records as buckets of stuff. These are not Objects or Functions or Variables or anything we code in JavaScript, these buckets contain all these things. There are many buckets in a JavaScript application. Each bucket operates independently from the other buckets. That independence is represented as a Context (or Execution Context) in JavaScript. But sometimes we want to use stuff from one bucket inside a different bucket. That is where binding comes in. We can bind stuff from one bucket into the context of a different bucket for execution there. (A side effect of doing all that is the this keyword reflects the bucket borrowing the stuff).
A binding in JavaScript is the formal terminology for what a lot of people refer to as a variable. In ES2015+, a variable can be defined with the let keyword, but you can also define constant with the const keyword. A binding could refer to either a variable or a constant.
Reference: See chapter 2, page 1 of Eloquent JavaScript, under the section heading 'Bindings' (https://eloquentjavascript.net/02_program_structure.html)
In this book, they use binding or variable interchangeably. So simply means, a binding is a variable. I guess you started reading a book by skipping the pages, don't do it again. I will write a very simple program to illustrate.
let count = 1;//count is a binding(a variable)
++count;//it's called side effect(because the original value of count binding was modified)

what does function () {} mean when assigned to a variable

I know that functions are objects in javascript, and that functions can be assigned to variables. I am also aware of this question: How does the (function() {})() construct work and why do people use it?.
But I would like to know precisely what does it mean in this context:
https://github.com/zsolt/retwis-nodejs/blob/master/domain.js#L43
User = function(){}
This line is followed by the declaration of some member functions (methods?) of the "supposed" User object.
It seems there is no other explanation answer here in SO.
It means User is a function that takes no inputs, has no side effects and returns nothing.
Most likely it is a class constructor and methods will be added to it later. User.foo = function() { /* ... */} would imply a static method, so this is more like a utilities class if you're used to thinking in Java architecture.
You should look up pseudo-classical inheritance in Javascript. Analogizing to Java, the code would be adding static methods to the User class, not object.
I'm still pretty convinced the code is following Java class patterns because the writer would prefer User to be a constructor that can be instantiated, has static methods, and has no instance methods (that I saw), over an object with properties that are functions. You are right that this is circuitous, but it's what the writer would do if they are a Java developer. It does have the advantage that instance methods may be added to User later with little client-code impact but I see no evidence this will happen to User (I didn't look long).
By the way, I deduced this because CapitalizedNames for functions implies it should be called with new in Javascript engineering in general, which implies it's a class. Figuring out why a class might be preferable just has to do with Java experience.
The canonical way to create an object in Javascript is:
function user(config) {
this.config = config;
...
}
User = new user(config);
It uses this context (and concept). This format is used if you want to create named properties and/or methods.
If you don't need to create this context you may use just following:
User = function(){}
Here the constructor function is anonymous and doesn't create any context. For the same reason the new keyword is not needed.

Why do Function properties are defined on the object itself (e.g. Function.name), but methods - on Function.prototype?

From the API properties are defined like Function.name, and methods like Function.prototype.call(). But in the code I still invoke them in the same way, for example:
function Foo() {console.log("inside Foo")}
console.log(Foo.name); // Foo
Foo.call(); // inside Foo
I.e. I simply put a function name(Foo), then a method/property I want to use. Then why in API do I see properties defined on Function, and methods - on Function.prototype ?
Placing methods in the prototype allows you to share them among all instances, instead of duplicating them for each one.
For example, the behavior of Function.prototype.call does not depend on which function is called. It only needs a reference to the function (received via this argument) in order to call it later.
However, intrinsic data like name must be stored in the function object itself. It can't be stored in the prototype because each function instance has its own name. Well, it could be store as an internal [[Name]] property, and accessed via a getter and setter defined in the prototype, but the data would still need to be stored in the function.
Note there are non-method properties defined in the prototype, e.g. constructor.
Short answer:
Functions (in general) can be shared among instances, so they go in prototype.
Properties are per-instance, so go in the constructor.
prototype properties (such as the method Foo.prototype.call) are accessible using instances of the object, while direct properties (such as Foo.name) are accessible through the object itself (and not its instances) like static properties.
In your example there is a big difference between Foo.name and Foo.prototype.call, in order to use Foo.name you can call it directly, while in order to use Foo.prototype.call - you need to create an instance, and then it'll be available
function Foo(){}
Foo.prototype.call = funciton(){console.log('I was called');}
Foo.name = 'My name is';
console.log(Foo.name); //My name is
var instance = new Foo();
instances.call(); //I was called
Another thing you need to notice is that both name and call has a native definition in the Function object type in JavaScript - therefore when you call Foo.call() - you call the Function.prototype.call method (which is just like calling Foo();, with one small difference that doesn't affect in this case)
There are actually some argument for placing the default values of immutable values (or objects that are not mutated, by contract) in the prototype for common/expected properties.
Re-assignment of the properties will always be in the 'current this' object (well, object on which the assignment occurs). So if properties are assigned later - in the constructor or even after that - they will be 'promoted' to properties of the actual instance and not the prototype1.
However, since the difference (if any) is very modest, and dependent upon situation, it is common practice just to dump all the property assignments in the constructor. Per-object properties would need to be set individually anyway, regardless of the approach used.
Sharing mutable properties in the [prototype] can get questionable as then the property (when mutated) acts akin to a static variable; mutating shared objects should always be done with care.
1 The only observable difference as to 'where' default properties are assigned is if hasOwnProperty is used.
Interesting related-ish read: Should I put default values of attributes on the prototype to save space? (And yes, I know this disagrees with my vary first sentence.)
You have a slight misconception here. You can define properties and functions (methods) on the function itself. You can define properties and functions that you want the object that the function construct on the prototype. It's not the same thing.
For example, the .create() method of the base Object constructor is defined as as Object.create() but the .hasOwnProperty() method of object instances is defined as Object.prototype.hasOwnProperty().
For example, if you have an object mango created from the constructor Fruit() then:
mango.weight(); // method comes from Fruit.prototype.weight()
Fruit.isFruit(mango); // method comes from Fruit.isFruit()
In particular, the this inside Fruit.isFruit() refers to the function Fruit() while the this inside Fruit.prototype.weight() in the above example refers to the object mango.
If you are used to OO programming from other languages, the difference is between static and non-static class members.

Is it possible to create a function where [[prototype]] refers to another function

I would like to create function objects (yes, all functions are objects) with some control over the prototypal inheritance, that is, I would like one function to inherit from another.
I can make objects that have prototypal inheritance, and know to set the prototype property of a function performing as a constructor to initialize the [[prototype]] property of the object.
However, when creating a function, I must use the function operator or the Function constructor. I could try to swizzle Function.prototype, but (1) don't know if that is writable, and (2) that just seems quite dangerous [still, I should try doing that].
btw: I only care to do this for V8 within node.JS, so if there are means that work only for that environment, that would be acceptable.
For the record, I have seen this:
Is it possible to create a function with another prototype than Function.prototype?
In V8 (and most other browsers/engines except IE) you can change an object's prototype by setting the __prototype__ __proto__ attribute. Setting the prototype attribute will instead change the prototype that is used to create an object if the function is invoked as a constructor function. This should not be what you want.
Afaik there currently is no standard conform way to directly "subclass" a function (or array for that matter). There's only Object.create, but there is no Function.create or Array.create.
EDIT: I just realized that function objects do not have the __prototype__ attribute and changing / setting it will not turn an object into a function.
I believe though that I just recently watched a talk by Brendan Eich (the creator of JavaScript) in which he talked about Function and Array equivalents of Object.create. And infact, googling for "Function.create brendan eich" reveals the following blog post by Eich in which he talks about his wish to implement Function.create and Array.create.
EDIT 2: Ok, I screwed up. Pretty much. The non-standard attribute is of course __proto__ and not __prototype__. Setting __proto__ works fine for functions with some restrictions, which are:
To be able to call aFunction you must initialize it with an actual function, eg:
var aFunction = function () {};
This is important. Calling a function does not access the prototype chain, so if you define aFunction as an object and simply set the __proto__ attribute, you will not able to call aFunction.
You can now assign any other function to aFunction.__proto__ and reading any members (including methods) will correctly delegate to the prototype chain if the porperty is not found on aFunction itself.
Calling aFunction() will always invoke the function that was originally declared when aFunction was defined and will never invoke aFunction's prototype function. So the body of the function is not subject to inheritence.
Sorry for screwing up first with the name of the attribute. Hope this helps you nevertheless.
I came up with a solution that solves my needs. It is not cross-browser, but can be used cross-browser. My most important use case is as a module for node.JS. In that case, the mechanism of setting __proto__ works just fine, in which case I can call methods on the base function object
f.method(args...);
and it executed by code in the "super" function. Because the method is invoked by the method invocation pattern, "this" is set to the base function object, and so the proper properties are accessed even though the method resides in the "super."
Now for the in-Browser case: when I use my library client-side, I provide a proxy mechanism. Alas, code intended for the browser must be written differently. The invocation is:
f.proxy(methodName, args...);
The proxy method in the base function object is:
f.proxy = function (methodName) {
var p = this.constructor.prototype;
return p.proxy(this, methodName, arguments);
};
The proxy in the "super" object's prototype is:
proxy: function (instance, methodName) {
var args = Array.prototype.splice.apply(arguments, [2]),
method = this[methodName];
return (method) ? method.apply(instance, args) : undefined;
}
I probably should have named this "forward" or some such, but "proxy" is good enough.
Perhaps this mechanism might be useful to someone...
I think I understand what you're trying to do. In short, there's no way to really do it natively. You'd have to access the Function constructor, which for function expressions and definitions (i.e. anything using the 'function' keyword), isn't possible as far as I can tell. You could overwrite Function and just always use new Function([args], string) but I doubt you (or any JS programmer) want to do that.
Your best bet would probably be to send your function expressions to another function that returns the function object with your custom methods dynamically added:
wrapFunc = function(f){
f.customFunc = someCustomFunc;
return f;
}
var myNewFunc = wrapFunc(
function(){
//do something
}
);
myNewFunc.customFunc();

Categories

Resources