Given the following function:
function countdown() {
var result = "";
// do something with the result variable
return result;
}
How can result variable be updated from within another function, before calling the countdown function?
function something(){
// update private variable "result"
}
function countdown(modifiedResult) {
var result = "";
// do something with the result variable
result = modifiedResult;
return result;
}
function something(modifiedResult){
// update private variable "result"
var updatedResult = countdown(modifiedResult);
alert(updatedResult);
}
something("I am updated value");
The variable result is private, and cannot be accessed from the outside.
One solution is to wrap the whole thing in a factory:
function countdownFactory () {
var result = 0;//since its named countdown i assumed it should be a number
return {
get: function () { return countdown},
set: function (value) {countdown = value}
};
}
To use this you would do:
var countdown = countdownFactory();
countdown.set(2);
countdown.get() // returns 2
JavaScript doesn’t have keywords for defining if a variable/function/object is private/public/protected/final/etc (assessor keywords)… But since it has closures and each closure has its own scope we can emulate some of these access controls, a private variable is simply a variable declared inside an “unreachable scope”.
learn more ....
http://asp-net-by-parijat.blogspot.in/2015/08/private-variables-and-functions-in.html
A closure should do it, but you need some access to the function. Here in this case it is countdown.setResult(), which puts the value to private variable result.
var countdown = function () {
var result = '';
function countdown() {
return result;
}
countdown.setResult = function (r) {
result = r;
};
return countdown;
}();
function something(){
countdown.setResult(42);
}
alert(countdown()); // empty string
something();
alert(countdown()); // 42
Related
I want a function in JS, which can take some value at first call and set it to a variable inside it.
And then again on another call i want to again get the data of that variable.
something like this:
while calling the function for first time
function set_and_get(value){
var a = value;
}
on another call it should return the value like
returned_value = set_and_get()
Thanks.
Normally the pattern looks more like this where the function will return another function which you then would use.
function set_and_get(value){
return function () {
return value;
}
}
var test = set_and_get(1)
console.log(test())
var test2 = set_and_get(2)
console.log(test(), test2())
Now if the function can not be reused, aka once it is set, it is done. You could just overwrite the function. It is not the best practice, but it can work.
function set_and_get(value) {
set_and_get = function() {
return value;
}
return value
}
console.log(set_and_get(1))
console.log(set_and_get())
console.log(set_and_get(2))
While not necessarily recommended, you can attach a property to the function object itself:
function get_and_set(value) {
if (value !== undefined) {
get_and_set._value = value;
} else {
return get_and_set._value;
}
}
but note that the property is in no way protected - it is possible to read it (And overwrite it) from outside the helper function.
You would have to use a combination of concepts called closure and high order function.
var set_and_get_fn = function(value){
var a = value;
var set_and_get = function(){
return a;
}
return set_and_get;
}
var set_and_get = set_and_get_fn(10);
var returned_value = set_and_get();
// 10
set_and_get();
// still 10
set_and_get = set_and_get_fn(12);
set_and_get();
//12
set_and_get();
//12
Closure allows an inner function set_and_get to have access to the variables of it's outer function/context set_and_get_fn, even after set_and_get_fn has returned. set_and_get has closed over variable a. High order functions allows you to treat functions as objects, you can pass them as arguments and return them from functions. I'm returning set_and_get function from set_and_get_fn
var greet="Hello";
function Greet(Greetings=greet)
{
console.log(Greetings);
}
function Greet_Friend()
{
var greet="Hi";
Greet();
}
Greet_Friend();
I am having some problems in understanding the scopes in JavaScript?
On Running this code i get "Hello" as output but I need "Hi".
I know your logic, you want to use Greet() to log a variable that in other function, right?
var greet="Hello";
function Greet(Greetings=greet) {
console.log(Greetings);
}
function Greet_Friend() {
var greet="Hi";
// you forgot to pass the local variable to the log function
Greet(greet);
}
Greet_Friend();
In reality, we don't invoke Greet() directly in the Greet_Friend,we do this
var greet="Hello";
function Greet(Greetings=greet) {
console.log(Greetings);
}
function Friend() {
var greet="Hi";
return greet;
}
Greet(Friend());
Or use callback:
var greet="Hello";
function Greet(Greetings=greet) {
console.log(Greetings);
}
function Greet_Friend(callback) {
var greet="Hi";
callback(greet);
}
Greet_Friend(Greet);
var
The function Greet sets the default value of Greetings as greet.
var greet="Hello"; is a global variable thus the value of greet is always "Hello" unless overrridden during function call.
In your function Greet_Friend you call the function Greet without supplying any parameters, thus the function Greet takes the global variable with the value of Hello.
To get the value of "Hi", you would need to pass the local variable greet to the function Greet as follows
function Greet_Friend()
{
var greet="Hi";
Greet(greet);
}
Then call Greet_Friend as follows:
Greet_Friend()
No Global Variables
//greet takes a string as a parameter - you can call it anything, but no equals sign
function greet(str) {
console.log(str)
}
//greet_friend initializes the variable and sends it to greet
function greet_friend() {
var myGreeting = 'Hi';
greet(myGreeting);
}
function greet_friend(); // "hi"
I am a bit new to javascript, i was just trying the below snippet:
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}());
s = _getUniqueID();
console.log(s); // 1
console.log(_getUniqueID()); // 2
I was under the impression that i would have to do s() to get 1 as the result and i was thinking that _getUniqueID() returns a function rather than execute the funtion inside it. Can somebody explain the exact execution of this function please ?
What you're seeing here is a combination of Javascript's notion of closure combined with the pattern of an immediately invoked function expression.
I'll try to illustrate what's happening as briefly as possible:
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}()); <-- The () after the closing } invokes this function immediately.
_getUniqueID is assigned the return value of this immediately invoked function expression. What gets returned from the IIFE is a function with a closure that includes that variable i. i becomes something like a private field owned by the function that returns i++ whenever it's invoked.
s = _getUniqueID();
Here the returned function (the one with the body return i++;) gets invoked and s is assigned the return value of 1.
Hope that helps. If you're new to Javascript, you should read the book "Javascript, the Good Parts". It will explain all of this in more detail.
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}());
s = _getUniqueID();
console.log(s); // 1
console.log(_getUniqueID()); // 1
when you do () it calls the function,
a- makes function recognize i as global for this function.
b- assigns function to _getUniqueID
you do s = _getUniqueID();,
a - it assigns s with return value of function in _getUniqueID that is 1 and makes i as 2
when you do _getUniqueID() again it will call the return function again
a- return 2 as the value and
b makes value of i as 3.
This is a pattern used in Javascript to encapsulate variables. The following functions equivalently:
var i = 1;
function increment() {
return i ++;
}
function getUniqueId() {
return increment();
}
But to avoid polluting the global scope with 3 names (i, increment and getUniqueId), you need to understand the following steps to refactor the above. What happens first is that the increment() function is declared locally, so it can make use of the local scope of the getUniqueId() function:
function getUniqueId() {
var i = 0;
var increment = function() {
return i ++;
};
return increment();
}
Now the increment function can be anonymized:
function getUniqueId() {
var i = 0;
return function() {
return i ++;
}();
}
Now the outer function declaration is rewritten as a local variable declaration, which, again, avoids polluting the global scope:
var getUniqueId = function() {
var i = 0;
return (function() {
return i ++;
})();
}
You need the parentheses to have the function declaration act as an inline expression the call operator (() can operate on.
As the execution order of the inner and the outer function now no longer make a difference (i.e. getting the inner generator function and calling it, or generate the number and returning that) you can rewrite the above as
var getUniqueId = (function() {
var i = 0;
return function() {
return i ++;
};
})();
The pattern is more or less modeled after Crockford's private pattern
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}());
console.log(_getUniqueID()); // 1 , this surprised me initially , I was expecting a function definition to be printed or rather _getUniqueID()() to be called in this fashion for 1 to be printed
So the above snippet of code was really confusing me because I was't understanding that the above script works in the following manner, by the time the IFFE executes _getUniqueID is essentially just the following:
_getUniqueID = function () {
i = 1
return i++;
};
and hence,
_getUniqueID() // prints 1.
prints 1.
Note: please note that I understand how closures and IFFE's work.
Is it possible, while creating an instance of an object, to check during the instantiation itself the type of the parameter passed to the constructor, and set one of the object's variable accordingly?
This is what I'm trying to do:
function Test(num1) {
this.num1 = num1;
this.isValidNumber = (function() {
console.log(this.num1); // logs "undefined" upon instantiation
if (isNaN(this.num1)) {
return false;
} else {
return true;
}
}());
}
var testObj = new Test(5);
I want isValidNumber's value to be true or false according to the parameter passed to the constructor.
Your IIFE (Immediately-Invoked Function Expression) creates a new context, which means this doesn't point to your constructor anymore but to the Window object (unless you're using strict mode which would make it undefined). One possible solution is to execute this function with the right context:
this.isValidNumber = function() {
if (isNaN(this.num1)) {
return false;
} else {
return true;
}
}.call(this);
The much simpler solution is obviously:
function Test(num1) {
this.num1 = num1;
this.isValidNumber = !isNaN(this.num1);
}
First of all, the code could (and probably should) be rewritten the following way:
function Test(num1) {
this.num1 = num1;
console.log(this.num1);
this.isValidNumber = !isNaN(this.num1);
}
As for the reason why your code is not working as expected – your self invoking function has its own this parameter which is unrelated to the this parameter within your constructor.
In this case the this parameter of your self invoking function references the global object. (In strict mode it would've been undefined)
If you really need to reference the this parameter of a containing function then there are several ways to achieve this, the simplest of which being:
function Test(num1) {
this.num1 = num1;
var self = this;
this.isValidNumber = (function() {
console.log(self.num1);
return !isNaN(self.num1));
}());
}
In your particular case you don't even need to capture it, and this would also achieve the same effect:
function Test(num1) {
this.num1 = num1;
this.isValidNumber = (function() {
console.log(num1);
return !isNaN(num1));
}());
}
But again, the self invoking function is simply not required here.
This in the inner function no longer references the parent object. A common way of storing the object reference is to create a 'self' variable and assign this to it when it's in the correct scope
function Test(num1) {
var self = this;
this.num1 = num1;
this.isValidNumber = (function() {
console.log(self.num1);
if (isNaN(self.num1)) {
return false;
} else {
return true;
}
}());
}
var testObj = new Test(5);
I have the following piece of code:
function initValidation()
{
// irrelevant code here
function validate(_block){
// code here
}
}
Is there any way I can call the validate() function outside the initValidation() function? I've tried calling validate() but I think it's only visible inside the parent function.
function initValidation()
{
// irrelevant code here
function validate(_block){
console.log( "test", _block );
}
initValidation.validate = validate;
}
initValidation();
initValidation.validate( "hello" );
//test hello
Hope that you are looking for something like this
function initValidation()
{
// irrelevant code here
this.validate = function(_block){
// code here
}
}
var fCall = new initValidation()
fCall.validate(param);
This will work.
Hope this addresses your problem.
You can call validate from within initValidation. Like this.
function initValidation()
{
// irrelevant code here
function validate(_block){
// code here
}
return validate(someVar);
}
validate is not visible to anything outside of initValidation because of its scope.
Edit: Here's my suggestion of a solution.
(function() {
function validate(_block){
// code here
}
function initValidation()
{
// irrelevant code here
return validate(someVar);
}
function otherFunctions() {
// ...
}
// initValidation = function
}());
// initValidation = undefined
All of your functions will be hidden to anything outside the function wrapper but can all see each other.
This invocation will return function statement, which is function validate.
So you can invoke directly after the first invocation.
function initValidation() {
// irrelevant code here
return function validate(_block) {
// code here
}
}
initValidation()();
I know this is an old post but if you wish to create a set of instances that you wish to work with that reuse the code you could do something like this:
"use strict";
// this is derived from several posts here on SO and ultimately John Resig
function makeClassStrict() {
var isInternal, instance;
var constructor = function(args) {
if (this instanceof constructor) {
if (typeof this.init == "function") {
this.init.apply(this, isInternal ? args : arguments);
}
} else {
isInternal = true;
instance = new constructor(arguments);
isInternal = false;
return instance;
}
};
return constructor;
}
var MyClass = makeClassStrict();// create "class"
MyClass.prototype.init = function(employeeName, isWorking) {
var defaultName = 'notbob';
this.name = employeeName ? employeeName : defaultName;
this.working = !!isWorking;
this.internalValidate = function() {
return {
"check": this.working,
"who": this.name
};
};
};
MyClass.prototype.getName = function() {
return this.name
};
MyClass.prototype.protoValidate = function() {
return {
"check": this.working,
"who": this.name
};
};
var instanceBob = MyClass("Bob", true);// create instance
var instanceFred = MyClass("Fred", false);// create instance
var mything = instanceFred.internalValidate();// call instance function
console.log(mything.check + ":" + mything.who);
var myBobthing = instanceBob.protoValidate();
console.log(myBobthing.check + ":" + myBobthing.who);
I know this thread's been here for quite some time but I thought I'd also leave my 0.02$ on how to call inner functions from outside their scope (might benefit somebody).
Note that in any place, a better design decision should be taken into consideration rather than some hackish workaround which will bite you back later.
How about using function expressions instead of function statements and making use of the global scope.
var innerFn;
function outerFn() {
innerFn = function(number) {
return number ** 2;
}
}
outerFn();
console.log(innerFn(5));
// if there's more complex code around and you could write this defensively
if (typeof innerFn !== 'undefined') {
console.log(`we are squaring the number 5 and the result is: ${innerFn(5)}`);
} else {
console.log('function is undefined');
}
Or, you can make use of closures:
function outer() {
// initialize some parameters, do a bunch of stuff
let x = 5, y = 10;
function inner() {
// keeps references alive to all arguments and parameters in all scopes it references
return `The arithmetic mean of the 2 numbers is: ${(x + y) / 2}`;
}
return inner;
}
innerFn = outer(); // get a reference to the inner function which you can call from outside
console.log(innerFn());
Create a variable outside the parent function, then in the parent function store your required function in the variable.
Var Store;
Function blah() {
Function needed() {
#
}
Store = needed;
}
As a minor variation of Esailija's answer, I did this:
function createTree(somearg) {
function validate(_block) {
console.log( "test", _block );
}
if (somearg==="validate") { return validate; } // for addNodes
// normal invocation code here
validate(somearg);
}
function addNodes() {
const validate = createTree("validate");
//...
validate( "hello" );
}
createTree("create");
addNodes();
//validate("illegal");
so validate() is now perfectly shared between createTree() and addNodes(), and perfectly invisible to the outside world.
Should work.
function initValudation() {
validate();
function validate() {
}
}
Function definition:
function initValidation() {
// code here
function validate(_block){
// code here
console.log(_block);
}
return validate;
}
Call it as below:
initValidation()("hello");
function initValidation()
{
function validate(_block){
console.log(_block)
// code here
}
// you have to call nested function
validate("Its Work")
}
// call initValidation function
initValidation()