Does New make any sense in this case? - javascript

Is there any case where a Constructor returns something on purpose and it still makes sense to new it?
var Fn = function(){
return this.fn = function(){}
}
var a = new Fn()
var b = Fn()
I can't seem to find any difference between a and b from console, but just in case I missed something, are they identical? Apart from b's side effect of adding fn as a method to window object. And if they're the same, does it mean that when a Constructor returns something, it's no longer a Constructor and shouldn't be newed?
Edit, the reason I'm asking is that I'm working with Coffee and Angular at the moment, while both seem to be pretty sensitive about return, especially with providers. Do you have any best practises regarding this?

Yes. The new invocation creates a new this context in which the function inside the constructor will be evaluated. Without it, the invocation assumes the local context and attaches your function to it. This is really important if you have multiple functions that you want to bind a unique object to.
I had the same question you did, and read the spec. I wrote about this in What the 'new' operator means to Javascript.
Arun's answer is half-right, in that it's true for the special case that you're working at the base level of the Javascript interpreter, where this === windows (or, for Node, this === global; for PLv8, this === role). Inside other objects (a really common occurrence when working with modern libraries like jQuery or Backbone!), the this operator is the local context, not the windows root.

So with the information #Elf provided, as in
When the [[Construct]] property for a Function object F is called, the following steps are taken:
Create a new native ECMAScript object.
Set the [[Class]] property of Result(1) to “Object”.
Get the value of the prototype property of the F.
If Result(3) is an object, set the [[Prototype]] property of Result(1) to Result(3).
If Result(3) is not an object, set the [[Prototype]] property of Result(1) to the original Object prototype object as described in 15.2.3.1.
Invoke the [[Call]] property of F, providing Result(1) as the this value and providing the argument list passed into [[Construct]] as the argument values.
If Type(Result(6)) is Object then return Result(6).
Return Result(1).
When the Constructor intentionally returns something, that something would get returned in Result(6), therefore defying the purpose of Constructors--to return Result(1) as an instance.
The only possible use of this is to take advantage of Step 6 and call the Fn with certain arguments and certain this, which, could easily be done without using Constructors and a simple call. So I guess, if Constructors return stuff, it ain't Constructor anymore.
Edit:
The interesting exception being, the object returned is Result(1) on purpose, in order to be able to take arbitrary number of arguments: Use of .apply() with 'new' operator. Is this possible?. Thanks #Elf.

Related

What is meaning of Function.prototype.__proto__?

I am a beginner in Javascript and am learning about Object Oriented and prototyping in it.
As far as I know, Object is a function and is created by Function because Object.__proto__ === Function.prototype but looking through various diagrams online, I am quite confused by fact that How Function.prototype.__proto__ === Object.prototype.
What does Function.prototype.__proto__ mean?
Isn't it something that is developed by language owners as Function is the first thing from which everything arrives.
Then what does it mean? Am I lacking some important fact? I looked through other StackOverflow answers but can't find anything related to it.
TL;DR
__proto__ is a property of an object which enables you to look up in the prototype chain. While prototype is a property of a Function which enables you to add shareable functionalities to a constructor function.
Long Answer
Understand this from an example, let's say you create a constructor function.
function A() {} and then create an instance of it, var a = new A().
Then, add a function as following:
A.prototype.getA = function () { return 'A'; }.
Now, if you try to access a.getA(), you'll get the result, i.e. getA will be executed.
But how does it know about the function getA even though getA has been added after the instance a was created. It's because of using __proto__, you can traverse up in the chain (you must have heard about prototype chaining).
Technically, __proto__ is a property of an object, while prototype is a property of function. But how could functions have property? Because everything in JavaScript is converted implicitly to an object. Ever wondered how could you something like this: 'test'.toUpperCase()? Isn't string literals are 'not object' and they are primitives?
Read this for reference: http://jayendra.co.in/objects-in-javascript/
Now to answer your question:
What does Function.prototype.__proto__ mean?
You are trying to access the prototype property of Function constructor function. Remember, prototype itself is an object, so you can access properties like constructor and __proto__.
Function.prototype.__proto__ === Object.prototype
To enable chaining, when you access __proto__ property, you are looking up!
Any function can access all the properties of an object. How?
A property of Object, let's say toString. You can do, A.toString() // A created at the start. But we never created a function toString for A constructor function!
myFunc.prototype is the __proto__ of any object constructed by calling new myFunc().
Thinking in terms of classical (Java- or C++-style) OO, you could say that myFunc is a constructor and (therefore) myFunc.prototype is the class. In that sense, myFunc.prototype.__proto__ is the superclass; that is, the prototype of the prototype of all objects created with new myFunc.
One useful thing you can do to myFunc.prototype.__proto__ is assign to it to create a superclass relationship, e.g.
myFunc.prototype.__proto__ = mySuperclassConstructor.prototype
This idiom sheds light on why Function.prototype.__proto__ === Object.prototype holds (the core of your question): it simply means that Function is a subclass of Object — Or in other words, JavaScript runtimes do something equivalent to the above code snippet in their prelude so as to make Function a subclass of Object (as they should, per ECMA-262 §§ 19.2.2 and 19.2.3)
Careful though, while __proto__ happens to work on all modern (2019) JavaScript implementations (node.js and browsers), its use is both non-standard and slow. Consider using “real” ES6 classes instead.

