I was reading another question, and I saw this:
var basketModule = (function() {
var basket = []; //private
return { //exposed to public
addItem: function(values) {
basket.push(values);
},
getItemCount: function() {
return basket.length;
},
getTotal: function(){
var q = this.getItemCount(),p=0;
while(q--){
p+= basket[q].price;
}
return p;
}
}
}());
Can you please explain why does he wrap the function in ( and )'s? Also, what is the purpose of that return? Couldn't he just write self.addItem = ... and so on?
When you wrap a function with parantheses, and add () to the end of it, it's a self executing function.
(function() x() {
//do something;
})();
And, by returning he's making basket variable somewhat private. Try getting basketModule.basket from anywhere else, and you'll get undefined.
That is called javascript Module Pattern. Defining a function and calling it immediately to prevent variables to be in the global space or to define a function name.
Note parentheses in the last line: (). The function is defined and immediately called:
(function() { })();
return { ... } returns an object having a method addItem
The intention of the code is to create an object with three methods. addItem,getItemCount and getTotal. They all depend on state represented by basket.
if basket was defined globally that state would be exposed (and there could only ever be one variable basket. both of those can lead to issues so by wrapping the entire declaration the state is encapsulated and only accessible from the created object.
There are other ways of achieving the same and the pro's and con's are related to style and how many objects of that particular type you're going to need.
wrapping the function(){}() is required since function(){}() will not parse
Related
I have code snippet in which there is a Angular Modular Controller, but there is a function inside the same controller and with a call, which is raising doubt in my mind that is this way of coding allowed in Javascript or Angular? If Yes then how does it read it? See the below code format I have:
obj.controller('CartController',function($scope){
$scope.totalCart = function(){
var total = 10;
return total;
}
function calculate(){
...Some Logic..
}
$scope.$watch($scope.totalCart, calculate);
)};
Please help me to understand that is this type of function definition and call within a controller allowed in Angular/Javascript?
The calculate() is a private function -- it is only accessible in the scope of CartController. If you do not need to make use of your function in the view it is good idea to make it private. It says that it is not intended to be used in the view, so if someone else will be working with this code should think twice before use it in the view. Moreover: from within calculate you have access to all objects that are accessible in the scope of the CartController (including objects passed to CartController as parameters).
Function declared in this way is a proper JS function, which means you can get reference to it by its name. Sometimes it is thought to be more readable if you declare / create your function in advance and only then assign them to properties of some other object (in this case $scope):
function someFn (...) { ... }
function someOtherFn (...) { ... }
...
$scope.someFn = someFn
In the above snippet the intentions are very clear: make someFn accessible, while keep someOtherFn private.
Btw. declaring functions like: function nameFn(...){...} is called function statement; you can very similarly do it like: var nameFn = function(...) {...} (so called function expression). There is a slight difference between those -- basically it is illegal:
someFn();
var someFn = function(...) {...}
whereas, this works:
someFn();
function someFn(...) {...}
Sometimes you are forced to use this pattern, look e.g. at my answer to this question.
$scope.launch = function (which) {
};
var _func = function () {...}
The definition is allowed, it has the same affect as
$scope.$watch($scope.totalCart, function(){..some logic...})
I'm currently trying to implement some common JS concepts
in little projects to understand better how to use them.
I've been working on a simple game, trying to
understand and use the module pattern and closures.
I'm using the module pattern from Stoyan Stefanov's 'patterns'
book.
I'm struggling to understand how best to mix modules and
closures.
I'd like to know if I'm organising the following code in a
sensible way? If so, my question is: what's the best way
to modify the code so that in the $(function(){}) I have
access to the update() function?
MYAPP.utilities = (function() {
return {
fn1: function(lives) {
//do stuff
}
}
})();
MYAPP.game = (function() {
//dependencies
utils = MYAPP.utilities
return {
startGame: function() {
//initialisation code
//game state, stored in closure
var lives = 3;
var victoryPoints = 0;
function update(){
utils.fn1(lives);
//do other stuff
}
}
}
})();
$(function(){
MYAPP.game.startGame();
//Want to do this, but it won't work
//because I don't have access to update
$('#button').on('click',MYAPP.game.update)
});
I've come up with a couple of options which would work, but
I'd like to know if they're good practice, and what the best
option is.
Options:
(1) Bind $('#button').on('click', ...) as part of the
startGame initialisation code.
(2) Assign the update() function to a variable, and
return this variable from the startGame function, So in
$(function(){}) we could have
updatefn = MYAPP.game.startGame(); and then
$('#button').on('click',MYAPP.game.update)
(3)? Is there a better way?
Thank you very much for any help,
Robin
First off, to access the update function in that fashion it will have to exposed in the returned object.
return {
update: function() {
[...]
},
startGame: function() {
[...]
this.update();
}
}
Calling obj.method() automatically sets the this reference inside this method call to obj. That is, calling MYAPP.game.startGame() sets this to MYAPP.game inside this startGame method call. More details about this behavior here.
You will also want to move the lives variable to a common scope which is accessible by both startGame and update methods, which is exactly what the closure is for:
MYAPP.game = (function() {
[...]
var lives; //private/privileged var inside the closure, only accessible by
//the returned object's function properties
return {
update: function() {
utils.fn1(lives);
},
startGame: function() {
[...]
lives = 3; //sets the closure scope's lives variable
[...]
this.update();
}
}
})();
Fiddle
In this case you will need some method to set the lives variable when you want to change it. Another way would be to make the lives variable public as well by making it a property of the returned object and accessing it through this.lives inside of the methods.
NOTE: If you simply pass a reference to the function object stored as property of the returned object as in:
$('#button').on('click', MYAPP.game.update);
The this reference inside the click handler will not point to MYAPP.game as the function reference that has been passed will be called directly from the jQuery core instead of as an object's member function call - in this case, this would point to the #button element as jQuery event handlers set the this reference to the element that triggered the handler, as you can see here.
To remedy that you can use Function.bind():
$('#button').on('click', MYAPP.game.update.bind(MYAPP.game));
Or the old function wrapper trick:
$('#button').on('click', function() {
MYAPP.game.update(); //called as method of an obj, sets `this` to MYAPP.game
});
This is important when the this keyword is used inside the update method.
There are a few issues in your code. First, update() function is not visible outside the object your creating on the fly. To make it part of game object it has to be on the same level as startGame.
Also, if you declare var lives = 3 it will be a local variable and it won't be visible outside startGame() function, as well as victoryPoints. These two variable have to be visible in some way (via closure or as object fields).
Finally, attaching MYAPP.game.update as an event listener will attach just that function, preventing you from using all other object methods/functions. Depending on what you want to do you might prefer to pass a closure like function() { MYAPP.game.update() } instead.
Your code should look something like:
MYAPP.utilities = (function() {
return {
fn1: function(lives) {
console.log(lives);
}
}
})();
MYAPP.game = (function() {
//dependencies
utils = MYAPP.utilities
var lives;
var victoryPoints;
return {
startGame: function() {
//initialisation code
//game state, stored in closure
lives = 3;
victoryPoints = 0;
},
update: function() {
utils.fn1(lives);
//do other stuff
}
}
})();
$(function(){
MYAPP.game.startGame();
//Want to do this, but it won't work
//because I don't have access to update
$('#button').on('click', MYAPP.game.update)
});
(DEMO on jsfiddle)
Hello i have the following issue i am not quite sure how to search for it:
function(){
var sites;
var controller = {
list: function(){
sites = "some value";
}
}
}
So the question is how to access the sites variable from the top defined as
var sites
EDIT:
Here is a more complete part. i am Using marionette.js. i don't want to define the variable attached to the Module (code below) variable but keep it private to the Module, hope that makes sense. Here is the code that works:
Admin.module("Site", function(Module, App, Backbone, Marionette, $, _ ) {
Module.sites = null;
Module.Controller = {
list: function (id) {
Module.sites = App.request("site:entities");
}
};
});
and i would like instead of
Module.sites=null;
to do
var sites;
That sort of thing does make a difference right? Because in the first case i would be defining an accessible variable from outside where as the second case it would be a private one. i am a bit new to javascript so please try to make it simple.
if you are looking for global access, just declare the variable outside the function first, make your changes to the variable inside the function, then you can get the value whenever you need it.
I have found some info on this: sadly what i am trying to do doesn't seem possible.
Can I access a private variable of a Marionette module in a second definition of that module?
So i guess i have to do _variable to make developers know its private.
Disclaimer: I have no experience using Marionette, however, what you're describing sounds very doable.
One of the most powerful (in my opinion) features of JavaScript is closures. What this means is that any function declared from within another function has access to the variables declared in the outer function.
For example:
var func;
function foo() {
var answer = 42;
func = function () {
// I have access to variable answer from in here.
return answer++;
};
}
// By calling foo(), I will assign the function func that has access "answer"
foo();
// Now I can call the func() function and it has access to the "answer"
// variable even though it was in a scope that doesn't exist anymore.
// Outputs:
// 42
// 43
console.log(func());
console.log(func());
What this means is that if you declare var sites from within your module definition function as you described, you should have access to it from within any of your inner anonymous functions. The only exception is if Marionette is re-writing your functions (by using the Function function and toString()), which seems unlikely but possible.
Your original example should would as described, my suspicion is that there is something else going wrong with the code that is unrelated to your scope.
var ObjectLiteral = {
myName:function() {
}
}
I want to call the myName function immeditetly when the page is
loaded.
I am not sure hot to write a self calling function inside an
ObjectLiteral...
You can't assign a function while simultaneously calling it (since calling it means that its return value gets assigned instead). You have to do this in two steps.
var ObjectLiteral = {
myName:function() {
}
};
ObjectLiteral.myName();
Just because no one mentioned it:
var ObjectLiteral = {
myName: function() {
console.log('myName was called!');
return arguments.callee;
}()
}
Since arguments.callee is deprecated in ES5, we would need to give the method a name:
var ObjectLiteral = {
myName: function _myName() {
console.log('myName was called!');
return _myName;
}()
}
Done. The method would get called at pageload and would still be callable later on. The caveat of doing it that way is the this context value which is replaced with window or undefined (strict) on the self-executing method. But you could apply some magic to solve that aswell. For instance, invoking .call(ObjectLiteral) in es3 or .bind(ObjectLiteral) in es5.
var ObjectLiteral = {
myName: function _myName() {
console.log('myName was called!');
return _myName;
}.call(ObjectLiteral)
}
Looks like I was wrong (damn!). The idea ok, but the assignment to ObjectLiteral is not done on the first invocation of myName. Therefore, the above code will only run from the second call on, which of course makes it useless anyway. You would need to invoke another context, but that would be just overkill.
It still does work after all, but it screws up if you need to access this, otherwise its a fine solution I think.
For your first question:
The simplest possible answer is to add this line to your script:
window.onload = ObjectLiteral.myName();
A better answer is to include that line somewhere in a larger function assigned to window.onload:
window.onload = function () {
....
ObjectLiteral.myName();
}
An even better answer is to scope things properly in case window has been reassigned.
For the second question, what to you mean by self-calling? (EDIT: n/m, Quentin answered)
Taking into account you want to execute your code after page load, jQuery is very suitable for that:
$(function() {
// called then page loaded..
var ObjectLiteral = {
myName:function() {
}
};
ObjectLiteral.myName();
});
How can I define a function's prototype in JavaScript? I want to do this like I would do it in C where you would do something like:
void myfunction(void);
void myfunction(void){
}
So is there any way to do this in JavaScript? I'm asking this because of the function declaration order that is required in JavaScript.
Edit:
I have an object:
function something(){
var anArrayOfSomethingObjects;
aPrivateFunction(){
// does some stuff
anArrayOfSomethingObjects[3].aPublicFunction();
}
return {
functionA: function() { },
aPublicFunction: function() { },
functionC: function() { }
}
}
privateFunction needs to access publicFunction which is declared afterwards.
How can I do this?
JavaScript is dynamic language there is no need to do that. Meaning Javascript has dynamic binding and dynamic typing, so the check will be on the run time. So no need to define forward declaration like in static languages.
Reply to edit:
Even in this case you still do not need to define forward declaration. Once object will have that method or field in run-time it will work fine. But you probably tackled to the problem of scoping in JavaScript, assuming you asking your question after something gone wrong.
you have to really understand what is a dynamic language, and why your question doesn't really make a lot of sense. your problem is not about 'definition vs. declaration' like on C, it's most about statements order.
in JavaScript (as with most dynamic languages) a function definition like this
function whatever (params) {
...
}
is in fact syntactic sugar for an assignment statement like this:
whatever = function (params) {
...
}
as you can see, whatever is in fact a variable, and it's assigned a function value. so you can't call it before assigning it.
Of course, execution order doesn't have to follow lexical order. If that's your case, you just have to make sure you assign the needed variable before using it. If it's a local variable and you want closure semantics, you can define it first and assign later, like this:
var myfunc = undefined;
function first () {
...
myfunc (...);
...
}
myfunc = function (...) {
...
}
What you are looking for is the Module pattern:
function Something()
{
var someObjects;
var pub = {};
var privateFunction = function()
{
pub.publicFunction();
}
pub.functionA = function() {};
pub.functionB = function() {};
pub.publicFunction = function() {};
return pub;
};
More info and examples: http://www.wait-till-i.com/2007/08/22/again-with-the-module-pattern-reveal-something-to-the-world/