I get confuse about function while doing study javascript.
I think that's same thing about function.
What the difference?
var getCode = function() {
apiCode = '0]Eal(eh&2';
return function() {
return apiCode;
};
}
var getCode = (function() {
apiCode = '0]Eal(eh&2';
return function() {
return apiCode;
};
}();
It's the same difference as between f and f(). The former is a function (assuming f refers to a function), the latter is a function call.
The "II" part in IIFE means "immediately invoked", i.e. you don't just have a function expression, you immediately call it by putting () after it.
var getCode = function() {
apiCode = '0]Eal(eh&2';
return function() {
return apiCode;
};
}
This assigns function() { apiCode = '0]Eal(eh&2'; return function() { return apiCode; }; } to getCode.
var getCode = (function() {
apiCode = '0]Eal(eh&2';
return function() {
return apiCode;
};
}();
Here we have function () { ... }(), so this immediately calls the outer function and assigns the return value to getCode, which is function() { return apiCode; }.
Perhaps a simpler example:
var x = function () { return 42; }; // x is a function that, when called, returns 42
var y = function () { return 42; }(); // y is 42
Simply put, an IIFE executes the function once and puts the returning value to the variable.
E.g;
let res = (function sum(){
return 1+2;
})();
console.log(res);
On the other hand, function expression just holds a reference to the function and needs to be invoked.
E.g.;
let res = function sum(){
return 1+2;
};
console.log(res());
Related
I have a function, which calls another function and so on like
var fn1 = function() { return 'bar'; };
var fn2 = function() {
return fn1;
};
var fn3 = function() {
return fn2;
};
now this can keep on going.
Therefore I would like to recursively call a method, till I get a string/value i.e. the innermost return statement.
I tried like this:
function p (val){
var res = val;
while(typeof(res)=="function"){res = p()}
return res;
}
and calling it like p(fn2); but it doesn't seem to work. What am I missing.
You need to reassign the res (or val) inside the loop, then return it (don't return the p) at the end:
var fn1 = function() {
return 'bar';
};
var fn2 = function() {
return fn1;
};
var fn3 = function() {
return fn2;
};
function p(val) {
while (typeof val === "function") {
val = val();
}
return val;
}
console.log(p(fn3));
You can try this:
var fn1 = function() {
return 'bar';
};
var fn2 = function() {
return fn1;
};
var fn3 = function() {
return fn2;
};
function p(val) {
if (typeof val === "function") {
return p(val())
}
return val;
}
console.log(p(fn3));
Why this is working:
var a = () => {
var print = function(i) { console.log(i); return this; }
var print2 = function(i) { console.log(i); return this; }
return { print:print , print2:print2 }
}
a().print(5).print2(5);
this is also working:
var b = () => {
var print = (i) => { console.log(i); return this; }
return { print:print}
}
b().print('Arrow function works');
while this is not working:
var b = () => {
var print = (i) => { console.log(i); return this; }
var print2 = function(i) { console.log(i); return this; }
return { print:print , print2:print2 }
}
b().print(5).print2(5);
https://jsfiddle.net/Imabot/1gt2kxfh/14/
It's all due to arrow functions behavior(docs)
Step by step explanation:
var b = () => {
// 1
var print = (i) => { console.log(i); return this; }
var print2 = function(i) { console.log(i); return this; }
return { print:print , print2:print2 }
}
const res = b()
// 2
const secondRes = res.print(5)
// 3
secondRes.print2(5);
here print function saves this reference from the outer scope, so this can't be reassigned anymore
now print function is not using this reference that comes from res variable, because this has already been attached to print function above
as a result secondRes is not going to reference to the object that was returned by b function. But it will use this reference that is attached to print function. And finally because secondRes doesn't have print2 property - it throws
Hope it helps <3
In a non-arrow function, the value of this depends on how the function is called. If the function is called as a member of an object, this refers to this object:
someObj.myFunction() // inside myFunction this will point to someObj
In contrast, the arrow functions do not affect this. So whithin an arrow function the value of this is whatever it is in the enclosing scope.
The answer from Lex82 gives the why. If you want to return the functions, so you can use function chaining:
var b = () => {
var print = (i) => { console.log(i); return { print:print , print2:print2 }; }
var print2 = function(i) { console.log(i); return this; }
return { print:print , print2:print2 }
}
b().print(5).print2(5);
So I have 3 functions.
What i want to achieve is to take value from one function which is nested in parent function, and the pass it as the argument in third function.
And can this be achieved with closer, and how ?
Thanks so much.
function foo () {
var rand = 10;
function bar() {
return {
age:rand;
}
}
}
function addValue(arg) {
console.log(bar());
}
Call as below
function foo () {
var rand = 10;
return function bar() {
return {
age:rand
}
}();
}
function addValue(arg) {
console.log(foo());
}
Edited
function foo (func) {
var rand = 10;
function bar() {
return {
age:rand
}
};
//Do your stuff
return eval(func+"()");
}
function addValue(arg) {
console.log(foo("bar"));
}
You can instead assign the function to the parent object and call it like this.
function foo(){
var rand = 10;
this.bar = function(){
return {age: rand};
}
}
var obj = new foo();
function addVal() {
console.log(obj.bar());
}
addVal();
function test() {
alert(1);
return "hello";
}
Function.prototype.before = function (func) {
var __bself = this;
return function () {
if (func.apply(this, arguments) == false)
return false;
return __bself.apply(__bself, arguments);
}
};
test.before(function (){
alert(2);
})();
What is the meaning of if (func.apply(this, arguments) == false)?
I don't think the function will return false.
Functions can return any value. That includes false.
If your functions don't return false then the code inside that conditional will never run. So you can remove it, if it annoys you for some reason.
Here is an example with a function which returns false:
function test() { // This function is never called
console.log(1);
return "hello";
}
Function.prototype.before = function (func) {
var __bself = this;
return function () {
if (func.apply(this, arguments) == false){
return false;
}
return __bself.apply(__bself, arguments);
}
};
test.before(function (){
console.log(2);
return false;
})();
I have following javascript code
function MyFunc () {
var add = function () {
return "Hello from add";
};
var div = function () {
return "Hello from div";
};
var funcCall = function (obj) {
if (!obj) {
throw new Error("no Objects are passed");
}
return obj.fName();
};
return {
func: function (obj) {
funcCall(obj);
}
};
}
var lol = new MyFunc();
When lol.func({fName: add}); is passed it should invoke the function private function add or when lol.func({fName: div}); is passed it should invoke the private div function. What i have tried does not work. How can i achieve this.
DEMO
In this case it's better to store your inner function in the object so you can easily access this with variable name. So if you define a function "map"
var methods = {
add: add,
div: div
};
you will be able to call it with methods[obj.fName]();.
Full code:
function MyFunc() {
var add = function () {
return "Hello from add";
};
var div = function () {
return "Hello from div";
};
var methods = {
add: add,
div: div
};
var funcCall = function (obj) {
if (!obj) {
throw new Error("no Objects are passed");
}
return methods[obj.fName]();
};
return {
func: function (obj) {
return funcCall(obj);
}
};
}
var lol = new MyFunc();
console.log( lol.func({fName: 'add'}) );
When you pass lol.func({fName: add}) add is resolved in the scope of evaluating this code, not in the scope of MyFunc. You have to either define it in that scope like:
function MyFunc () {
var add = function () {
return "Hello from add";
};
var div = function () {
return "Hello from div";
};
var funcCall = function (obj) {
if (!obj) {
throw new Error("no Objects are passed");
}
return obj.fName();
};
return {
add: add,
div: div,
func: function (obj) {
funcCall(obj);
}
};
}
var lol = new MyFunc();
lol.func({fName: lol.add});
Or use eval.