How to have function recall private variable between invocations - javascript

Here's an easy one straight from the text book I can't seem to find.
I have a javascript function. I want it to contain a private variable which remembers its value between invocations.
Can someone jog my memory please.

Create it using a closure:
function f() {
var x = 0;
return function() {return x++;};
}
Then use it as follows:
> g = f()
function () {return x++}
> g()
0
> g()
1
> g()
2

var accumulator = (function() {
var accum = 0;
return function(increment) {
return accum += increment;
}
})();
alert(accumulator(10));
alert(accumulatot(15));
Displays 10 then 25.

I am not sure if I understood correctly but maybe something like this would do the trick :
function Foo() {
var x = "some private data";
return {
getPrivateData : function(){
return x;
}
};
};
var xx = new Foo();
xx.getPrivateData();

Here is a truly private implementation
(function() {
var privateVar = 0;
window.getPreviousValue = function(arg) {
var previousVal = privateVar;
privateVar = arg;
return previousVal;
}
})()
alert(getPreviousValue(1));
alert(getPreviousValue(2));
Cheers

Related

Why does IIFE function return undefined when value is passed instead of an Object?

I'm learning Javascript at the moment, Please look at this snippet of code:
I've here defined 3 Immediately Invoked Function Expressions. My expectation here is when I console.log(controller) it returns undefined. Can anyone please explain me, why does controller IIFE be able to return an Object but not a value?
var budgetController = (function() {
var x = 23;
var add = function(a) {
return x + a;
}
return {
publicTest: function(b) {
console.log(add(b));
}
}
})();
var UIController = (function() {
//Some UI based Code
})();
var controller = (function(budgetCtrl, UICtrl) {
var z = budgetCtrl.publicTest(5);
return z;
})(budgetController, UIController);
console.log(controller); // Should return the value of 'z' [My Confusion/Misconception lies here]
console.log(budgetController); // Returns a Object
since you are passing params to publicTest, you should return the value to store it in Z variable
var budgetController = (function() {
var x = 23;
var add = function(a) {
return x + a;
};
return {
publicTest: function(b) {
console.log(add(b));
return add(b);
}
};
})();
var UIController = (function() {
//Some UI based Code
})();
var controller = (function(budgetCtrl, UICtrl) {
var z = budgetCtrl.publicTest(5);
return z;
})(budgetController, UIController);
console.log(controller); // Should return the value of 'z' [My Confusion/Misconception lies here]
console.log(budgetController);

Object function scope

factory(n) returns objects with functions.
func1 function definition creates its own scope, and x inside this function references x = n + ''.
But func2 is a reference and the scope is wrong.
Is there a way to return an object from create so its functions were references (not separate definitions)?
Actually, I'm fine with func1 approach while function definition footprint is small. If it is a complex function it would be better not to clone this function into every object comming from factory(n). inner_func may not use this, it is simple function. Also I want to avoid new and this.
var factory = (function(){
var x = '!';
return function create(n){
var x = n + '';
return {
func1: function(y){return inner_func(x, y); },
/* vs */
func2: inner_func_api
}
}
function inner_func_api(y){ return inner_func(x, y); }
function inner_func(a, b){ return a + b; }
}());
var f1 = factory(2);
var f2 = factory(3);
var f1_func1 = f1.func1(4);
var f2_func1 = f2.func1(5);
var f1_func2 = f1.func2(4);
var f2_func2 = f2.func2(5);
console.log(f1_func1, f2_func1); //24 35
console.log(f1_func2, f2_func2); //!4 !5
You could define that function separately from the object initializer on the return statement:
var factory = (function(){
var x = '!';
return function create(n){
var x = n + '';
function func1(y) {
return inner_func(x, y);
}
return {
func1: func1,
/* vs */
func2: inner_func_api
}
}
function inner_func_api(y){ return inner_func(x, y); }
function inner_func(a, b){ return a + b; }
}());
However, it makes no practical difference, and it doesn't matter how big or complicated that function is. Function instances do take up space, but the code for the function is constant (immutable) and doesn't need to be part of every Function object created from the same piece of source code.

How to define a javascript internal method that needs to be accessible from inside obj and out

