This post has been migrated from injulkarnilesh.blogspot.com.
Then there are two special data types :
A function contained within an object is generally referred to as a method.
A key in an object is called as a property which could be any String even an empty String, whereas property value could anything but undefined.
When objects are passed around to and from functions, they are passed by reference.
When tried to access not existing property, it returns undefined.
Generally constructor function sets fields and methods of objects to be created using this. You can call the construction function just like normal function and if it sets values using this, then the values would be set to what this is referring to and that generally would be a global scope, window in case of browser.
If you want to create an object from constructor function, use new. Then in that case the this will be referring to the object being newly created. So, variables and methods set using this in the constructor function would be available for the newly created object.
In above example when Person is called without new, this is referring to global scope and so the properties firstname, house etc and functions sayHello, print etc. are available on global scope.
You can set functions at prototype level as well. That way also methods could be created for all the objects created with new on the constructor function. This is a part of prototype inheritance that we will see later.
We will see later what exactly happen when you call new on any function.
- Calling using conventional () notation.
- Using call method
- Using apply method
In traditional () way, you just use () after the function name to call it. If you have arguments to pass, you pass those into the parenthesis separated by comma.
Only difference between call and apply is how argument are passed to the function to be called. In apply we pass the arguments in the form of array. So second argument to apply is an array of arguments for the function that you are calling apply on.
In case of call, second onwards all arguments are used as the arguments for function that you are calling the call upon.
When constructor function is defined it will have following structure. lastName and say would be added to Stark.prototype.
When Stark is called, it just sets firstName and print to whatever this will be referring to while execution.
When new is called as
var arya = new Stark(‘Arya’);
following three steps happen :
2) Stark method is called using call or apply so as to use arya object as this, so that properties set to this from within Stark will be added to arya. I don’t know whether it’s call or apply. Just know that purpose is to have new object to be used as this, that is what first parameter of either of these two methods represents.
So when called as Stark.call(arya, ‘Arya’), this function sets firstName and print as properties of arya object.
3) Next step is to set __proto__ of this new object to prototype property of constructor function that is Stark.prototype. As __proto__ property is used as a parental reference in prototypical inheritance, properties of Stark.prototype gets available to arya object as well.
Final picture looks like this :
Advantage of having methods at prototype of constructor function (e.g., say) is that only single copy of that function/method would exist and the same would be shared by all the instances. And if methods are added to the created objects using this (eg. print), then each created object will have its own copy though the same body.
Also every function has prototype property, which refers to the common object that every object created with a new on the function shares.
But when you set a property and that object contains that property then value of that property is updated to new value. But while setting if that object does not contain the property, new property is added to that object with given value, without checking the prototypical hierarchy.
So we can say, get is deep and set is shallow.
Here we are setting Person constructor function as a prototypical parent of Lannister constructor function. That we do with
So the objects created with Lannister contains properties set by Lannister function, properties of Lannister.prototype, properties set by Person and properties of Person.prototype (and obviously Object.prototype).
In above case we have created Lannister as a child constructor function of Person constructor function.
Value of first matching property in above objects in given sequence is retrieved as a value of the property. If no match is found in entire hierarchy, undefined is returned.
The idea behind having this way of inheritance is to have __proto__ of child function’s prototype to point to Parent function’s prototype, so that properties of both the prototypes are available to object of child function. Also it is important to have properties set by parent function itself, and for that we have called new on parent function and value created is set to child function’s prototype. This all is done in
Points to note :
- We are setting Lannister.prototype to a new object, so anything added to Lannister.prototype before we call Lannister.prototype = new Person(); will be lost. So it’s important to add anything to Lannister.prototype (trick function for example) after we have set it to new Person.
- Lannister.prototype.name will be undefined as we are calling Person constructor without parameters.
If you don’t want to use constructor functions for creating objects and still want to achieve inheritance, you can do that by just setting __proto__ of child object to parent object or by using Object.create() method, which does the same for you.
The difference is that to explicitly set __proto__ of child object, object could be created earlier and set other properties, but while using Object.create() method, which creates new object with __proto__ being set to given argument and returns it, you need to set other properties after it is created with Object.create method.
This could used appropriately to have methods available to all the functions of all the objects.
Notice that var robbProperty refers to property in robb object not the values of properties. So you need to use robb[robbProperty] to access properties.
If you want to restrict the loop to actual properties of robb object only, skipping the properties available from inheritance, then you can use hasOwnProperty method of objects which return if the given property is its own.