Javascript closure overwrite function expression - javascript

I try to figure out, how closure works, this is my example
function func1(func) {
return function(summand) {
return func() + summand;
}
}
var func2 = function() {
return 3;
}
var func3 = func1(func2);
var value = func3(4);
alert(value);
var func2 = function() {
return 100;
}
var newValue = func3(100);
alert(newValue);
First of all let breaks down the code. I write a function that expected as parameter a function and it will return a function.
function func1(func) {
return function(summand) {
return func() + summand;
}
}
Then i defined the parameter function func2 in expression form
var func2 = function() {
return 3;
}
then call func1 and give func2 as pamerater. As result i have got a function back
var func3 = func1(func2);
then i execute function and pass 4 as parameter argument
var value = func3(4);
as result i've got 7. Then i overwrite func2 and return 100
var func2 = function() {
return 100;
}
then call func3 again and pass as parameter value 100.
var newValue = func3(100);
as result i've got 103. The first function that i defined(that return a function and takes function as parameter), will still used the first version of func2. This the power of closure, i know it.
But look at the following code, when i define func2 as function declaration not as expression, then func2 will overwrite
function func1(func) {
return function(summand) {
return func() + summand;
}
}
function func2() {
return 3;
}
var func3 = func1(func2);
var value = func3(4);
alert(value);
function func2() {
return 100;
}
var newValue = func3(100);
alert(newValue);
The first value is 104 and second is 200.
My question is, why when i use function declaration it will overwrite the old function, in this example is func2. But when i use function expression it will keep the reference to old func2.
It that because of function hoisting?

This is not because of closures.
Just like you figured out - this issue is because of function hoisting.
You can think of function declarations as "moved up" to the start of the current scope.
var f2 = function(){
return 50;
}
function f2(){
return 100;
}
In this case, f2 is 50 because it gets parsed in a way that's similar to:
var f2 = function(){
return 100;
}
var f2 = function(){
return 50;
}
Because of hoisting.

It is because of hoisting. Using the function statement rather than the function expression causes the function func2 to get hoisted to the top of the scope. You are overwriting func2 before any code in the scope gets executed.
because of hoisting you code actually looks like this:
function func1(func) {
return function(summand) {
return func() + summand;
}
}
function func2() {
return 3;
}
// Hoisted!!! Overwriting the previous func2 definition.
function func2() {
return 100;
}
var func3 = func1(func2);
var value = func3(4);
alert(value);
var newValue = func3(100);
alert(newValue);
Inside func1, func is a stable reference to the function that it was passed... It's just that you are passing the return 100; version before you think you are.

When you use the function foo() { ... } style, you are defining a function with the name foo. When you use the var foo = function() { ... } style, you are declaring a variable foo (which will be hoisted), and assigning it the anonymous function as its value.
It is ok to write
var a;
a = 2;
// ...stuff...
a = 3;
and we expect the value to be 3. So it is here, hoisting makes this like:
var func2;
func2 = function() { .. some stuff.. };
// ...stuff...
func2 = function() { .. some other stuff .. };
By comparison, I think if you define the functions, it will just take the one or other function definition in the initial parse.

Related

What does function in function do exactly in nodejs?

See this example:
var tools1 = require('../tools/tools1');
var test_func = function(arg1, arg2, arg3) {
var local_var_1 = "lc1";
var local_var_2 = "lc2";
return function(data) {
var result = tools1.doSth(local_var_1);
result = result+local_var_2;
}
}
exports.test_func = test_func;
I do not understand what does inner function do what it is for!
In javascript when you return function it returns reference of that function and you can call it later.
In your Code when you do var result = test_func(), result will hold reference of that function. Then later you can call that returned function like result(data).
A basic example:
function sum(x, y) {
var rs = x+y;
return function(message) {
console.log(message + rs); //rs holds its value because of clousers
}
}
var result = sum(2, 3);
result("This is result: ");
Variables that are used locally, but defined in an enclosing scope
like rs in above example because of Closures
This concept of function inside a function is known as closure in JavaScript. They are self invoking and makes it possible to have a function's private variables.
I am representing a similiar code of yours which I found in W3schools.com.
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
add();
add();
add();
Initially, the counter is set to 0 and then it returns a function reference. The counter is protected by the scope of the anonymous function, and can only be changed using the add() function.
The counter is set to 3 then, as add() function is called three times.
In the very similiar way, your code is working I guess:
var test_func = function(arg1, arg2, arg3) {
var local_var_1 = "lc1";
var local_var_2 = "lc2";
return function(data) {
var result = tools1.doSth(local_var_1);
result = result+local_var_2;
}
}
the local_var_1 and local_var_2 is set to "lc1' and "lc2" and returning a function reference.
The inner function then comes and do some operation with tools1.doSth() on local_var_1 and append the result with local_var_2.
Note: I am not clear with the output of your code, so I tried to tell you the steps with help of another code.

