Hi still i'm not sure about the exact usage of using closures in javascript.I have idea about closures "A closure is an inner function that has access to the outer (enclosing) function’s variables—scope chain".But i don't know why we are using closures in javascript.
It allows you to succinctly express logic without needing to repeat yourself or supply a large number of parameters and arguments for a callback function.
There is more information available here: javascript closure advantages?
Imagine if instead of
alert("Two plus one equals" + (2+1) );
you'd be forced to declare a variable for every constant you ever use.
var Two = 2;
var One = 1;
var myString = "Two plus one equals";
alert(myAlert + (Two + One) );
You'd go crazy if you had to define a variable for every single constant before you can ever use it.
The access to local variables in case of closures is an advantage, but the primary role - usefulness - is the use of a function as a primary expression, a constant.
Take
function Div1OnClick()
{
Counter.clickCount ++;
}
$('#Div1').click(Div1OnClick);
versus
$('#Div1').click(function(){ Counter.clickCount++; });
You don't create a new function name in the "above" namespace just to use it once. The actual activity is right there where it's used - you don't need to chase it across the code to where it was written. You can use the actual function as a constant instead of first defining and naming it and then calling it by name, and while there are countless caveats, advantages and tricks connected to closures, that's the one property that sells them.
In general, the main use of closures is to create a function that captures the state from it's context. Consider that the function has the captured variables but they are not passed as parameters.
So, you can think of it of a way to create families of functions. For example if you need a series of function that only differ in one value, but you cannot pass that value as a parameter, you can create them with closures.
The Mozilla Developer Network has a good introduction to closures. It shows the following example:
function init() {
var name = "Mozilla";
function displayName() {
alert(name);
}
displayName();
}
init();
In this case the function displayName has captured the variable name. As it stand this example is not very useful, but you can consider the case where you return the function:
function makeFunc() {
var name = "Mozilla";
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc();
myFunc();
Here the function makeFunc return the function displayName that has captured the variable name. Now that function can be called outside by assigning it to the variable myFunc.
To continue with this example consider now if the captured variable name were actually a parameter:
function makeFunc(name) {
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc("Mozilla");
myFunc();
Here you can see that makeFunc create a function that shows a message with the text passed as parameter. So it can create a whole family of function that vary only on the value of that variable ("Mozilla" in the example). Using this function we can show the message multiple times.
What is relevant here is that the value that will be shown in the massage has been encapsulated. We are protecting this value in a similar fashion a private field of a class hides a value in other languages.
This allows you to, for example, create a function that counts up:
function makeFunc(value) {
function displayName() {
alert(value);
value++;
}
return displayName;
}
var myFunc = makeFunc(0);
myFunc();
In this case, each time you call the function that is stored in myFunc you will get the next number, first 0, next 1, 2... and so on.
A more advanced example is the "Counter" "class" also from the Mozilla Developer Network. It demonstrates the module pattern:
var Counter = (function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
}
})();
alert(Counter.value()); /* Alerts 0 */
Counter.increment();
Counter.increment();
alert(Counter.value()); /* Alerts 2 */
Counter.decrement();
alert(Counter.value()); /* Alerts 1 */
Here you can see that Counter is an object that has a method increment that advances the privateCounter variable, and the method decrement that decrements it. It is possible to query the value of this variable by calling the method value.
The way this is archived is with an auto-invocation of an anonymous function that creates a hidden scope where the varialbe privateCounter is declared. Now this variable will only be accessible from the functions that capture its value.
Closures are a powerful construct used to implement a lot of additional features in JavaScript. For instance a closure can be used to expose private state as follows:
function getCounter() {
var count = 0;
return function () {
return ++count;
};
}
var counter = getCounter();
alert(counter()); // 1
alert(counter()); // 2
alert(counter()); // 3
In the above example when we call getCounter we create a private variable count. Then we return a function which return count incremented. Hence the function we return is a closure in the sense that it closes over the variable count and allows you to access it even after count goes out of scope.
That's a lot of information stuffed in a few lines. Let's break it down?
Okay, so variables have a lifetime just like people do. They are born, they live and they die. The beginning scope marks the birth of a variable and the end of a scope marks the death of a variable.
JavaScript only has function scopes. Hence when you declare a variable inside a function it's hoisted to the beginning of the function (where it's born).
When you try to access a variable which is not declared you get a ReferenceError. However when you try to access a variable which is declared later on you get undefined. This is because declarations in JavaScript are hoisted.
function undeclared_variable() {
alert(x);
}
undeclared_variable();
When you try to access an undeclared variable you get a ReferenceError.
function undefined_variable() {
alert(x);
var x = "Hello World!";
}
undefined_variable();
When you try to access a variable which is declared later in the function you get undefined because only the declaration is hoisted. The definition comes later.
Coming back to scopes a variable dies when it goes out of scope (usually when the function within which the variable is declared ends).
For example the following program will give a ReferenceError because x is not declared in the global scope.
function helloworld() {
var x = "Hello World!";
}
helloworld();
alert(x);
Closures are interesting because they allow you to access a variable even when the function within which variable is declared ends. For example:
function getCounter() {
var count = 0;
return function () {
return ++count;
};
}
var counter = getCounter();
alert(counter()); // 1
alert(counter()); // 2
alert(counter()); // 3
In the above program the variable count is defined in the function getCounter. Hence when a call to getCounter ends the variable count should die as well.
However it doesn't. This is because getCounter returns a function which accesses count. Hence as long as that function (counter) is alive the variable count will stay alive too.
In this case the function which is returned (counter) is called a closure because it closes over the variable count which is called the upvalue of counter.
Uses
Enough with the explanation. Why do we need closures anyway?
As I already mentioned before the main use of closures is to expose private state as is the case with the getCounter function.
Another common use case of closures is partial application. For instance:
function applyRight(func) {
var args = Array.prototype.slice.call(arguments, 1);
return function () {
var rest = Array.prototype.slice.call(arguments);
return func.apply(this, rest.concat(args));
};
}
function subtract(a, b) {
return a - b;
}
var decrement = applyRight(subtract, 1);
alert(decrement(1)); // 0
In the above program we had a function called subtract. We used partial application to create another function called decrement from this subtract function.
As you can see the decrement function is actually a closure which closes over the variables func and args.
That's pretty much all you need to know about closures.
It is because of information hiding.
var myModule = (function (){
var privateClass = function (){};
privateClass.prototype = {
help: function (){}
};
var publicClass = function (){
this._helper = new privateClass();
};
publicClass.prototype = {
doSomething: function (){
this._helper.help();
}
};
return {
publicClass: publicClass
};
})();
var instance = new myModule.publicClass();
instance.doSomething();
In javascript you don't have classes with ppp (public, protected, private) properties so you have to use closures to hide the information. On class level that would be very expensive, so the only thing you can do for better code quality to use closure on module level, and use private helper classes in that closure. So closure is for information hiding. It is not cheap, it cost resources (memory, cpu, etc..) so you have to use closures just in the proper places. So never use it on class level for information hiding, because it is too expensive for that.
Another usage to bind methods to instances by using callbacks.
Function.prototype.bind = function (context){
var callback = this;
return function (){
return callback.apply(context, arguments);
};
};
Typical usage of bound function is by asynchronous calls: defer, ajax, event listeners, etc...
var myClass = function (){
this.x = 10;
};
myClass.prototype.displayX = function (){
alert(this.x);
};
var instance = new myClass();
setTimeout(instance.displayX.bind(instance), 1000); //alerts "x" after 1 sec
Related
From the MDN description of Function:
Note: Functions created with the Function constructor do not create
closures to their creation contexts; they always are created in the
global scope. When running them, they will only be able to access
their own local variables and global ones, not the ones from the scope
in which the Function constructor was called. This is different from
using eval with code for a function expression.
I understand,
var y = 10;
var tester;
function test(){
var x = 5;
tester = new Function("a", "b", "alert(y);");
tester(5, 10);
}
test(); // alerts 10
Replacing the tester = new Function("a", "b", "alert(y);"); with tester = new Function("a", "b", "alert(x);");, I will get
// ReferenceError: x is not defined
But couldn't understand the author's line-
...they always are created in the global scope.
I mean how is the new Function("a", "b", "alert(y);"); nested within the test fn is in global scope?
In fact, accessing it from outside the test fn will simply result in
Uncought TypeError:tester is not a function
Please elucidate.
In your example, "created in the global scope" means that tester will not have closure over x from test:
function test(){
var x = 5;
tester = new Function("a", "b", "alert(x);"); // this will not show x
tester(5, 10);
}
When you new up a Function, it does not automatically capture the current scope like declaring one would. If you were to simply declare and return a function, it will have closure:
function test(){
var x = 5;
tester = function (a, b) {
alert(x); // this will show x
};
tester(5, 10);
}
This is the trade-off you make for having dynamically compiled functions. You can have closure if you write the function in ahead of time or you can have a dynamic body but lose closure over the surrounding scope(s).
This caveat doesn't usually matter, but consider the (slightly contrived) case where you build a function body as a string, then pass it to a function constructor to actually be evaluated:
function addOne(x) {
return compile("return " + x + " + 1");
}
function addTwo(x) {
return compile("return " + x + " + 2");
}
function compile(str) {
return new Function(str);
}
Because the function is instantiated by compile, any closure would grab str rather than x. Since compile does not close over any other function, things get a bit weird and the function returned by compile will always hold a closure-reference to str (which could be awful for garbage collection).
Instead, to simplify all of this, the spec just makes a blanket rule that new Function does not have any closure.
You have to create an object to expose via return inside the test() function for it to be global. In other words, add var pub = {} and name your internal functions as properties and/or methods of pub (for example pub.tester = new func) then just before closing test() say return pub. So, that way it will be publically available (as test.tester). It's Called the Revealing Module Pattern.
What it means is that inside the function you can only refer to global variables, as you've found. However, the reference to the function itself is still in the local scope where it was created.
I'm confused as to where the confusion is.
It says that the function will be in global scope...and therefore will only have access to its own scope and the global scope, not variables local to the scope in which it was created.
You tested it and it has access to its own scope and the global scope, not variables local to the scope in which it was created.
So where's the confusion?
Is it in your assigning of the function to the variable testing? testing is just a local variable with a reference to the function...that has nothing to do with the scope of the creation of the function.
Scope is lexical, and has to do with where the function is created, not what random variables a function reference happens to be assigned to at runtime. And the documentation is telling you that when you make a function this way it acts as if it was created in the global scope...so it's acting completely as expected.
Here's an illustration:
This:
var y = 10;
var tester;
function test()
{
var x = 5;
// 10 and errors as not defined
tester = new Function("console.log(y); console.log(x);");
}
Is similar to this:
var y = 10;
var tester;
function test()
{
var x = 5;
// also 10 and errors as not defined
tester = something;
}
function something()
{
console.log(y);
console.log(x);
}
NOT
var y = 10;
var tester;
function test()
{
var x = 5;
// 10 and 5...since x is local to the function creation
tester = function()
{
console.log(y);
console.log(x);
}
}
I'm coming from an Actionscript background and (very late to the party) I am trying to learn JavaScript. I am going through this AngularJS - Video Tutorial For Beginners on YouTube (it's pretty good) and saw something really basic that I don't understand.
At line 5 the var workcount is defined. Then two anonymous functions are defined and returned in an object. The functions reference workcount but isn't workcount in a different scope? Is this like blocks in Objective-C where local vars remain accessible within the block. Is there a name for what this is?
Or if a function "knows about" vars previously defined in its scope, would the function task2 "know about" task1?
It bugs me that I can't make sense of this.
Update: Thanks for all the replies. I get it now – and while I have seen the term "closures" before, I never understood it (it seems a not very descriptive term. In reading up, I saw the term "stack-frames" and then the light bulb lit up: stack... frame of reference);
var createWorker = function(){
var workCount = 0;
var task1 = function(){
workCount += 1;
console.log("task1" , workCount);
};
var task2 = function(){
workCount += 1;
console.log("task2" , workCount);
};
return {
job1: task1,
job2:task2
}
};
worker=createWorker();
worker.job1();
worker.job2();
Output:
task1 1
task2 2
Just note that the variable and the two anonymous functions are wrapped inside the same function (let's call it a parent function). So the scope of this variable is available within this parent function.
So now this variable acts as a global variable for these two inner functions But the scope is limited to the parent function. Both the inner functions share the same variable.. Changing the value of the variable in one function will have effect in other function too..
So taking the logic in the post Let's say we execute task1 and task2 one after the other. The variable is initially set to 0. Then in your task1 it's incremented by one. Which makes the variable value 1 (0 + 1). Now in task two also its increased by one, making its value 2 (1 + 1).
This scope concept is called as closure in JavaScript.
This is called a closure in JavaScript.
The scope of a closure in JavaScript is lexical, which means that everything that is contained within the function the closure belongs to, has access to any variable that is in it
Basically createWorker is a scope and since task 1 and task 2 are declared inside createWorker they have access to all the variables declared in createWorkers scope.
But createWorker does not have access to any variables declared inside task 1 and task 2.
Yes, functions are aware of everything in their scope, including each other.
There are two parts to your question.
The second part is easy to answer first: all variables and functions in a scope are "hoisted," allowing you to use a variable before you declare it:
x = 5;
var x;
console.log(x); // Gives 5
Back to the first part of your question: in terms of scope, I won't expand too much on it since it is a widely covered topic on this and other sites. w3schools has a good guide on this.
Basically, it boils down to global and local scope. Global scope works as you might imagine, with the variable (or function) being available globally:
var x = 10;
function foo() {
console.log('Global scope! ' + x);
}
Local scope is, basically, for everything within a closure (a topic well beyond this question), which functions are:
function foo() {
bar(); // This will work, since foo and bar share scope
foobar(); // This will not work: foobar is only in scope within bar
}
function bar() {
function foobar() {
console.log('foobar');
};
console.log('bar');
foobar(); // This will work, since foobar is defined within bar's local scope
}
Things get a little more complicated with var declarations. This is being greatly simplified by the ES6 let declaration. Read more.
And by the way, while your functions are anonymous, they aren't really since you are saving references to them. Functionally, the two examples below are perfectly equivalent:
// These give the exact same result
function foo() {}
var foo = function() {}
// You can use either by calling
foo();
This code illustrates how it works.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Closure JS</title>
<script type="text/javascript">
var createWorker = function () {
var workCount = 0;
var task1 = function () {
var t = t || 0;
workCount += 1;
console.log("task1: " + workCount);
console.log("task1 t: " + (t++));
}
var task2 = function () {
var t = t || 0;
workCount += 1;
console.log("task2: " + workCount);
console.log("task2 t: " + (t++));
}
return {
job1: task1,
job2: task2
};
}
var app = new createWorker();
</script>
</head>
<body>
<div>
<input type="button" value="task1" onclick="app.job1()" />
<input type="button" value="task2" onclick="app.job2()" />
</div>
</body>
</html>
Console output after several clicks on buttons:
task1: 1
task1 t: 0
task1: 2
task1 t: 0
task2: 3
task2 t: 0
task2: 4
task2 t: 0
It easy to see that task1 and task2 know about their parent scope and know nothing about each other and about their previous execution.
This way ball bounces.
You can write write your code as in below and javascript will interpret it the same.
var createWorker = function(){
var workCount, task1, task2;
workCount = 0;
task1 = function(){
workCount += 1;
console.log("task1" , workCount);
};
task2 = function(){
workCount += 1;
console.log("task2" , workCount);
};
return {
job1: task1,
job2:task2
}
};
What happens here is, variables are defined at the top of the enclosing function block. No matter in what order they are defined. So not only task2 knows about task1, task1 also knows about task2. However order of assignments in important. Consider the code:
function foo1() {
console.log("foo1: " + a);
var a = "Hello";
}
function foo2() {
var a = "Hello";
console.log("foo2: " + a);
}
function foo3() {
console.log("foo3: " + a);
let a = "Hello";
}
function foo4() {
console.log("foo4: " + b);
}
var b = 5;
foo1(); // undefined
foo2(); // Hello
try {
foo3(); // Throws ReferenceError
} catch (e) {
console.log("foo3: " + e.message);
}
foo4(); // 5
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
When foo1 tries to use a, it was defined but it was not assigned.
foo3 uses let instead of var. let is more intuitive for some
coming from other programming languages. But be careful as it is part
of ES6 specification and not widely supported yet.
foo4 works since b was defined before foo4 was
defined. b was assigned before foo4 was invoked.
JavaScript has some interesting variable scoping rules. Here is a quick overview:
x = 0; // Global, as no "var" keyword preceeds it. Btw: var is optional!
var x = 0; // This is scoped to it's parent fn. Child fn's can use it.
let x = 0; // This is similar to var, but has a special use case. (See below.)
As an added bonus, this next line of code looks like it's a variable declaration, but it's not. It defines a constant. It's part of the EcmaScript 2015 spec, AKA ES6. Here's what's new in ES6.
const x = 0; // This is a constant (locked variable) and can't be changed.
While both var & let are accessible by their immediate function & their children functions, here is where they're different: The let keyword can allow someone to make duplicates variables with the same name, from both inside of the parent & child functions! It just makes JS stranger!
Since workCount is defined inside of the parent createWorker function with the "var" keyword, then the task1 & task2 functions can change it's value, as they are children functions.
Check out the MDN specs on how the var & let keywords work.
So the answers to some of your questions are:
No, it's in the same parent "createWorker" function scope.
Unknown as I don't write ObjectiveC code. Someone else can answer that one.
Yes & No: Yes, because it can tell that task1 is a function, but No, because the code in task2's function block can't see inside of task1's function block.
task 2 would not know about variables created within task 1, task 1 and task 2 do know about workCount.
Does javascript function stored in memory once when we define a function anywhere weather its in object or global.
function (){
alert("some value");
}
obj = {
m: function(){
alert('some value');
}
}
If you define the function one time, and pass a reference of that function to different variables/properties, then yes, it's stored one time.
var one_func = function () { console.log("I'm just one function."); };
var reused = one_func;
var reuser = { func : reused };
All of them have pointers to the same function.
But if you have something like this:
var Circle = function (r) {
var circle = {
radius : r,
calculate_area : function () { return 2 * Math.PI * r; }
};
return circle;
};
var circle_1 = Circle(2),
circle_2 = Circle(4);
The two objects do NOT share calculate_area.
You've created two distinct versions of the function.
And they must remain distinct due to function-scope and closures.
See, each copy knows about its own circle's r.
If you notice, I'm not looking at circle.radius, I'm looking at the r passed into the Circle function.
So any function which is defined inside of Circle has to be new every single time, because those functions save references to any variables inside of the constructor, through closure.
The memory-hit of having multiple copies, versus the benefits of having totally private properties is well worth it, until you hit thousands and thousands of copies (unless we're talking about gigantic objects or horrible old browsers, or running JavaScript on an LED screen on a Toaster).
More advanced engines might optimize the memory-footprint here, but it's rarely worth wasting the CPU, given how little memory each of these functions would take up, and how much RAM smartphones have (let alone custom-built gaming PCs).
EDIT
for the sake of pedantry
var Wallet = function (opening_balance) {
var balance = opening_balance,
overdraft = 50,
is_sufficient_funds = function (amount) {
return balance + overdraft >= amount;
},
deposit = function (funds) {
if (amount <= 0) { return; }
balance += funds;
},
withdraw = function (amount) {
if (amount <= 0) { return; }
if (is_sufficient_funds(amount)) {
balance -= amount;
return amount;
}
},
public_interface = {
deposit : deposit,
withdraw : withdraw
};
return public_interface;
};
Now, it should be blisteringly-apparent that we do not want balance or overdraft to be publicly accessible in any instance of Wallet.
Even this pedestrian version of Wallet is quite safe.
Sure, it's not doing any authorization right now, so you can deduct everything, or add a million dollars...
...but can you set your overdraft to $300?
Can you manually copy the value of balance?
Even if you created var wallet = Wallet(35); and then tried to rewrite the deposit method, your rewriting of it would then have absolutely no access to the private balance.
Now the closure-related benefits of this memory-overhead should be apparent.
If you'd prefer, you could consider the rate of fire of a gun in a multiplayer game.
Or a character's movement.
Or their health.
Or high-scores.
By keeping all of these things encapsulated in closures, they're untweakable.
That doesn't mean that the server is unhackable.
But it does mean that there's one less spot for people to get in, without rewriting your engine from the ground up.
It's kind of hard to tell what you're asking, but I see two possible questions and therefore two answers:
A JavaScript function is created once for each execution of the execution context in which you've defined it. So if that context is global (outside of any function), yes, each declaration or expression will create only one function. If that context is within a function, they'll be defined each time the function is called.
So for example, if this is a global scope:
function foo() { }
...only one of those will be created. In contrast, something like this:
function bar() {
return {
foo: function() { }
};
}
...creates a new function and assigns it to the foo property on the returned object each time bar is called. (That doesn't mean a smart JavaScript engine can't share the underlying code for them — and I'm told by people who claim to know that V8 [the engine in Chrome and elsewhere] does indeed reuse the code — but they'll be separate function objects.)
Each function declaration or expression creates its own function; if you have two equivalent declarations or expressions, they create two functions, even though they're equivalent. That doesn't mean that a smart JavaScript engine can't share the underlying code under-the-covers, but you'll still have two separate function objects.
So for example:
var a = function() { };
var b = function() { };
console.log(a === b); // "false"
// Adding a property to `a`, since functions are objects, demonstrates
// further that they are not the same function object
a.foo = "bar";
console.log(a.foo); // "bar"
console.log(b.foo); // "undefined"
No. The anonymous function
function(){
alert("some value");
}
is not the same as the anonymous function inside the object literal obj.
To make sure you 'recycle' a stored object or function, do somethign like this:
var f = function(){ alert('test') };
obj = {
m: f
}
I'm trying to create a function which returns another function. I want separate information when each of the inner function is run, but this isn't happening. I know that explanation is not great, so I've put together a small example.
var testFn = function(testVal) {
return (function(testVal) {
var test = testVal;
this.getVal = function() {
return test;
}
return that;
})(testVal);
}
var a = testFn(4);
var b = testFn(2);
console.log(b.getVal(), a.getVal());
This outputs 2, 2. What I would like is 2, 4 to be output. I know this isn't explained perfectly, so if it's not clear what I'm trying to achieve, can someone explain why the variable seems to be shared across the two functions?
Thanks
Like this ?
var testFn = function(testVal) {
var test = testVal
return {
getVal: function() {
return test
}
}
};
var ab = testFn (4)
var ac = testFn (2)
console.log(ab.getVal(),ac.getVal()) //4 //2
The problem in your code is this.getVal() / returning this
because 'this' refers to the global scope / Window
You are glubbering with the global namespace and overwriting Window.getVal() , the moment you are setting b = testFn (2)
This results in overwriting as method getVal too because they both refer to the global Object and always share the same method getVal
Therefore they share the same closure and are outputing 2
console.log("The same: " + (Window.a === Window.b)) // true
console.log("The same: " + (a === b)) // true
you can see that if you change it a little:
var testFn = function(testVal) {
var x = {}
return (function(testVal) {
var test = testVal;
x.getVal = function () {
return test;
}
return x
})(testVal);
}
var a = testFn(4);
var b = testFn(2);
console.log(b.getVal(), a.getVal());//4 2
it suddenly works because it results in 2 different Objects returned (btw you don't even need the outer closure)
console.log("The same: " + (a === b)) // false
Here are the JSbins First / Second
I hope you understand this, I'm not good in explaining things
If theres anything left unclear, post a comment and I'll try to update the answer
This question comes down to the context in which functions are invoked in JavaScript.
A function that is invoked within another function is executed in the context of the global scope.
In your example, where you have this code:
var testFn = function(testVal) {
return (function(testVal) {
var test = testVal;
this.getVal = function() {
return test;
}
return this;
})(testVal);
}
The inner function is being called on the global scope, so this refers to the global object. In JavaScript a function executed within another function is done so with its scope set to the global scope, not the scope of the function it exists within. This tends to trip developers up a fair bit (or at least, it does me!).
For argument's sake, lets presume this is in a browser, so hence this refers to the window object. This is why you get 2 logged twice, because the second time this runs, this.getVal overwrites the getVal method that was defined when you ran var a = testFn(4);.
JavaScript scopes at function level, so every function has its own scope:
var x = 3;
function foo() {
var x = 2;
console.log(x);
};
console.log(x); //gives us 3
foo(); // logs 2
So what you want to do is run that inner function in the context of the testFn function, not in the global scope. You can run a function with a specific context using the call method. I also recorded a screencast on call and apply which discusses this in greater detail. The basic usage of call is:
function foo() {...}.call(this);
That executes foo in the context of this. So, the first step is to make sure your inner function is called in the right context, the context of the testFn method.
var testFn = function(testVal) {
return (function(testVal) {
var test = testVal;
this.getVal = function() {
return test;
}
return this;
}.call(this, testVal);
}
The first parameter to call is the context, and any arguments following that are passed to the function as parameters. So now the inner function is being called in the right scope, it wont add getVal to the global scope, which is a step in the right direction :)
Next though you also need to make sure that every time you call testFn, you do so in a new scope, so you're not overwriting this.getVal when you call testFn for the second time. You can do this using the new keyword. This SO post on the new keyword is well worth reading. When you do var foo = new testFn() you create and execute a new instance of testFN, hereby creating a new scope. This SO question is also relevant.
All you now need to do is change your declaration of a and b to:
var a = new testFn(4);
var b = new testFn(2);
And now console.log(b.getVal(), a.getVal()); will give 2, 4 as desired.
I put a working example on JSBin which should help clear things up. Note how this example defines this.x globally and within the function, and see which ones get logged. Have a play with this and hopefully it might be of use.
The output you get is (2,2) because when you do
var that = this;
what you actually get is the global object (window),
the object that holds all the global methods and variables in your javascript code.
(Note that every variable that is not nested under an object or function is global and
every function that is not nested under an object is global, meaning that functions that are nested under a function are still global)
so, when you set:
var test = testVal;
this.getVal = function() {
return test;
}
you actually set the function "getVal" in the global object, and in the next run you will again set the same function - overriding the first.
To achieve the affect you wanted I would suggest creating and object and returning it in the inner function (as #Glutamat suggested before me):
var testFn = function(testVal) {
return new Object({
getVal: function() {
return testVal;
}
});
}
var a = testFn(4);
var b = testFn(2);
console.log(b.getVal(), a.getVal());
In this way, in the outer function we create an object with an inner function called "getVal" that returns the variable passed to the outer function (testVal).
Here's a JSBin if you want to play around with it
(thanks to #Glutamat for introducing this site, I never heard of it and it's really cool :D)
It is possible to access ther oute scope of a function?
I will explain better.
I've a function, from which I want to acccess its calling function scope.
function called() {
// i want to access the calling outer function scope
}
function calling() {
called();
}
obviusly called() function could be called by a lot of calling functions, and called() has to know time to time which function has called him,` and access its scope variables and functions.
No, that isn't possible.
To access a variable from two functions you need to either:
Declare it in a shared scope
var the_variable;
function called() {
// i want to access the calling outer function scope
}
function calling() {
called();
}
Pass it as an argument
function called(passed_variable) {
return passed_variable;
}
function calling() {
var some_variable;
some_variable = called(some_variable);
}
You should pass any relevant information into called() as parameters:
function called(x, y, z) {
}
function calling() {
var x = getX();
var y = computeY();
var z = retrieveZ();
called(x, y, z);
}
If you expect called to do different things, and receive different contextual information, depending on who calls it, you should probably make it multiple separate functions.
function called(outterScope) {
// outterScope is what you want
x = outterScope.declaredVariable;
outterScope.declaredFunction();
}
function calling() {
this.declaredVariable = 0;
this.declaredFunction = function() { // do something };
var _self = this;
called(_self);
}
No,
if you need to use variables from scope of calling code block (example function)
you have to pass them in arguments
or you can create object and access properties in Object scope (via this.param_name)
Depending on what you want to do, there might be better ways to do it, but if absoultely have to resort to it, you may find that out via Function.caller:
function myFunc() {
if (myFunc.caller == null) {
return ("The function was called from the top!");
} else
return ("This function's caller was " + myFunc.caller);
}
Do note that its not part of the standards, even though some major browsers and IE7 support it.
Also, you cannot access the caller functions scope or variables. Its usability is limited to finding out who called you (helpful for logging or tracing).