Why I am getting different output when accessing inner function in JavaScript? - javascript

Here is my code
function first() {
console.log("first")
return function second() { return console.log("second") }
}
let foo = first() // It is outputing "first" once
foo() // Output is "second"
first()() // Output is "first" "second"
What I do not understand is why foo() is giving a different output comparing to first()(). If foo = first(), then I think it should have the same output.
The second question (and less important) is: how can I avoid the output when assigning the variable let foo = first() ?

It's because you are not assigning first to foo when you do first(), you are calling first. When first is called, it logs "first" to the console and then it returns the function second. So foo gets assigned the return value of first which is the function second.
Assigning first to foo
You can assign the function first to foo via normal assignment without calling it:
let foo = first; // now foo === first
Assigning the returned function second to foo
let foo = first(); // note the use of (); now foo === second
Immediately calling the returned function
In the last line, you are doing two things in one line. The first first() (no pun intended) returns the second function (and thereby executes the console.log statement) which is immediately called via () (and executes the other console.log statement). That's why you see it logging "first"and "second".
let foo = first()(); // note the doubled use of (); now, foo === undefined
Whatever are we doing here?
Although it might seem a bit strange at first, the technique of passing and/or returning a function to/from another function is very useful - so much that it has a name: Higher Order Function (or - as I like to call it - HOF).
One pretty common example of a HOF is Array.prototype.map. When you pass a function to .map, it projects the function onto every element in the array and collects the resulting value of each projection into a new array which it finally returns.
A concrete example of a HOF besides .map: Suppose you have to call .split on different input strings that come from different sources but you always want to split the strings on the same character. Create a makeSplitter HOF:
function makeSplitter(splitOn) { // <-- HOF
return function (inputString) { // <-- return value of HOF
return inputString.split(splitOn);
}
}
With this, you can create a general function that splits an input string, say, by slash:
const splitSlashes = makeSplitter(/\//g);
You can think of splitSlashes as if it had been written like so:
const splitSlashes = function (inputString) {
return inputString.split(/\//g);
}
And now you can use that to split various strings that contain slashes into separate parts:
console.log(splitSlashes('08/12/2022')); // logs ['08', '12', '2022']
console.log(splitSlashes('www.example.com/path/to/x/')); // logs ['www.example.com', 'path', 'to', 'x']
If you need another function that - for example - splits a string on ., just use makeSplitter with another argument:
const splitDots = makeSplitter(/\./g);

Output of a function is a value in return statement but not console.log in a function body
function first() {
return function second() { return 'second' }
}
let foo = first() //now a function is in foo variable
foo() // "second"
first()() // "second"
the same output in both cases

Related

I expect this code to return undefined but it return function instead

I expect this code to print undefined, but it prints function instead. Can anyone tell me why? I am new in JS.
function createGreeter(greeting){
function greet(){
console.log(greeting,name)
}
return greet
}
let g1=createGreeter('Good Morning')
console.log(typeof g1)
let g2=createGreeter('Good Evening')
So it looks like you want to create a function that accepts a greeting but returns another function that accepts a name (while maintaining a pointer to the variable (greeting) in its outer lexical environment when its returned) and returns the result of joining up those strings when it's called.
// `createGreeter` accepts a string and
// returns a new function that accepts a name
// and when that function is called ties both strings together
function createGreeter(greeting) {
return function (name) {
return `${greeting}, ${name}.`;
}
}
// Both of these return a function that accepts a name
const goodevening = createGreeter('Good evening');
const expectingyou = createGreeter('I\'ve been expecting you');
// And now we just need to call those functions with the name
console.log(goodevening('Blofeld'));
console.log(expectingyou('Mr. Bond'));
You are returning inside the function greet the function itself
If you want to store in a var the result of greet function then you must call it:
Instead of return greet you should return greet()
The code says return greet on line 5. The value of greet is the function greet itself. You may want to change line 5 to return greet(), which would execute the greet() function and then return the return value of greet(), which itself is undefined.

Difference between using arrow functions to declare method and function() when assigning the method to a variable?

If I have the following code:
let myObject = {
greeting: "Hi",
greet1(message) {
return(console.log(`${this.greeting} ${message}`));
},
greet2() {
return(message => console.log(`${this.greeting} ${message}`));
}
}
greeting = "Hello";
anotherGreet1 = myObject.greet1;
anotherGreet1("It is sunny today");
anotherGreet2 = myObject.greet2(); // Why is there a parenthesis here?
anotherGreet2("It is raining today"); // Doesn't run unless previous line has ()
Why is it that when I assign anotherGreet1 with the function greet1 I don't need to use parentheses, but to assign greet2 to anotherGreet2 I need to use parenthesis? I understand that in assigning a function to a variable I want to assign the entire function and not just it's return value. This logic makes sense for greet1 but doesn't hold for greet2.
Your greet1 is function that first processes console.log(...) and only then returns it's value as string: myObject.greet1()
Your greet2 if function that returns another function. You must call that function once more to be able to get output of console.log(...): myObject.greet2()()

Why pass an undefined javascript function parameter?

So I'm learning Javascript and I see this code:
var apple = {//... an object with some properties};
var fruit = apple.someMethod(function (b) {return b.a_property_of_apple});
Where someMethod and a_property_of_apple are valid methods and properties.
My question pertains to the argument, b, of the anonymous function which is not declared or defined anywhere else:
function (b) {return ...
What is going on here? What is b and why is it being used?
Apologies in advance for the basic nature of the question. If someone just wants to drop some focused terms on me to read up on that would be great short of an explanation.
The anonymous function is a callback function being passed to the apple.method() invocation.
apple.method() will invoke that anonymous function at some point during it's execution, ( or pass it to another function ). Whenever it's invoked it will be invoked with an argument that will be available inside the callback. You could call it b, or response, or whatever you want (logical names are best) and be able to use it within the anonymous function.
You should read about Callback functions over at MDN.
EDIT: I will explain the parts to you
var apple = {} This is the definition of an object
var fruit = apple.someMethod(function (b) {return b.a_property_of_apple}); is defining that fruit is equal to the return value of the invocation of apple.someMethod(...)
apple.someMethod(function (b) {return b.a_property_of_apple}); is the invocation of apple.someMethod with function (b) {return b.a_property_of_apple} as the only argument.
The b argument in the anonymous function function (b) {return b.a_property_of_apple} will be passed to it's invocation within the apple.someMethod.
Here is an example snippet.
// define apple
var apple = {
// define method
someMethod: function( callback ) {
var obj = {
a_property_of_apple: "Eat me!" // this will be returned
}
// return the invocation of callback with obj as argument
return callback(obj);
}
}
var fruit = apple.someMethod(function (b) {return b.a_property_of_apple});
console.log(fruit);
EDIT: Ok, going to use something slightly less abstract as an example.
// notice employees being passed to this function
// that is called an argument and is usable inside the function
var orginization = function( employees ) {
// this will take the empoyees argument and assign it to this.employees
// or set this.employees to an empty array if there is no employees argument
this.employees = employees || [ ];
// this is a method ( a method is a function on an object )
// this function takes 3 arguments
this.addEmployee = function( employee ) {
// we use the 3 arguments to push a new object with title, name, and salary
// properties provided by the function arguments
this.employees.push( employee );
}
// this method returns the value stored in this.employees
this.getEmployees = function() {
return this.employees;
}
}
// this is a variable an array of employees only containing 1 employee
// i will use it in the creation of my new orginization
var employess = [
{
title: "CEO",
name: "Enola",
salary: "$$$$$$$"
}
];
// i use the new to create learningInc from originization( employees )
// originization is a constructor function which creates an object
// with methods and properties found on the constructor
var learningInc = new orginization( employess );
// console.log learningInc.getEmployees() an you will see still only the CEO
// works here
console.log( "before newHire: ", learningInc.getEmployees() );
// lets make a newHire
var newHire = {
title: "Peon",
name: "Sadly McFrownFace",
salary: "$"
};
// add the newHire to the employess of learningInc wth out getEmployees() method
learningInc.addEmployee( newHire );
// log the new value of learningInc.getEmployees and you see we now have 2 employees
console.log( "after newHire: ", learningInc.getEmployees() );
Ok now notice this line var learningInc = new orginization( employess );
The employees variable I'm passing to this function as an argument is used in this function var orginization = function( employees ) { ... }.
Hope this help.
My question pertains to the parameter, b, of the anonymous function which is not declared or defined anywhere else: What is going on here?
What is b and why is it being used?
Why you say it is not declared? It is declared right there. Consider this simple JavaScript function:
function doSomething(a, b){
//do something here;
}
In this code, we are creating a function, naming it "doSomething", and declaring two parameters for it a and b. This is how we declare function parameters in JavaScript. Now your example:
function (b) {return ...
is exactly the same, except we didn't give this function a name, which means it is an anonymous function. That's the only difference, but its parameter b is declared right there like any standard function. So there is nothing special going here, it's a standard function parameter and used as such.
There are a couple concepts at work here
Function declarations vs function expressions; you can use function as an operator to define a function, and assign the function to an identifier and pass it around like any normal object
Callbacks; you can pass a function CB into another function A to be called by A (as defined by A)
Passing something without an identifier
Function Declaration
// declare function
function foo(argFoo) {
console.log('foo', argFoo);
}
// invoke function
foo('was declared'); // "foo" "was declared"
Function Expression
// express function
var bar = function (argBar) {
console.log('bar', argBar);
};
// invoke function
bar('was expressed'); // "bar" "was expressed"
Callbacks
function fizz(callback) {
console.log('first I fizz');
callback();
}
function buzz() {
console.log('then I buzz');
}
fizz(buzz);
// "first I fizz"
// "then I buzz"
Passing without an Identifier,
Basically, defining things in-place
// say we have some fn fizzbuzz
function fizzbuzz(foo) {
console.log(foo);
}
// we could pre-define what we want to pass to it
var i = 1;
fizzbuzz(i); // 1
// or we could pass directly
fizzbuzz(1); // 1
// with anything we like
fizzbuzz({some: 'object'}); // {some: "object"}
// even a function
fizzbuzz(function () {}); // function () {}
Maybe if I break down what is happening into more readable code, you can see what is happening.
someMethod is a method that take a function as an argument. This is more easily seen when broken down like below.
It's up to someMethod to determine what they do with that function. In this example, I am executing the function being passed into someMethod and passing it my this context.
var apple = {
name: 'Apple',
someMethod: function(func) {
return func(this);
}
};
function getName (b) {
return b.name;
};
const name = apple.someMethod(getName); // Apple
To your question: b is defined as the first argument to your anonymous function. This is more clearly expressed when the code is broken out above. But you could also express it like this:
const name = apple.someMethod(function(x) { return x.name; }); // Apple
or like this using ES6:
const name = apple.someMethod(x => x.name); // Apple

javascript about AOP

review my code make it print expected result thax
var Obj = (function () {
var b = 'b',
_f = function () {
// print arguments
Array.prototype.push.call(arguments,b);
console.log(arguments,b);
}
return {
f:_f
};
})();
//rewrite Obj.f
Obj.f = function () {
// add parameters dynamically
Array.prototype.push.call(arguments,333);
// it dose not work
Obj.f.apply(Obj.f,arguments);
}
//when I rewrite Obj.f how to make it print result below
// expected result print 111 333 'b'
Obj.f(111);
// expected result print 666 333 'b'
Obj.f(666);
// expected result print 444 333 'b'
Obj.f(444);
If you want the new version of f() to be able to call the original version of f() that was overwritten then you need to save a reference to the original version. Here's one way to do that:
//rewrite Obj.f
Obj.f = (function() {
var originalF = Obj.f;
return function () {
// add parameters dynamically
Array.prototype.push.call(arguments,333);
// Call original:
originalF.apply(this,arguments);
}
})();
That is, use an IIFE to give you some private scope for the originalF variable and then use that variable from within the new function. (This structure is similar to what you were already using to create your Obj in the first place.)
Note also that the first argument to .apply() sets the value of this within the function being called, so you probably just want to pass this through rather than passing Obj.f, so that the original function gets the same this as the new function. (It doesn't actually matter in your specific example, because your function doesn't use this at all, but still for future reference that's the most logical approach.)

What is the difference in the following JS syntax?

Following are two ways to define BW.Timer. Can someone tell me what the difference is? I am not certain the first is even valid, but if it is valid, what is different about using the myfunc=(function(){}()) syntax?
BW.Timer = (function () {
return {
Add: function (o) {
alert(o);
},
Remove: function (o) {
alert(o);
}
};
} ());
And...
BW.Timer = function () {
return {
Add: function (o) {
alert(o);
},
Remove: function (o) {
alert(o);
}
};
};
The first is the return-value of the immediately-invoked function. The second is a function. It essentially comes down to what the difference is between these:
var f = (function() { return 0; })();
var f = function() { return 0; };
Since the first function is called immediately, the value of 0 is given to the variable f. The first f is not a function. However, the second f we must call in order to get the value:
f(); // 0
It follows that in your example, the first BW.Timer is the object literal itself and the second is a function returning an object literal. You must call the function in order to get to the object:
BW.Timer().Add(x);
Why use the first then?
You might ask yourself why one would use a syntax like a = (function() { return {}; })() instead of a = {}, but there's a good reason. An IIFE (Immeditately-Invoked Function Expression), unlike a regular function allows the emulation of static variables (variables that maintain their value through a single instance). For example:
var module = (function() {
var x = 0;
return { get: function() { return x },
set: function(n) { x = n }
};
})();
The above a text-book example of the Module Pattern. Since the function is called right away, the variable x is instantiated and the return value (the object) is given to module. There's no way we can get to x other than by using the get and set methods provided for us. Therefore, x is static, meaning its variable won't be overridden each time you use module.
module.set(5);
module.get(); // 5
On the other hand, let's see an example where module is declared as a function instead:
// assume module was made as a function
module().set(5);
module().get(); // 0
When we call module() the x variable is overridden each time. So we're effectively using different instances of module and x each time we call module.
The difference is rather large.
In the first case, BW.Timer is executed when it is first encountered, and that is the static version assigned to BW.Timer. In that instance, BW.Timer.Add(1) may be used. Each call to BW.Timer will be the same object.
In the second case, BW.Timer is not executed when first encountered, and instead is a function referece which must be invoked BW.Timer(). For Add to be used, this must be the case BW.Timer().Add(1). Also, you can issue var timer = new BM.Timer();. Each instance of BW.Timer() will be unique here.
In the first example BW.Timer references an object that the self-executing function returns, while in the second example it references a function object, in other words it's a function that can be executed BW.Timer().

Categories