Reputation: 355
I was confused with this following code in javascript.
var x=(function(){
var customObject = function(){};
customObject.prototype.sayHello=function(){
alert("hello");
};
return customObject;
})();
//var y=new x();// If I uncomment this line and comment the next line "var
//y=x;" the code works
var y=x;
y.sayHello();
This code doesn't say hello but it does when I remove the comment. I read that IIFE executed immediately after it is defined. So, it should assign the customObject to x directly.
My question is that why I need to create a new instance of x to say hello. It is not clear to me how IIFE is working here.
Please help me to understand this concept. Thank you in advance :-) .
Upvotes: 2
Views: 496
Reputation: 34563
You're correct that the customObject
is assigned to x
. But customObject
(and therefore x
) does not have a sayHello
property. It has a prototype
property, and that has a sayHello
property.
When you do y=x
and then y.sayHello()
, you're trying to call customObject.sayHello
, which doesn't exist.
When you do y=new x()
, you create an object whose prototype is the customObject.prototype
object. Then, when you call y.sayHello()
, the sayHello
function is found via the prototype chain.
This isn't really related to your use of an IIFE. You'd get the same result if you just wrote:
var x = function() {}
x.prototype.sayHello = function() {
alert("hello");
}
instead of the IIFE.
Upvotes: 3
Reputation: 4757
Ok, I got your confusion here.
First, IIFE is doing its job correctly here. It executes and returns customObject
to variable x
This is what it is supposed to do.
Now coming to your actual question, why I need to create a new instance of x to say hello?
You may have read, all classes(functions)
have a prototype
and all variables
have __proto__
property.
Anything set on a prototype is accessible to instances of that constructor.
For ex:
var myName = "apl"; // a simple string
console.log(myName.toUpperCase()) // outputs: APL
How do you think we were able to call toUpperCase()
on our variable name?
We could, since typeof(myName )
turns out to be string
. So myName
would be able to call any properties/methods which are set on String.prototype
.
In short, __proto__
property on myName
should be set to String's prototype
i.e myName.__proto__ === String.prototype
// true since myName is an instance of String
Hence, in your case, you need y
to be an instance of x
. Only then you would be able to access methods set on x
prototype which in turn is customObject.prototype
Upvotes: 1