How to global a js var in a function? - javascript

It is possible to global a variable inside a function, if not, how can I access a var in function b from function a.
var money;
var moneyInput = document.getElementById('input');
function check(){
if (moneyInput.value == "") {
money = 100;
}
function hit() {
document.write(money) // will this money var be 100 or undefined?
}

Just declare that variable outside function and then use it inside of that function.
P.S Please, post some code that you tried already.
let a = 5;
let b = 0; // Declare global variable
function printAB(_b) {
b = _b; // Set new value through this function
console.log(a, b);
}
function printBC() {
let c = 7;
console.log(b, c); // Get b variable
}
printBC(); // 0, 7 // b = 0
printAB(2); // 5, 2
printBC(); // 2, 7 // b = 2
Edit
With code you provided, answer is simple. Variable money can be equal 100 or be undefined, that depends if function hit will be called before function check.

If you assign a value to an undeclared variable in a function it will be created as a global variable.

You should declare the variable outside of the function scope:
var myGlobalVar = "foo";
function a(){
var myLocalVar = 'bar';
alert(myGlobalVar); //shows foo
alert(myLocalVar); //shows bar
}
function b(){
var myLocalVar = 'baz';
alert(myGlobalVar); //shows foo too
alert(myLocalVar); //shows baz
}

Assign a variable without using var, let, or const
var foo = 'bar';
function fn() {
console.log(foo);
bar = 'xyz';
}
fn()
console.log(bar)
Repl: https://repl.it/languages/javascript

You can assign a value to the global object ( window in browsers):
function a(){
window.test="test";
}
function b(){
console.log(test);
}
a(),b();

Declaring the variable on the outer scope and using it inside should solve your problem. However if you insist on creating a variable on the global scope you can do the following;
window.VAR_NAME = 'foo';
By doing so you are actually creating a global variable VAR_NAME and it now has the value foo.

/* 1 */
var a = 'sample text';
function one() {
a = 'modified text';
}
function two() {
console.log(a);
}
one();
two();
/* 2 */
function one(callback) {
var a = 'sample text callback';
callback(a);
}
function two() {
one(function(a) {
console.log(a);
});
}
two();
/* 3 */
var one = new Promise(function(resolve, reject) {
var a = 'sample text promise';
resolve(a);
});
function two() {
one.then(function(a) {
console.log(a);
});
}
two();
/* 4 */
var myGlobals = {};
function one() {
myGlobals.a = 'sample text';
}
function two() {
console.log(myGlobals.a);
}
one();
two();

Related

Javascript accessing scope by using bind

why this logs 1 and not 2 ? i am trying to pass this scope to initData function but no success. after running init i should trigger iniData but this should refer to the object itself not to a new scope
let startFunction = function (){
let initData = () => {
this.x = 2
}
return {
x:1,
init:initData.bind(this)
};
};
obj=startFunction()
obj.init();
console.log(obj.x); // should be 2
update:
let startFunction = function (){
let initData = function(){
this.x = 2
}
return {
x:1,
init:initData
};
};
obj=startFunction()
obj.init();
console.log(obj.x); // should be 2
and why this works ? shouldn't the function create a new scope ?
There are two issues here. The first issue is that arrow functions are immutably bound to their execution context. Function.prototype.bind has no effect on an arrow function. The second issue here is what this refers to when you call startFunction. When you invoke a function freely, without a binding to a particular object, this refers to the object in which the function is invoked. So this refers to the global object in initData permanently.
So let's think about the value of obj and the global object's x value after each line.
After obj=startFunction:
// global x is undefined
// obj
{
x: 1,
init: initData // with the same binding to the global object
}
After obj.init(), initData sets the global object's x value to 2:
// global x is 2
// obj
{
x: 1,
init: initData // with the same binding to the global object
}
Problem you are facing is the x in the object has nothing to do with the this.x that is being assigned in the init method. You need to set an object and in the init code adjust that object.
let startFunction = function() {
const initData = () => {
data.x = 2
};
var data = {
x: 1,
init: initData,
};
return data;
};
const obj = startFunction()
obj.init();
console.log(obj.x);
Better solution, use a proper class.
class MyClass {
x = 1;
init() {
this.x = 2;
}
}
const obj = new MyClass();
obj.init();
console.log(obj.x);
class MyClass2 {
x = 1;
constructor() {
this.x = 2;
}
}
const obj2 = new MyClass2();
console.log(obj2.x);

Why is the 'this' value different in Javascript?

var obj = {
a: 2,
}
var a = 3;
const func = () => {
console.log(this.a);
}
function test() {
setTimeout(func, 100);
}
function test2() {
setTimeout(() => {
console.log(this.a);
}, 100);
}
test.call(obj); //3
test2.call(obj); //2
It seemed that the test and test2 are the same, but the returned result is different, what's the problem with 'this'?
with test arrow function, this will refer to the window object, and as var a = 3, the a will be assigned as a property to the window, it will be like
window.a
But in test2 this will refer to the obj object.

javascript equivalent way of passing variable to anonymous function

In php we can do something like this:
$foo = 1;
$bar = 2;
$fn = function() use ($foo, $bar) {
return $foo;
};
$foo = 3;
echo $fn(); // gives 1
How to do it in javascript?
I try it like this, but failed:
var foo = 1;
var bar = 2;
var fn = function() { return foo; }.bind(foo,bar);
foo = 3;
console.log(fn()); // gives 3, instead of 1
bind is a method to explicitly define the this value and the values passed to the initial arguments of the function.
The arguments that can be passed to a function are defined when the function is created.
var fn = function(foo) { console.log(foo) }
JavaScript doesn't have any features to modify what arguments a function accepts after it has been created.
The scope of a function is also defined when it is created and can't be changed later. If you don't shadow foo with an argument name, then it will read foo from the scope it is defined in.
var foo = 1;
var fn = function(foo) { return foo; }.bind({}, foo);
foo = 3;
console.log(fn());
or through context
var foo = 1;
var fn = function() { return this.foo; }.bind({foo});
foo = 3;
console.log(fn());

Calling inner function in Nested Scopes in JavaScript

I'm learning JS and am wondering, is there a way to return the function bar() or buz() by without returning foo()? For example, if I wanted to return the function bar(); to get 2, could I do that? Would it be something like foo().bar(); ?
// Nested Scopes
function foo() { // can only access itself
var a = 1;
function bar() { // access to foo(), not buz()
var b = 2;
function buz() { // access to bar() and foo()
var c = 3;
console.log(a, b, c); // 1, 2, 3
}
buz();
console.log(a, b); // 1, 2
}
bar();
console.log(a); // 1
}
foo(); // 1
Certainly. You can return an object at each stage which holds the function, or you can return the function itself. This utilizes what's called a closure.
function foo() {
var a = 1;
function bar() {
var b = 2;
function buz() {
var c = 3;
console.log(a, b, c);
}
console.log(a, b);
return { buz: buz };
}
console.log(a);
return { bar: bar };
}
foo().bar().buz();
You can do this, but it’s quite over-complicated.
The basic syntax is:
foo().bar().buz();
Where-ever you add another () after an existing one, it’ll print that level out. See the snippet for examples.
// Nested Scopes
function foo() { // can only access itself
var a = 1;
function bar() { // access to foo(), not buz()
var b = 2;
function buz() { // access to bar() and foo()
var c = 3;
return (function() {
console.log(a, b, c);
});
}
return (function() {
var tmp = function() {
console.log(a, b);
return {
buz: buz
};
};
tmp.buz = buz;
return tmp;
})();
}
return (function() {
var tmp = function() {
console.log(a);
return {
bar: bar
};
};
tmp.bar = bar;
return tmp;
})();
}
foo().bar().buz(); // (nothing)
foo().bar()().buz(); // 1, 2
foo()().bar()().buz(); // 1 // 1, 2
foo()().bar().buz()(); // 1 // 1, 2, 3
foo()().bar()().buz()(); // 1 // 1, 2 // 1, 2, 3
This kind of abuses the fact that you can assign properties to anything in JavaScript, including functions.
foo is a function that refers to the outer foo.
foo() is another function that refers to that inner tmp which has a bar property that refers to the inner bar function.
foo()() actually calls that inner tmp function but still leaves you with an object that has a bar property that again refers to the inner bar function.
This approach is basically the same for bar.
For buz, however, (something).buz() is just a function, without any extra properties and (something).buz()() doesn’t return anything, because that’s the final level.
you do this more like setting a variable.
var foo = {
bar: function() {
return 3;
}
}
console.log(foo.bar());

Javascript accessing object variable from another callback without placing variable in global scope

I have the following scenario. I have an object 'a' with two callback methods however one callback requires access to the other callback variable value (for modifications / to read value / update value). I would like to know what is the best approach to structuring this code without placing the variable b into global scope. Under is the code and a jsfiddle.
Code
var a = {
load: function(){
var b = 25;
console.log(b);
},
add : function (b){
console.log('The value of b is '+ b);
}
};
Use a closure:
var module = (function () {
var b; //Scoped to this module
return { //Return object with methods
load: function () {
b = 25; //This refers to the module's b
console.log(b);
},
add: function () {
console.log('The value of b is '+ b);
}
};
})(); //Self invoking function, invokes instantly.
module.load(); //b is now 25.
module.add(); //The value of b is 25
console.log(b); //undefined, out of scope.
Now all the "private" variables are scoped directly to the module, and don't affect global scope.
// Alternative 1: Using a "private" variable
function A(b) {
// seal b in closure
var b = b;
this.load = function(){
b = 25;
console.log(b);
};
this.add = function(){
console.log('The value of b is '+ b);
};
this.getB = function(){
return b;
};
}
// Alternative 2: Using a object property
function A(b) {
// seal b in closure
this.b = b;
this.load = function(){
this.b = 25;
console.log(this.b);
};
this.add = .add = function(){
console.log('The value of b is '+ this.b);
};
}
var a = new A('foo');
var callback = a.load;
// ...

Categories