Is Object.prototype.toString a function or a property?

Before asking, I have tried to do my homework and to avoid a duplicate. Thus, I have read about 20 questions and answers (mainly on SO) which all deal with toString(). But unfortunately, none of them did answer my actual question. So here we go ...
Many examples contain code like that:
Object.prototype.toString.call(someVariable);
I just would like to know why toString can be used like a property here. I have read the reference for Object.prototype at MDN and other places. All of them list a function toString() among the members of Object.prototype, but no property toString.
Furthermore, I am using a line like that shown above at several places in my code. For testing purposes, I have added parentheses to make it "clean":
Object.prototype.toString().call(someVariable);
Obviously, that did not make it "clean", but just made it return wrong results or even made the browser stall (I am currently in the process of researching what exactly is going on).
I already have read some questions and answers regarding calling functions without parentheses. But even if I accept that the first of the code lines shown above actually calls a function (although it looks like accessing a property), that still does not explain why it goes wrong horribly when I add the parentheses as shown in the second code line. Being able to call functions without parentheses should not mean being unable to call them with parentheses, should it?
I don't think that question has an answer already (if yes, I apologize), so could anybody please give a short explanation?
Is Object.prototype.toString a function or a property?
Object.prototype.toString is a property. The value of that property is a reference to a function. Exactly like this:
var obj = {f: function() { } };
There, obj.f is a property, the value of which is a reference to a function.
The initial value of Object.prototype.toString is the intrinsic function known in the spec as %ObjProto_toString%. It can be overwritten, but doing so would like break a lot of things.
The thing to remember is that in JavaScript, functions are just objects that inherit from Function.prototype* and are callable. Just like other objects, you can keep references to them in properties and variables (you can even add properties to functions themselves), pass those references around, etc. This is in marked contrast to many languages which treat "classes" and methods and other kinds of functions as special, non-object things.
* (host-provided objects aren't required to inherit from Function.prototype, but in modern environments most do; in some obsolete browsers, some don't.)
Functions are just values. toString is a property of the Object.prototype object whose value is a function.
() is the function call operator. Object.prototype.toString doesn't call a function; it just fetches the value of the Object.prototype.toString property (which happens to be a function).
Functions are also objects, with properties of their own. That's why you can do Object.prototype.toString.call(...): This gets the Object.prototype.toString function, then fetches its call property, then calls it (which is allowed because the value of call is another function).
This works even without involving properties:
var foo = function () { return "hello"; };
var bar = foo;
console.log(bar);
console.log(bar());
The first line assigns a function value to the foo variable.
The second line assigns the same value to bar, reading from foo. Note that we're not calling the function, we're just passing it around like any other value.
The first console.log displays the function itself.
The second console.log displays the result of calling the function, because we used ().
Welcome to JavaScript. It's true that functions can be called without () in some cases (specifically, new f), but not in this case. What you see is the reference to the function being used as an object but not called (yet). That's a common thing to do, although in this case it's probably a bit more obscure than usual so I'll explain why it's done like that.
The function finally gets called when you explicitly call its call method (every function inherits that from the Function prototype), which allows you to bind this in the function body to some arbitrary object. Your first example may do the same thing as someVariable.toString(). So why use the longer form ?
Well, someVariable may not have a toString method (if it's null or undefined, because they are not objects and can't be boxed into an object), in which case using someVariable.toString would throw a TypeError. Or its prototypal toString method may have a different behaviour than the one for basic Objects. In this case, I guess that the author wanted to use an old-school trick for getting the name of an object's "species", which involves the fact that Object.prototype.toString always returns "[Object whatever]" where "whatever" will be the constructor's name or Null or Undefined.

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:
it creates an empty object,
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,
it executes the provided function in context of that object (this points to it during that function's execution), and
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.

Why the prototype method is ignored here?

In the code below I am trying to understand the behavior of the method assigned to the prototype object and those defined at the object definition of the function Vehicle:
function Vehicle(theMake) {
var make = theMake;
//this. attachs "make" to this instance of
//the object Vehicle which is infact an object of type Object
this.getInfo = function () {
return 'Local definition of getInfo, Vehicle: ' + make;
};
}
Vehicle.prototype.getInfo = function () {
//prototype will not have access to the variable make
return 'Overriding getInfo for all instances of Vehicle';// which later I realized is just the opposite( check the selected answer)
}
var car1 = new Vehicle('Honda');
alert(car1.getInfo());//Displays: Local definition of getInfo, Vehicle: Honda
1- Despite providing the definition of Vahicle.prototype.getInfo(), why the car1.getInfo() will be invoked? ( the local copy not the generic one?) why it ie being ignored?
If i remove the "this.getInfo = function()..."
then the generic getInfo will be invoked by car1.getInfo()
2-How can I invoke the car1.prototype.getInfo())? If I call it like car1.prototype.getInfo().call
the interpreter says: Unable to get property 'getInfo' of undefined or null reference
You should be assigning getInfo in only one place. Either in the prototype or in the constructor (preferably prototype), but NOT both places.
If you do both, the one assigned in the constructor will take precedence because it is assigned to the actual object which is searched first (before the prototype is searched). The prototype is only used if there is no property with the desired name already attached directly to the object. Because you've assigned a .getInfo property directly to the object in the constructor, the prototype is not searched when resolving that property name (because it's already found).
Since your code indicates that you think the .prototype version is the override, it appears that you just have that logic backwards. The getInfo() assigned to the object in the constructor is what overrides the prototype.
If you truly wanted to execute the prototype version, you could access it directly on the prototype:
Vehicle.prototope.getInfo.call(car1);
But, really if you want access to both methods, you should just given them different names so they are both accessible as car1.method1() and car1.method2().
So to summarize from your specific questions:
1- Despite providing the definition of Vahicle.prototype.getInfo(),
why the car1.getInfo() will be invoked? ( the local copy not the
generic one?) why it ie being ignored?
The object itself is searched before the prototype so the getInfo assigned directly to the object in the constructor will be found by the interpreter first and the prototype will not be searched.
2-How can I invoke the car1.prototype.getInfo())? If I call it like
car1.prototype.getInfo().call the interpreter says: Unable to get
property 'getInfo' of undefined or null reference
The best solution is to give the two functions different names so they are both callable in the conventional way. If you absolutely have to call the prototype version, you can do so as Vehicle.prototope.getInfo.call(car1);.
One might ask, why are you giving these two functions the same property name? That's what is creating the problem in the first place.
The prototype chain allows the object to delegate to it's prototype when there is a failed lookup on the constructor. You have provided an instance where there will not be a failed lookup, so there is no need for it to look up the method on the prototype.

