double double parentheses javascript - javascript

I found this code in a book:
function foo() {
console.log( this.a );
}
var a = 2;
var o = { a: 3, foo: foo };
var p = { a: 4 };
o.foo(); // 3
(p.foo = o.foo)(); // 2
What does last line mean?

The last line is doing an assignment and then calling the function.
Assignment happens first
(p.foo = o.foo)
Then call the function
(p.foo = o.foo)();
In this second call to foo, it is being called outside of the scope of p or o, so it's essentially the same as calling:
foo();

Related

Anonymous arrow functions in objects [duplicate]

This question already has answers here:
Why does the logical or operator (||) with an empty arrow function (()=>{}) cause a SyntaxError?
(3 answers)
Closed 2 years ago.
How is it that this syntax works:
let foo = 0; // or 1
let bar = {
foo: foo || function (x) { return 'foo ' + x; }
};
// If foo is 0
bar.foo('bar'); // Returns 'foo bar'
// If foo is 1
bar.foo; // Returns 1
and this one doesn't:
let foo = 0; // or 1
let bar = {
foo: foo || (x) => { return 'foo ' + x; }
};
If I try to run the bottom example, I get the Malformed arrow function parameter list error in the console. How is it Malformed, and what would the correct syntax be to get the same functionality as the top example?
The issue is that the arrow function doesn't know how to group the parameters. You should wrap the function in parenthesis as such:
let foo = 1
let bar = {
foo: foo || (x => { return 'foo ' + x; })
};
I did'nt use js for a while but I think
let bar = {
foo: foo || (x => { 'foo' + x })
};
should do the job
greetings

function is being invoked even though it's not being called in javascript

I came across this problem where I'm not calling the function f(), yet the object 'obj' is invoked even though we also aren't doing anything with 'obj'. The value of x to 11.
Does it invoke the function f() when attempting to set obj.g to a value?
var x = 10;
function f () {
console.log(x); //logs 10
x = x + 1;
console.log(x); //logs 11
return x;
}
var obj = {
func: f,
g: f(),
};
console.log(x); // logs 11
With g: f() you are actually invoking the function. Specifying () after a function without function body ({..}) will execute the function immediately. Just remove the parenthesis after the function name:
var x = 10;
function f () {
console.log(x); //logs 10
x = x + 1;
console.log(x); //logs 11
return x;
}
var obj = {
func: f,
g: f,
};
console.log(x); // logs 10
Does it invoke the function f() when attempting to set obj.g to a
value?
Yup!
f is invoked when assigning obj.g.
You're assigning obj.g to the return value of calling f with no arguments. To get the value, the function (f) has to be invoked.
console.log(obj.g); // 11

How to global a js var in a function?

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();

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());

How to turn an undefined var to an object, inside a function

There is something I can't find an answer or an explanation for. Let's take for example the following code:
function fn(x){
x = {value: 10};
}
var a;
fn(a);
alert(a.value); //a is undefined
Shouldn't a = {value: 10}; as we passed it through that function?
The x is locally scoped. You are passing only values and not references. So you might need to return and assign like this:
function fn(x){
x = {value: 10};
return x;
}
var a;
a = fn(a);
From an awesome article:
When passing in a primitive type variable like a string or a number, the value is passed in by value. This means that any changes to that variable while in the function are completely separate from anything that happens outside the function.
function myfunction(x)
{
// x is equal to 4
x = 5;
// x is now equal to 5
}
var x = 4;
alert(x); // x is equal to 4
myfunction(x);
alert(x); // x is still equal to 4
Passing in an object, however, passes it in by reference. In this case, any property of that object is accessible within the function.
function myobject()
{
this.value = 5;
}
var o = new myobject();
alert(o.value); // o.value = 5
function objectchanger(fnc)
{
fnc.value = 6;
}
objectchanger(o);
alert(o.value); // o.value is now equal to 6

Categories