Relationship of Function object and Javascript object - javascript

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.

Related

Can you initialize a function? - Javascript

I have this function here, I need to work with this other function called OrderRepository in another file.
main.js
function main() {
var orderRepo = new OrderRepository();
// Your code here
}
orderrepository.js
function OrderRepository() {
}
OrderRepository.prototype.getYesterdaysOrders = function
getYesterdaysOrders() {
var yesterdaysOrders = [{ array of objects }],
return yesterdaysOrders;
};
These were given as examples to use, 1 question rolled into 2 parts:
1) var orderRepo = new OrderRepository();
Can you initialize a function like this?
2) In the orderrepository.js:
function OrderRepository() {
}
is being called in main.js, but nothings inside of it, this was given as-is in the assignment, is this just a typo and really they meant to throw everything inside that function or am I missing something?
Shouldn't it look like this?
Expected
function OrderRepository() {
OrderRepository.prototype.getYesterdaysOrders = function
getYesterdaysOrders() {
var yesterdaysOrders = [{ array of objects }],
return yesterdaysOrders;
};
}
Diving deeper into JavaScript, the language is hard to understand. JavaScript is not really OOP (imho), at least it does not implement the common OOP concept. Some call it object-based language. There are no classes. Recent ECMA Script standards do implement the class keyword, however, it is syntax sugar. Used with the new keyword it builds the same objects as you can achieve by 'constructor' functions.
Everything in JavaScript is an object, even numbers and functions. Every function can act as constructor function. The new keyword call a constructor function with a newly creates empty object as the function's this context. The function can do what it wants. If it does not return anything, its this context is returned by the new expression.
Since there are no classes, there is no inheritance. Some inheritance-like behavior is achieved by the prototype concept. In most cases the constructor will return nothing and sometimes modify the this object by adding properties. Methods are properties holding a function object. The object in the new context of a constructor call will have a prototype object reference as the __proto__ property. This is copied by the new operator from the prototype property of the called constructor function. The default is an empty object.
// empty constructor function
function OrderRepository() {
}
// define a function property on the constructor's prototype object
OrderRepository.prototype.getYesterdaysOrders = function
getYesterdaysOrders() {
var yesterdaysOrders = [ /* array of objects */ ],
return yesterdaysOrders;
};
// create an empty object with a `__proto__` property holding a
// reference to the object { getYesterdaysOrders: function(){/*code*/} }
var obj = new OrderRepository();
Now, when the method invocation obj.getYesterdaysOrders() is tried, JavaScript will look if there is such a property defined in obj. If not, it looks if there is a reference in obj.__proto__ and the property name is searched the properties of obj.__proto__. If not, the same step is repeated until it was found or the __proto__ property in the chain is null. Since obj.__proto__.getYesterdaysOrders is defined, it is checked if it is a callable function object and finally invoked with a this context of obj since we called obj.getYesterdaysOrders(). Otherwise an error is thrown.
NOTE: Even if the major browsers do expose the __proto__ property, it is not part of the standards. Do not use it directly (except for debugging at development time) and even more important: do not manipulate it. If you really need to get or manipulate a prototype (__proto__) of an object instance after construction, use the methods of the builtin Object object.
Upon your last edit: Your expected code would define a new function object in prototype on each instantiation (and thus constructor invocation). This is not what you want, it's just needless overhead.
Regarding the first part, it looks like this assignment is dealing with how to create instances of objects in JavaScript as that is what the new operator does.
You can find more information regarding new on the MDN.
Regarding the second question, it is dealing with how to create objects that inherit methods. So, yes it is empty, until you get to the prototype expression.
The expected code would not give you the inheritance in this case. Notice how OrderRepository is repeated inside the function, which would be invalid. Javascript requires you to add inheritance to the special prototype property. Code that is added to the function declaration, would be scoped to the function only in that case.
You can find more information about prototype on the MDN.

What is happening in the creation and execution phase of an object?

I created a normal JavaScript object, like this:
let obj = {
name : "something",
print() {
console.log(this.name);
}
}
let res = obj.print()
console.log(res);
In this example obj has a name and a simple method. I am calling the method from the outside. After that I log the return value to the console, which is undefined.
I don't understand what is happening behind the scenes within the object. Please explain to me the creation and execution phase for this code.
Behind the scenes, the JavaScript interpreter creates an object in memory and refers to it through obj. When you call obj.print(), it refers to the same object and calls the method defined.
In the method, this refers to the object itself (obj), and is set by the JS interpreter as an implicit reference.
At last, you forgot to return the value from print(). So, nothing is assigned to res. Refer to the following example, as it prints the value of res correctly, when a value is returned from the function.
let obj = {
name: "something",
print() {
console.log(this.name);
return this.name;
}
}
let res = obj.print()
console.log(res);
I am going to write about the "behind the scenes" that you are asking for. Unfortunately this might confuse you, instead of making things clearer as JavaScript is quite a "different" language on its own.
In JavaScript a function is an object. Sometimes even called a first-class object. It has everything an object has (attributes and methods) and in addition can further more be invoked. Don't believe me? See for yourself:
function abracadabra()
{
return "this is magic";
}
console.log(abracadabra.name);
console.log(abracadabra.call());
Now a method is simply another function to which an attribute of an object is referring to. Let's take your example:
let obj = {
name : "something",
print() {
console.log(this.name);
}
}
Here obj is defined as an object with two attributes. A value type and a function. When you call the obj.print() function the following happens:
The function is called.
The so-called function context this is set to the object that the method is called upon. You can use this to access other attributes of the same object.
What exactly is this? As said it is the so-called function context that can refer to four different objects depending on how a function is called.
The function is called as a function. e.g. abracadabra() => this is referring to the global context, to which it is always referring by default.
The global context is dependent on the environment JavaScript is executed in. Remember JavaScript can not only run in a browser. It can also be used as a server-side scripting language. In the browser the global context is the current browser window. Don't believe me? See for yourself:
// We are not in any method, still "this" is available:
console.log(this.toString());
The function is called as a method. e.g. obj.print() => this is referring to the object the method is invoked on. I described this above.
The function is called as a constructor. e.g. new abracadabra() => A new empty object is created and this is referring to it. Now the function should extend the empty object with attributes.
The function is called using its apply or call methods => this is referring to whatever you pass as the very first argument of these methods.
So to sum it up: It can get tricky to really understand how these things work in JavaScript. This is because basically there are only objects and functions in the language. Methods look like methods, but are in reality only functions as well.
To get a really good in depth understanding I can recommend the book Secrets of the JavaScript Ninja.

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.

Categories