Passing information between JavaScript methods

I have an object with two different sets of objects inside:
var myObj;
(function (myObj) {
var myFunction = (function () {
function myFunction(){
this.myValue = "something";
}
myFunction.getValue = function () {
var _this = this;
return _this.myValue;
}
return myFunction;
})();
myObj.myFunction = myFunction;
var myFunction2 = (function () {
function myFunction2() {
}
myFunction2.prototype.something = function () {
var a = myFunction.getValue();
}
return myFunction2;
})();
myObj.myFunction2 = myFunction2;
})(myObj || (myObj = {}));
Every time I run myFunction2.something(), a is assigned: undefined.
How can I get the value from myFunction into myFunction2.something()?
There is quite a mixup of scopes and design patterns in your code. Having 2 functions named the same way on inside the other creates different scopes for that name depending on where you call them. This quickly gets out of control. Like in this part:
var myFunction = (function () { // this guy is named myFunction
function myFunction(){ // this guy is also named myFunction
this.myValue = "something"; // 'this' here most certainly refers to 'window', not myFunction. Unless you do a 'new myFunction()' a la prototype
}
myFunction.getValue = function () {
var _this = this;// same here
return _this.myValue;
}
return myFunction;// here you are returning a function, not an object with methods
})();
Also I noticed that you are handling some logic with prototypes and other with closures, this also is kinda confusing when someone else (or you in a couple of months) need to refactor this code.
myFunction.getValue = function () {
var _this = this;
return _this.myValue;
}
return myFunction;
You could go all prototypes or all closures. I prefer closures so here is what I would do.
var myObj;
(function (myObj) {
// in this closure, we create a scope and return only the public methods
var myFunction = (function () {
// define properties here
var myValue = 'default value';
// define your methods, here we return
// myValue declared on the parent scope
function getValue() {
return myValue;
}
// this acts as a constructor, it autoexecutes
(function init(){
myValue = "something";
})();
// return all the functions in this scope
// you want to expose
return {
getValue: getValue
};
})();
// we then put myFunction into myObj
// at this point myFunction is an object with a method called getValue()
myObj.myFunction = myFunction;
var myFunction2 = (function () {
function something() {
// once this guy is called, we get the value from the other 'class'
var a = myFunction.getValue();
alert(a);// voila!
}
(function myFunction2() {
// do your init stuff here
})();
return {
something: something
};
})();
myObj.myFunction2 = myFunction2;
})(myObj || (myObj = {}));
// at this point myObj is an object with 2 'classes', each 'class' has its own methods
// we can proceed and call the desired method
myObj.myFunction2.something();
Demo: http://jsfiddle.net/bzw9kse7/
I've stepped through your code and just noticed a couple small things you're doing wrong.
You appear to be misdefining myFunction slightly, because it's not going to have myValue as a member variable, just a temporary variable that quickly falls out of scope. (And because it becomes undefined, it gets assigned to a, which is then unassigned).
So, replace these lines:
var myFunction = (function () {
function myFunction(){
var myValue = "something";
}
myFunction.getValue = function () {
var _this = this;
return _this.myValue;
}
return myFunction;
})();
With this:
var myFunction = (function () {
var myFunction = {};
myFunction.myValue = "something";
myFunction.getValue = function () {
var _this = this;
return _this.myValue;
}
return myFunction;
})();
EDIT Sorry, got this all wrong. It returns undefined because getValue is a static method of myFunction Object, not an instance method. That means that the this is not the same as in myFunction constructor.
Moreover you are not even attaching myValue to the this anywhere...
Edit 2 I added getMyValue to the myFunction prototype.
Try this:
....
var myFunction = (function () {
function myFunction(){
this.myValue = "something";
}
myFunction.prototype.getValue = function () {
return this.myValue;
}
// this creates the instance of the myFunction class.
return new myFunction();
})();
myObj.myFunction = myFunction;
...
// now you should be able to see the right result
var a = myFunction.getValue();
This is one of the craziest code I have ever seen, but the answer is this:
var a = myFunction.getValue(); is undefined because your 2nd definition of myFunction returns undefined, as in here:
function myFunction(){
var myValue = "something";
}
Your 2nd definition of myFunction actually replaces the 1st. See the comments below:
var myFunction = (function () {
// this definition replaces the one above
function myFunction(){
var myValue = "something";
}
myFunction.getValue = function () {
var _this = this;
return _this.myValue;
}
// which makes this return to not be taking in account when you are
// calling myFunction()
return myFunction;
})();