I'm trying to fully grasp JavaScript inheritance and encapsulation. Take the following example (and here is a fiddle of it):
myPage = {
someObj: function() {
var x = 0;
//PRIVATE: increment by 10
var inc10 = function() {
x = x+10;
};
//PUBLIC: increment
this.inc = function() {
x = x+1;
};
//PUBLIC: decrement
this.dec = function() {
x = x-1;
};
//PUBLIC: output the current value of x
this.getValue = function() {
return x;
}
inc10(); //as soon as obj1 is created lets add 10
this.inc(); //as soon as obj1 is created lets add 1 more
}
};
obj1 = new myPage.someObj(); //x starts out at 11
// obj1.inc10(); won't work because it's private, excellent
obj1.dec();
obj1.inc();
alert(obj1.getValue());
My question is about the inc() method. I need it to be callable from inside and outside of the object. Is this the proper way to do that?
I need it to be callable from inside and outside of the object. Is this the proper way to do that?
Your script does seem to work as expected already, you are calling the method as this.inc() in your constructor perfectly fine - not sure why it needs improvement.
You could however define it as a local function, which you then are going to export as a method - and have it still available "inside" as a local variable:
function SomeObj() {
// local declarations:
var x;
function inc10() {
x = x+10;
}
function inc1() {
x = x+1;
}
// exported as property:
this.inc = inc1; // <== the function from above, not a literal
this.dec = function() {
x = x-1;
};
this.getValue = function() {
return x;
};
// initialisation:
x = 0;
inc10();
inc1(); // this.inc() would still work
}
To call function from inside and outside without attaching it to an obj.
This should work ...
myPage = function() {
var x = 0;
//PRIVATE: increment by 10
var inc10 = function() {
x = x+10;
};
//PUBLIC: increment
this.inc = function() {
x = x+1;
};
//PUBLIC: decrement
this.dec = function() {
x = x-1;
};
//PUBLIC: output the current value of x
this.getValue = function() {
return x;
}
inc10(); //as soon as obj1 is created lets add 10
this.inc(); //as soon as obj1 is created lets add 1 more
};
obj1 = new myPage; //x starts out at 11
// obj1.inc10(); won't work because it's private, excellent
obj1.inc();
alert(obj1.getValue());

how can i implement this logic add(1)(2)(1).. upto (n)?

I know this question is already answered with limited capability but I want it with n number of time with n arguments?
function add(x) {
return function(y) {
if (typeof y !== 'undefined') {
x = x + y;
return arguments.callee;
} else {
return x;
}
};
}
add(1)(2)(3)(); //6
add(1)(1)(1)(1)(1)(1)(); //6
problem is this works only when I add extra empty brackets ()
it doesn't work if do this add(1)(2)(3)
reference question
Try this:
function add(x) {
var fn = function(y) {
x = x + y;
return arguments.callee;
};
fn.toString = function(){ return x; };
return fn;
}
The following code works exactly like you asked:
function add(a)
{
var c=a,b=function(d){c+=d;return arguments.callee;};
b.toString=function(){return c;}return b;
}
Do note that some operations will detect the result given as a function, but any functions that require a string or integer will see the proper value.
Try sending your numbers as an array and changing your function code to reflect these changes.
Note: Code untested.
function add(x) {
var result = 0;
for (i = 0; i < x.length;i++){
result+=x[i];
}
return result;
}
add(new Array(1,2,3));

call javascript object method from html

I'm relatively new to Javascript programming. I'm working on an example and am having difficulty in invoking a method on an object from HTML. I suspect this has something to do with the scoping or externalization of the methods, but I'm not sure.
index.html:
<script type="text/javascript">
var f = new Fred();
f.bar();
f.foo();
</script>
Fred.js:
function Fred() {
this.a = 1;
function foo() {
if (a == 1) {
a++;
}
var e = 0;
}
this.bar = function () {
var a = 3;
var b = 4;
};
this.c = 3;
this.d = 4;
}
The call to bar() works, the call to foo() does not.
Yes, you are right, this does have to do with scoping and the concept of closures. You can think of the foo() function as being a "private" method if you are familiar with other object oriented languages like Java or C#. It is only available inside the scope of your Fred() object. The bar() function is "public" in the sense that declaring it with this.bar adds it to the publicly available properties of your Fred() object. So, to also make foo() "public", then declare it as:
this.foo = function () {
if (a == 1) {
a++;
}
var e = 0;
}
For a more in depth explanation of closures in javaScript, try this link: http://www.sitepoint.com/javascript-closures-demystified/
your not assigning a function pointer to foo. Change it to
this.foo = function() {
if (a == 1) {
a++;
}
var e = 0;
};
like you've done:
this.bar = function () {
var a = 3;
var b = 4;
};

Categories