Relationship of Function object and Javascript object

Recently I read a tutorial which says if define the function like below.
function Animal() { }
On the surface, this code seems to create a function called Animal.
But with JavaScript, the full truth is slightly more complicated. What
actually happens when this code executes is that two objects are
created. The first object, called Animal, is the constructor function
itself. The second object, called Animal.prototype, has a property
called Animal.prototype.constructor, which points to Animal. Animal
has a property which points back to its prototype, Animal.prototype.
But I have little confuse about it .What about the Function object ?What is the use for the Animal object?
And If I write code like below .
var test= new Function();
and I inspected the variable test in the Developer tool of the Chrome.
I found test is nothing to do with the Function. Can someone tell me why ? thanks.
Updated
The diagram below is the objects relationship when the code is executed, please review it.
If my understanding is wrong. please correct me. thanks.
That blog post goes into a lot of detail that's interesting but unnecessarily confusing for most people most of the time.
First, let's talk about functions; forget about prototypes for a minute. When you create a function:
function Whatever() {
// ...
}
you've created an object. That is, all functions are objects, and they're constructed via the Function built-in constructor. The symbol "Whatever" in this example will have as its value a reference to that object.
Given a reference to a function, it's possible to call it:
Whatever(); // call the function
It's possible to take that value (the reference to the function object) and assign it to another variable, or pass it as a parameter to another function, or to use it just like any other value in JavaScript.
var another = Whatever;
another(); // also calls the "Whatever" function
Constructing a function via the Function constructor explicitly is something that's rarely done, but it gives you a function that's otherwise unremarkable. (In the OP, the constructed function doesn't do anything because no code was passed to the Function constructor.)
Now, things get interesting when a function is invoked as part of a new expression.
var test = new Whatever();
By using new, a new object is instantiated and associated with the "Whatever" function. The "Whatever" function is the constructor for that new object.
Every function object, whether it's ever used as a constructor or not, has an associated "prototype" object. When a function is used as a constructor, then objects it constructs (that is, objects made in new expressions that invoke the function) are implicitly associated with that prototype object.
The prototype object becomes interesting when an object property reference expression is evaluated. Object property references look like this:
obj.name
obj[ nameExpression ]
In such an expression, the property name (either the identifier used in the . expression or the value of the expression inside [ ]) is checked against the set of properties on the object directly. If the name is not the same as one of the object's properties, then the runtime consults the prototype object associated with the constructor function used to make the object.
For most code that most people write, that relationship and some of its direct implications are the only things to worry about. You don't have to fool around with the (non-standard, at this time) "proto" property of objects unless you're putting together some sort of library or framework.
Finally, it might be instructive to look at the Object.create() function and in particular the "polyfill" shown in that documentation.

Categories