Private Member To Object Containing Function

In javascript, I have an object containing a function and want to add to it a private member.
How can I do that?
function function1 () {
var function2 = function () {
console.log("This is an actual function.");
}
function2.publicMember = 5;
function2.privateMember = 7;
return function2;
}
I want privatMember to be inaccessible to the user of function1.
I found this question but I can't quite translate it to my situation because my object is a function:
How to add private variable to this Javascript object literal snippet?
thanks!
Wrap it into one more function to create new scope (i.e. using iife):
function function1 () {
var function2 = (function(){
var privateMember = 7;
return function () {
privateMember ++; // do something with really private member
console.log("This is an actual function.");
}
})();
function2.publicMember = 5;
return function2;
}
Declare the vars inside the function that needs access to them:
function function1 () {
var publicMember = 5;
var function2 = function () {
var privateMember = 7;
console.log("This is an actual function.");
}
return function2;
}
So function2 can see the vars inside its own closure (privateMember) and any parent scope.

Double nesting a function-valued return stops from entering the double nested function

Trying to understand the scope chain and execution context stack articles from David Shariff's Blog, I've tried to understand closures here
function foo() {
var a = 'private variable';
return function bar() {
alert(a);
}
}
var callAlert = foo();
callAlert(); // private variable
I just wanted to test if inner function has the variable object just from its parent or from the whole scope chain, so I added a nested function repeating the example:
function foo() {
var a = 'private variable';
return function bar() {
return function foobar() {
console.log(a);
};
};
}
var callAlert = foo();
callAlert(); //
And that is not giving any result. It seems the interpreter is not even entering the foobar() function. And the syntax is the same than its parent.
But it works if I divide the function declaration and execution.
function foo() {
var a = 'private variable';
return function bar() {
function ra() {
console.log(a);
};
return ra();
};
}
var callAlert = foo();
callAlert(); // private variable
And really I'm trying to guess why; where's the difference from bar() and foobar() functions.
PS - I'm testing on JSFiddle
function foo() {
var a = 'private variable';
return function bar() {
return function foobar() {
console.log(a);
};
};
}
Here you're returning a function that returns a function, so you need to call that new, doubly nested function
var callAlert = foo()();
DEMO
Or any variation on that theme
var getBar = foo();
var getFooBar = getBar();
getFooBar(); //private variable.
Updated demo
The second example works fine because you're still returning one function—a function that simple calls another function.
return function bar() {
function ra() {
console.log(a);
};
return ra();
};

there is no alert prompt when run this simple javascript code?

var foo = function(){};
foo.prototype.value = 5;
foo.prototype.addValue = function(){ foo.value = 6; }
function bar(func)
{
func(); // I'm running the function!
}
bar(foo.addValue); // pass in the function
alert(foo.value); // it's now 6!
Why is the no alert prompt when running this JavaScript code?
The correct code should be
var foo = function(){};
foo.prototype.value = 5;
foo.prototype.addValue = function(){ foo.value = 6; }
function bar(func)
{
func(); // I'm running the function!
}
bar(foo.prototype.addValue); // pass in the function
alert(foo.value);
or
var foo = function(){};
foo.prototype.value = 5;
foo.prototype.addValue = function(){ foo.value = 6; }
function bar(func)
{
func(); // I'm running the function!
}
bar(new foo().addValue); // pass in the function
alert(foo.value);
Since you are declaring a prototype called addValue, foo itself does not contain addValue. To refer to that function, you have to use foo.prototype.addValue. Note that in this case, foo contains both foo.prototype.value with a value of 5, and foo.value with a value of 6.
Alternatively, if the intention is to create a new object, then the object will inherit the addValue function, so calling new foo().addValue works.
Well, refactoring your code would give:
var foo = {
value: 5,
addValue: function(){
foo.value = 6;
}
};
function bar(func){
func(); // I'm running the function!
}
bar(foo.addValue); // pass in the function
alert(foo.value); // it's now 6!
Setting foo.prototype.addValue won't help you to define foo.addValue.
And the reason for using foo.value instead of this.value is to resolve scope problems when calling via bar()

Categories

Resources