Shouldn't hello be printed in the console because of the return statement? The code is immediately invoked because of the () at the end so why isn't it printing?
var Module = (function () {
var privateMethod = function () {
// private
};
var someMethod = function () {
// public
console.log('hello');
};
var anotherMethod = function () {
// public
};
return {
someMethod: someMethod,
anotherMethod: anotherMethod
};
})();
return {
someMethod: someMethod, // just a function reference
anotherMethod: anotherMethod // again a function reference
};
So, you're not calling the function. You're just returning the function reference attached to a property of an object. Try to use comma operator here, which evaluates to the right most statement, whilst executing someMethod() function.
return {
someMethod: someMethod(), someMethod, // first getting called and someMethod ref is passed to the property
anotherMethod: anotherMethod
};
It's because of the var keyword on the top infront of Module.
f you do the following in the console:
var a = 5 // a is set to 5 yet undefined is shown in the console.
If you were to take off the var keyword:
a = 5 // a is again set to 5 yet 5 is shown in the console.
But in your real code you would want to use the var keyword.
So simply put it's just the console's way of outputting like that, idk why.
Enlighting more,
function itseld is object of Function (see https://msdn.microsoft.com/en-us/library/ie/x844tc74%28v=vs.94%29.aspx)
So Basically you are adding a reference to object of type Function, which is not IIFE.
Related
I'm a javascript newbie and trying to understand how functions work. I found a similar question here but it doesn't really answer my question.
Taking the following piece of javascript as an example
var test = function(){
console.log("kick off");
var insideTest = "variable inside test";
var init = function(){
var insideInit ="variable inside init";
console.log("inside init");
}
return{
init:init
}
}
test().init();
The above code prints the following:
kick off
inside init
But if I remove
return{
init:init
}
it gives me an error saying
Uncaught TypeError: Cannot read property 'init' of undefined
Also, even though I'm calling init method using test().init() it doesn't print inside Init if the return statement is removed.
My question is why is it necessary to return init:init to execute init method.
EDIT:
To answer why my init function is inside the test() function here is the larger picture of what i'm trying to do.
var test = function() {
var init = function() {
var a = 0;
function1();
function2();
}
var function1() = function() {
//some code
}
var function1() = function() {
//some code
}
return {
init: init
}
}
Have added inline comments. Also the init inside test will have access to variable defined outside it(init) scope which is closure. test is returning an object to access it's inner function.This specific pattern is revealing module pattern
var test = function(){
console.log("kick off");
var insideTest = "variable inside test";
// Here init is a function which is private to test function
// Any function calling test will not have access to init unless it is 'exposed'
var init = function(){
var insideInit ="variable inside init";
console.log("inside init");
}
return{
init:init // exposing the private function
}
}
When you return, you're returning an Object with a single key of init, which you've assigned the "init" function that you defined within the test function. This allows you to return multiple functions if you'd like, so you can chain calls.
If you'd prefer a different way, you could just return the function without the curly braces, ie. return init;, and then assign the return of test() to a variable. var externalInitFnc = test();
Edit: Looking back it seems that you are fuzzy on the idea of scope in Javascript. When you defined init within the test function, it is only accessible within that function. Similar to how a private variable in a Java class is only available within that same class.
Hey guys am a bit confused in running a function from the other. What I have tried is:
var a = (function() {
var babe = function() {
console.log('yay');
};
})();
When I run the code like a.babe() it gives me error like TypeError: Cannot read property 'babe' of undefined. Why is it happening like this?
I want to call the function babe from a ... How can i do it?
I hope you guys can help me ...
Thanks in advance.
You are creating a function called babe and it stays only within the scope of the immediately invoked function expression (IIFE) surrounding it. And since you are not returning anything to the caller, by default, the function call will be evaluated to undefined and that will be stored in a. That is why you are getting the error,
TypeError: Cannot read property 'babe' of undefined
It means that, you are trying to access a property called babe on an undefined value. In this case, a is undefined.
Instead of all this, you can simply return the babe function from the IIFE, wrapped in an object, like this
var a = (function() {
return {
babe: function() {
console.log('yay');
}
};
})()
Now, that the returned object is assigned to a, you can invoke babe function like this
a.babe();
babe is a local variable to the IIFE in that code. It isn't returned. It isn't a property of anything. It isn't accessible.
You have to expose it publicly if you want it to call it from outside that function.
var a = (function() {
var babe = function() {
console.log('yay');
}
return babe;
})();
a();
var a = (function() {
var babe = function() {
console.log('yay');
}
return {
"babe": babe
};
})();
a.babe();
Why have you made a a self executing function? What you want to do is to make a function babe part of an Object a for that, simply do this:
var a = {
babe: function() {document.write('yay');}
}
a.babe();
I have made an object a and added a function babe inside it.. then used the dot notation to access the function inside object a
To use your code you must do
var a = (function() {
var babe = function() { console.log('yay'); }
return babe
})();
a();
To make it a.babe() look at #thefourtheye or #Quentin.
The dot syntax is used to access a "property" of an object. So, in a simple example, you could use something like:
var a = {
babe: function(){ console.log('yay') }
};
a.babe(); // yay
In the case of your example, if you want to create a closure to hide other variables and functions from the global scope, you have to return an object that will then get assigned to a:
var a = (function() {
return {
babe: function(){ console.log('yay') }
}
})();
a.babe(); // yay
Just remember, anytime you use a dot, the variable in front HAS to be an object.
I am trying to create method inside a function. I can make this such a way:
function sample() {};
sample.show = function() { alert() };
And I'll see the alert calling sample.show();. But for the reason of code beautifying I want to move all method declarations inside functions. I tried that:
function sample() {
sample.show = function() { alert() };
}
But I get: TypeError: Object function sample() has no method 'show'
Another ways I tried:
function sample() {
this.show = function() { alert() };
}
function sample() {
sample.prototype.show = function() { alert() };
}
function sample() {
this.prototype.method = function show () { alert() };
}
But result was the same. I can't even find any information about creating methods inside functions. Can you point me a right way?
UPD: I want to have ability to call sample() function which also does some stuff. So there are no solution in answers yet.
function sample() {
this.show = function() { alert() };
console.log('you called "sample()"');
}
sample(); // ==> you called "sample()"
First attempt:
function sample() {
sample.show = function() { alert() };
}
This would only create a "static" method on the sample function and only after executing it
console.log(sample.show);
//would show undefined on the console
sample();
console.log(sample.show);
//would then show the method definition as it has now been
//defined as a property of "sample"
Second Attempt:
function sample() {
this.show = function() { alert() };
}
This will only work if you create a instance of sample
console.log(sample.show);
//will print undefined as there is no property "show" on sample
sample();
console.log(window.show);
//will print the function, but since sample was executed without a
//context, show is created as a property of the global object
//in this case "window"
var d = new sample();
console.log(d.show);
//will print the function as we now have a instance of sample which
//show was made a property of
console.log(sample.prototype.show);
//will show undefined as you are not actually creating the "show" method
//on the constructor sample's prototype
Now with the prototype version:
function sample() {
sample.prototype.show = function() { alert() };
}
With this after you will be able to access the "show" method either through the instance or from the prototype chain, but for the prototype chain call to work you have to at least make one instance before hand
console.log(sample.prototype.show);
//will print undefined as "show" has not been defined on the prototype yet
var d = new sample();
console.log(d.show);
console.log(sample.prototype.show);
//Both will now print the function because the method has been defined
However the last one:
function sample() {
this.prototype.method = function show () { alert() };
}
Will not work at all as you can not access the prototype directly from the instance you will get a undefined error once you try to create an instance.
For it to work you would have to go through the constructor chain to set the method
function sample() {
this.constructor.prototype.method = function show () { alert() };
//is the same as doing
sample.prototype.method = function show(){ alert() };
}
So overall for your "beautifying" to work you have to call sample first, either directly, for the first one, or by creating an instance for the others.
the code in the sample function will not be executed until sample is called. So you could get your example to work by doing this:
function sample() {
sample.show = function() { alert() };
}
sample()
sample.show()
You can try this:
function sample() {
this.show = function() { alert() };
}
var x = new sample();
x.show();
you need to make sample an object
var sample = {
this.show = function() { alert() };
}
I'm currently learning prototyping in javascript, i wrote the below and it seems to work fine when i use it. my question was why do i need the () at the end of the prototype declaration, without that if i try to make an instance of the object I get an error.
var MyTest = function (agencyId, dataId) {
this.agencyId= agencyId;
this.dataId= dataId;
};
MyTest.prototype = function () {
var setObservables = function () {
...
},
init = function (url) {
...
};
// public members
return {
init: init
};
}();
to use it I call it like
var obj = new DetailsDivisionKO(1, 2);
obj.init(actionUrl);
this works fine, but I'm confused about the }(); at the end of the public members section, why is that needed and I can not have that and still use the above code to call it? As without that if i try to call the above code I get a error stating:
Uncaught TypeError: Object [object Object] has no method 'init'
What you have is an IIFE. Its an imidiately invoked function. You are basically creating a closure. You are exposing your init function while preserving a true private scope to your setObservables function. So every time you create a new instance of the constructor, your init function will always be in the prototype. But setObservables will not. In your example you could only access setObservables function internally (hence private scope). Usually you would do that if you only want your init function to call your private functions which in your case is setObservables. But if this is not what you want, you simply can do this:
var MyTest = function (agencyId, dataId) {
this.agencyId= agencyId;
this.dataId= dataId;
};
MyTest.prototype = {
setObservables: function () {
...
},
init: function (url) {
...
}
}
Now every time you will create a new instance of MyTest, both of your functions will be in its prototype.
var test = new MyTest(1, 2);
test.init();
test.setObservables();
Suppose I have:
var myfunc = function() {
// do stuff
}
myfunc.foo = function() {
//do other stuff
};
Now myfunc has a property foo that is a function, great. Is there a way to create myfunc from the get-go in this state? That is, I want foo to be defined when myfunc is created. The syntax, I would imagine, is something like:
var myfunc = {
:function() {
// do stuff
},
foo: function() {
// do other stuff
}
}
Except that's wrong.
You can place an anonymous function inside an object, however the only plausible way of doing this is to call the anonymous function when the object is initialised, otherwise the function will never be able to be called - it's anonymous!
Here's a JSFiddle: http://jsfiddle.net/g105b/99K5F/
var myfunc = function() {
this.foo = function() {
console.log("myfunc.foo called!");
};
(function() {
console.log("Anonymous function called.");
})();
};
// Initialising "myfunc" will call the anonymous function.
var instance = new myfunc();
// Now the foo method can be called.
instance.foo();
A little confused as to what functionality you are looking to gain here...
If you want some code to execute when the myfunc is defined, you could use the module pattern:
var myfunc = (function() {
var self = {};
// any initialization code can go here
alert("myfunc init code");
self.somePublicMethod = function () {
}
return self;
}());
This can also be called an immediate function, a function that is defined and executed at the same time.
From within the closure, and code that is not defined as part of another function will be executed when the object is defined, so when you do something like this:
myfunc.somePublicMethod()
the alert would have already been fired.
(This answer written before the first half of the question was significantly revised)
Now myfunc has a property foo that is a function
No, it doesn't.
You called it with myfunc() so this is a reference to the global window object, thus you are creating window.foo.
Possibly what you are looking for is:
function myfunc () {
// do stuff when myfunc is called
}
myfunc.foo = function () {
// do stuff when myfunc.foo is called
};
or perhaps:
function myfunc () {
// do stuff when myfunc is instantiated
this.foo = function () {
// Add a foo property to this when myfunc is instantiated
// ... which is only worth while if you are doing pretty
// ... odd stuff with the variables that are passed in
}
}
var instance = new myfunc();
or maybe:
function myfunc () {
// do stuff when myfunc is instantiated
}
myfunc.prototype.foo = function () {
// Have a foo function on every instance of myfunc
}
var instance = new myfunc();
… but you've abstracted the problem you are trying to solve away in your question, so it is hard to tell what you are actually trying to achieve.
You can use jQuery:
var myFunc = jQuery.extend(
function() { ... },
{
bar: "wioll haven be",
foo: function() { alert(myFunc.bar); }
}
);
myFunc();
myFunc.foo();
This is mostly code acrobatics, this is probably the closest you'll get:
var myfunc;
(myfunc = function(){}).foo = function(){};
There is no practical difference in declaring methods later though, since javascript is single-threaded.