Is there a way to tell the difference between this
((a=true)=>{return a})(true)
And this?
((a=true)=>{return a})()
They both return true - how can I tell whether that true is coming from the default value of the argument, or from the value passed in to that parameter?
Is it possible from outside the function?
Is it possible from inside the function?
Is there a way to tell the difference between these two?
No. Arrow function doesn't support argument object, so there is no way to check this.
But, if you are using non-arrow functions, you can get arguments number from inside the function. For example:
(function(a=true){return arguments.length;})(); // 0
(function(a=true){return arguments.length;})(true); // 1
You can easily figure out how to extend this to multiple arguments.
You cannot tell the difference in your specific examples, and there is no way to tell from outside the function definitely. The only exposed info is what you explicitly expose with your return value, which is just the boolean.
From inside the function, you can tell the difference if you rewrite your logic. You could change your function from
((a=true)=>{
return a;
})(true)
to
((...args)=>{
const a = args[0] === undefined ? true : args[0];
if (args.length > 0) console.log("passed arg");
else console.log("passed no arg");
return a;
})(true)
Note that you cannot combine this with default value syntax, so if you'd have to rewrite it to use rest syntax.
Alternatively, you could use a normal function instead of an arrow, and use arguments, however that is also a potentially difficult change if your real-world case relies on the arrow-function's lexical this. e.g.
(function(a = true)=>{
if (arguments.length > 0) console.log("passed arg");
else console.log("passed no arg");
return a;
})(true)
Although not ideal in every way, one solution might be:
(a=undefined) => {
let is_default = false;
if (a === undefined) {
is_default = true;
a = true;
}
return a
}
If you really want to use arrow functions, you can achieve a robust (if convoluted) result using Symbol and a wrapping IIFE
var fn = ((def) =>
(a = def) => {
if(a === def) {
console.log('defaulted');
a = true;
}
console.log('a is', a);
}
)(Symbol());
both fn() and fn(true) will result in a is true - however, fn() will also output defaulted and then set a = true - though this last step I guess doesn't have to done, depends on what the real content of the real function you really want to "detect" this in
Or, a better way as pointed out by #Bergi (I keep forgetting about the block scope in ES6+ :D )
var fn;
{
const def = Symbol();
fn = (a=def) => {
if(a === def) {
console.log('defaulted');
a = true;
}
console.log('a is', a);
};
}
Related
We're going to make a decorator, caching computed results of deterministic functions (for simplisity let's assume one-argument functions).
In common case is could be done this way:
function makeCacheable(origFunc){
let registry = {};
return function (a){
if (a in registry){
return registry[a];
}
let res = origFunc(a);
registry[a] = res;
return res;
}
}
A problem appears when origFunc is recursive: only top-level calls go through the wrapping cache, but the rest of recursive call stack doesn't meet the cache. No need to explain why this happens. I wonder is there a natural way to make a recursive function cacheable in the same manner?
function fibonacciF(n) {
if (n <= 2) return 1;
let a = 1, b = 1;
for (let i = 2; i < n; ++i){
[a, b] = [b, a+b];
}
return b;
}
function fibonacciR(n) {
return n <= 2 ? 1 : (fibonacciR(n-1) + fibonacciR(n-2));
}
let fiboF = makeCacheable(fibonacciF); // OK
let fiboR = makeCacheable(fibonacciR); // actually is not what expected
The function calls a function named fibonacciR. If you want to make this call go through the cache, you have to overwrite fibonacciR:
fibonacciR = makeCacheable(fibonacciR);
Is there a natural way to make a recursive function cacheable in the same manner?
No. In general, a function implementation cannot be inspected, and it doesn't make a difference whether it's implemented recursively or with a loop or something else. Using pure functional programming, we can only use the whole function as a building block for the cached version (fiboR), but we cannot alter its behaviour or take only parts of the function unless the implementation is cooperative (e.g. by using some kind of recursion operator that can be user-supplied).
In the above solution, we break these rules by overwriting a variable that is used inside the function, but this is not always possible even in JavaScript.
You could make it work, if you would use the same (function) variable for storing the decorated version of it. To allow for returning back to the original, you could add a property original to the function object:
function makeCacheable(origFunc){
let registry = {};
let f = function (a){
if (a in registry){
console.log(`retrieving value from registry[${a}]`);
return registry[a];
}
let res = origFunc(a);
registry[a] = res;
return res;
}
// Add property for exposing the original function:
f.original = origFunc;
return f;
}
function fibonacciR(n) {
console.log(`Called fibonnacci(${n})`);
return n <= 2 ? 1 : (fibonacciR(n-1) + fibonacciR(n-2));
}
// Demo illustrating the registry is being used:
console.log('Call fibonnacciR(5) with cache turned on:');
var fibonacciR = makeCacheable(fibonacciR);
var f5 = fibonacciR(5);
console.log(`Result: fibonnaciR(5) = ${f5}`);
// Demo illustrating the function can be restored:
console.log('Call fibonnacciR(5) with cache removed:');
fibonacciR = fibonacciR.original;
f5 = fibonacciR(5);
console.log(`Result: fibonnaciR(5) = ${f5}`);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I can create a recursive function in a variable like so:
/* Count down to 0 recursively.
*/
var functionHolder = function (counter) {
output(counter);
if (counter > 0) {
functionHolder(counter-1);
}
}
With this, functionHolder(3); would output 3 2 1 0. Let's say I did the following:
var copyFunction = functionHolder;
copyFunction(3); would output 3 2 1 0 as above. If I then changed functionHolder as follows:
functionHolder = function(whatever) {
output("Stop counting!");
Then functionHolder(3); would give Stop counting!, as expected.
copyFunction(3); now gives 3 Stop counting! as it refers to functionHolder, not the function (which it itself points to). This could be desirable in some circumstances, but is there a way to write the function so that it calls itself rather than the variable that holds it?
That is, is it possible to change only the line functionHolder(counter-1); so that going through all these steps still gives 3 2 1 0 when we call copyFunction(3);? I tried this(counter-1); but that gives me the error this is not a function.
Using Named Function Expressions:
You can give a function expression a name that is actually private and is only visible from inside of the function ifself:
var factorial = function myself (n) {
if (n <= 1) {
return 1;
}
return n * myself(n-1);
}
typeof myself === 'undefined'
Here myself is visible only inside of the function itself.
You can use this private name to call the function recursively.
See 13. Function Definition of the ECMAScript 5 spec:
The Identifier in a FunctionExpression can be referenced from inside the FunctionExpression's FunctionBody to allow the function to call itself recursively. However, unlike in a FunctionDeclaration, the Identifier in a FunctionExpression cannot be referenced from and does not affect the scope enclosing the FunctionExpression.
Please note that Internet Explorer up to version 8 doesn't behave correctly as the name is actually visible in the enclosing variable environment, and it references a duplicate of the actual function (see patrick dw's comment below).
Using arguments.callee:
Alternatively you could use arguments.callee to refer to the current function:
var factorial = function (n) {
if (n <= 1) {
return 1;
}
return n * arguments.callee(n-1);
}
The 5th edition of ECMAScript forbids use of arguments.callee() in strict mode, however:
(From MDN): In normal code arguments.callee refers to the enclosing function. This use case is weak: simply name the enclosing function! Moreover, arguments.callee substantially hinders optimizations like inlining functions, because it must be made possible to provide a reference to the un-inlined function if arguments.callee is accessed. arguments.callee for strict mode functions is a non-deletable property which throws when set or retrieved.
You can access the function itself using arguments.callee [MDN]:
if (counter>0) {
arguments.callee(counter-1);
}
This will break in strict mode, however.
You can use the Y-combinator: (Wikipedia)
// ES5 syntax
var Y = function Y(a) {
return (function (a) {
return a(a);
})(function (b) {
return a(function (a) {
return b(b)(a);
});
});
};
// ES6 syntax
const Y = a=>(a=>a(a))(b=>a(a=>b(b)(a)));
// If the function accepts more than one parameter:
const Y = a=>(a=>a(a))(b=>a((...a)=>b(b)(...a)));
And you can use it as this:
// ES5
var fn = Y(function(fn) {
return function(counter) {
console.log(counter);
if (counter > 0) {
fn(counter - 1);
}
}
});
// ES6
const fn = Y(fn => counter => {
console.log(counter);
if (counter > 0) {
fn(counter - 1);
}
});
I know this is an old question, but I thought I'd present one more solution that could be used if you'd like to avoid using named function expressions. (Not saying you should or should not avoid them, just presenting another solution)
var fn = (function() {
var innerFn = function(counter) {
console.log(counter);
if(counter > 0) {
innerFn(counter-1);
}
};
return innerFn;
})();
console.log("running fn");
fn(3);
var copyFn = fn;
console.log("running copyFn");
copyFn(3);
fn = function() { console.log("done"); };
console.log("fn after reassignment");
fn(3);
console.log("copyFn after reassignment of fn");
copyFn(3);
Here's one very simple example:
var counter = 0;
function getSlug(tokens) {
var slug = '';
if (!!tokens.length) {
slug = tokens.shift();
slug = slug.toLowerCase();
slug += getSlug(tokens);
counter += 1;
console.log('THE SLUG ELEMENT IS: %s, counter is: %s', slug, counter);
}
return slug;
}
var mySlug = getSlug(['This', 'Is', 'My', 'Slug']);
console.log('THE SLUG IS: %s', mySlug);
Notice that the counter counts "backwards" in regards to what slug's value is. This is because of the position at which we are logging these values, as the function recurs before logging -- so, we essentially keep nesting deeper and deeper into the call-stack before logging takes place.
Once the recursion meets the final call-stack item, it trampolines "out" of the function calls, whereas, the first increment of counter occurs inside of the last nested call.
I know this is not a "fix" on the Questioner's code, but given the title I thought I'd generically exemplify Recursion for a better understanding of recursion, outright.
Using filter and map, recursion example removing null properties from an object
const obj = {
name: {
first: "Jeson",
middle: null,
last: "Holder"
},
age: 45
}
function removeNullOrEmpty(obj){
return Object.fromEntries(
Object.entries(obj)
.filter(([_, v])=> v!== null && v.length !== 0)
.map(([k, v])=>[k, v === Object(v)?removeNullOrEmpty(v):v])
)
}
console.log(removeNullOrEmpty(obj))
I'm porting some Python code that relies heavily on delayed evaluation. This is accomplished by via thunks. More specifically, any Python expression <expr> for which delayed evaluation is desired gets enclosed within a Python "lambda expression", i.e. lambda:<expr>.
AFAIK, the closest JavaScript equivalent of this is function(){return <expr>}.
Since the code I'm working with is absolutely awash in such thunks, I'd like to make the code for them more succinct, if at all possible. The reason for this is not only to save characters (a non-negligible consideration when it comes to JS), but also to make the code more readable. To see what I mean, compare this standard JavaScript form:
function(){return fetchx()}
with
\fetchx()
In the first form, the substantive information, namely the expression fetchx(), is typographically obscured by the surrounding function(){return...}. In the second form1, just one (\) character is used as "delayed evaluation marker". I think this is the optimal approach2.
AFAICT, solutions to this problem would fall into the following categories:
Using eval to simulate delayed evaluation.
Some special JavaScript syntax that I don't know about, and that accomplishes what I want. (My vast ignorance of JavaScript makes this possibility look quite real to me.)
Writing the code in some non-standard JavaScript that gets programmatically processed into correct JavaScript. (Of course, this approach will not reduce the final code's footprint, but may at least retain some gains in readability.)
None of the above.
I'm particularly interested in hearing responses of the last three categories.
P.S.: I'm aware that the use of eval (option 1 above) is widely deprecated in the JS world, but, FWIW, below I give a toy illustration of this option.
The idea is to define a private wrapper class whose sole purpose would be to tag plain strings as JavaScript code for delayed evaluation. A factory method with a short name (e.g. C, for "CODE") is then used to reduce, e.g.,
function(){return fetchx()}
to
C('fetchx()')
First, definitions of the factory C and of the helper function maybe_eval:
var C = (function () {
function _delayed_eval(code) { this.code = code; }
_delayed_eval.prototype.val = function () { return eval(this.code) };
return function (code) { return new _delayed_eval(code) };
})();
var maybe_eval = (function () {
var _delayed_eval = C("").constructor;
return function (x) {
return x instanceof _delayed_eval ? x.val() : x;
}
})();
The following comparison between a get function and a lazyget function shows how the above would be used.
Both functions take three arguments: an object obj, a key key, and a default value, and they both should return obj[key] if key is present in obj, and otherwise, the default value.
The only difference between the two functions is that the default value for lazyget can be a thunk, and if so, it will get evaluated only if key is not in obj.
function get(obj, key, dflt) {
return obj.hasOwnProperty(key) ? obj[key] : dflt;
}
function lazyget(obj, key, lazydflt) {
return obj.hasOwnProperty(key) ? obj[key] : maybe_eval(lazydflt);
}
Too see these two functions in action, define:
function slow_foo() {
++slow_foo.times_called;
return "sorry for the wait!";
}
slow_foo.times_called = 0;
var someobj = {x: "quick!"};
Then, after evaluating the above, and using (e.g.) Firefox + Firebug, the following
console.log(slow_foo.times_called) // 0
console.log(get(someobj, "x", slow_foo())); // quick!
console.log(slow_foo.times_called) // 1
console.log(lazyget(someobj, "x",
C("slow_foo().toUpperCase()"))); // quick!
console.log(slow_foo.times_called) // 1
console.log(lazyget(someobj, "y",
C("slow_foo().toUpperCase()"))); // SORRY FOR THE WAIT!
console.log(slow_foo.times_called) // 2
console.log(lazyget(someobj, "y",
"slow_foo().toUpperCase()")); // slow_foo().toUpperCase()
console.log(slow_foo.times_called) // 2
prints out
0
quick!
1
quick!
1
SORRY FOR THE WAIT!
2
slow_foo().toUpperCase()
2
1...which may strike Haskell programmers as strangely familiar. :)
2There's another approach, the one used, e.g., by Mathematica, that avoids the need for delayed evaluation markers altogether. In this approach, as part of a function's definition, one can designate any one of its formal arguments for non-standard evaluation. Typographically, this approach is certainly maximally unobtrusive, but a bit too much so for my taste. Besides, it is not as flexible, IMHO, as using, e.g., \ as a delayed evaluation marker.
In my humble opinion I think you're looking at this problem from a wrong perspective. If you're creating thunks manually then you need to consider refactoring your code. In most cases thunks should be:
Either returned from lazy functions.
Or created by composing functions.
Returning Thunks from Lazy Functions
When I first started practicing functional programming in JavaScript I was mystified by the Y combinator. From what I had read online the Y combinator was a divine entity to be worshipped. It somehow allowed functions which didn't know their own name to call themselves. Hence it was the mathematical manifestation of recursion - one of the most important pillars of functional programming.
However understanding the Y combinator was no easy feat. Mike Vanier wrote that the knowledge of the Y combinator is a diving line between those people who are "functionally literate" and those who aren't. Honestly, the Y combinator in itself is dead simple to understand. However most articles online explain it backwards making it difficult to understand. For example Wikipedia defines the Y combinator as:
Y = λf.(λx.f (x x)) (λx.f (x x))
In JavaScript this would translate to:
function Y(f) {
return (function (x) {
return f(x(x));
}(function (x) {
return f(x(x));
}));
}
This definition of the Y combinator is unintuitive and it doesn't make apparent how the Y combinator is a manifestation of recursion. Not to mention that it cannot be used at all in eager languages like JavaScript because the expression x(x) is evaluated immediately resulting in an infinite loop which eventually results in a stack overflow. Hence in eager languages like JavaScript we use the Z combinator instead:
Z = λf.(λx.f (λv.((x x) v))) (λx.f (λv.((x x) v)))
The resulting code in JavaScript is even more confusing and unintuitive:
function Z(f) {
return (function (x) {
return f(function (v) {
return x(x)(v);
});
}(function (x) {
return f(function (v) {
return x(x)(v);
});
}));
}
Trivially we can see that the only difference between the Y combinator and the Z combinator is that the lazy expression x(x) is replaced by the eager expression function (v) { return x(x)(v); }. It is wrapped in a thunk. In JavaScript however it makes more sense to write the thunk as follows:
function () {
return x(x).apply(this, arguments);
}
Of course here we're assuming that x(x) evaluates to a function. In the case of the Y combinator this is indeed true. However if the thunk doesn't evaluate to a function then we simply return the expression.
One of the most epiphanous moments for me as a programmer was that the Y combinator is itself recursive. For example in Haskell you define Y combinator as follows:
y f = f (y f)
Because Haskell is a lazy language the y f in f (y f) is only evaluated when required and hence you don't run into an infinite loop. Internally Haskell creates a thunk for every expression. In JavaScript however you need to create a thunk explicitly:
function y(f) {
return function () {
return f(y(f)).apply(this, arguments);
};
}
Of course defining the Y combinator recursively is cheating: you are just explicitly recursing inside the Y combinator instead. Mathematically the Y combinator itself should be defined non-recursively to describe the structure of recursion. Nonetheless we all love it anyway. The important thing is that the Y combinator in JavaScript now returns a thunk (i.e. we defined it using lazy semantics).
To consolidate our understanding let's create another lazy function in JavaScript. Let's implement the repeat function from Haskell in JavaScript. In Haskell the repeat function is defined as follows:
repeat :: a -> [a]
repeat x = x : repeat x
As you can see repeat has no edge cases and it calls itself recursively. If Haskell weren't so lazy it would recurse forever. If JavaScript were lazy then we could implement repeat as follows:
function repeat(x) {
return [x, repeat(x)];
}
Unfortunately if executed the above code would recurse forever until it results in a stack overflow. To solve this problem we return a thunk instead:
function repeat(x) {
return function () {
return [x, repeat(x)];
};
}
Of course since the thunk doesn't evaluate to a function we need another way to treat a thunk and a normal value identically. Hence we create a function to evaluate a thunk as follows:
function evaluate(thunk) {
return typeof thunk === "function" ? thunk() : thunk;
}
The evaluate function can now be used to implement functions which can take either lazy or strict data structures as arguments. For example we can implement the take function from Haskell using evaluate. In Haskell take is defined as follows:
take :: Int -> [a] -> [a]
take 0 _ = []
take _ [] = []
take n (x:xs) = x : take (n - 1) xs
In JavaScript we would implement take using evaluate as follows:
function take(n, list) {
if (n) {
var xxs = evaluate(list);
return xxs.length ? [xxs[0], take(n - 1, xxs[1])] : [];
} else return [];
}
Now you can use repeat and take together as follows:
take(3, repeat('x'));
See the demo for yourself:
alert(JSON.stringify(take(3, repeat('x'))));
function take(n, list) {
if (n) {
var xxs = evaluate(list);
return xxs.length ? [xxs[0], take(n - 1, xxs[1])] : [];
} else return [];
}
function evaluate(thunk) {
return typeof thunk === "function" ? thunk() : thunk;
}
function repeat(x) {
return function () {
return [x, repeat(x)];
};
}
Lazy evaluation at work.
In my humble opinion most thunks should be those returned by lazy functions. You should never have to create a thunk manually. However every time you create a lazy function you still need to create a thunk inside it manually. This problem can be solved by lifting lazy functions as follows:
function lazy(f) {
return function () {
var g = f, self = this, args = arguments;
return function () {
var data = g.apply(self, args);
return typeof data === "function" ?
data.apply(this, arguments) : data;
};
};
}
Using the lazy function you can now define the Y combinator and repeat as follows:
var y = lazy(function (f) {
return f(y(f));
});
var repeat = lazy(function (x) {
return [x, repeat(x)];
});
This makes functional programming in JavaScript almost as fun as functional programming in Haskell or OCaml. See the updated demo:
var repeat = lazy(function (x) {
return [x, repeat(x)];
});
alert(JSON.stringify(take(3, repeat('x'))));
function take(n, list) {
if (n) {
var xxs = evaluate(list);
return xxs.length ? [xxs[0], take(n - 1, xxs[1])] : [];
} else return [];
}
function evaluate(thunk) {
return typeof thunk === "function" ? thunk() : thunk;
}
function lazy(f) {
return function () {
var g = f, self = this, args = arguments;
return function () {
var data = g.apply(self, args);
return typeof data === "function" ?
data.apply(this, arguments) : data;
};
};
}
Creating Thunks by Composing Functions
Sometimes you need to pass expressions to functions that are evaluated lazily. In such situations you need to create custom thunks. Hence we can't make use of the lazy function. In such cases you can use function composition as a viable alternative to manually creating thunks. Function composition is defined as follows in Haskell:
(.) :: (b -> c) -> (a -> b) -> a -> c
f . g = \x -> f (g x)
In JavaScript this translates to:
function compose(f, g) {
return function (x) {
return f(g(x));
};
}
However it makes much more sense to write it as:
function compose(f, g) {
return function () {
return f(g.apply(this, arguments));
};
}
Function composition in mathematics reads from right-to-left. However evaluation in JavaScript is always from left-to-right. For example in the expression slow_foo().toUpperCase() the function slow_foo is executed first and then the method toUpperCase is called on its return value. Hence we want to compose functions in reverse order and chain them as follows:
Function.prototype.pipe = function (f) {
var g = this;
return function () {
return f(g.apply(this, arguments));
};
};
Using the pipe method we can now compose functions as follows:
var toUpperCase = "".toUpperCase;
slow_foo.pipe(toUpperCase);
The above code will be equivalent to the following thunk:
function () {
return toUpperCase(slow_foo.apply(this, arguments));
}
However there's a problem. The toUpperCase function is actually a method. Hence the value returned by slow_foo should set the this pointer of toUpperCase. In short we want to pipe the output of slow_foo into toUpperCase as follows:
function () {
return slow_foo.apply(this, arguments).toUpperCase();
}
The solution is actually very simple and we don't need to modify our pipe method at all:
var bind = Function.bind;
var call = Function.call;
var bindable = bind.bind(bind); // bindable(f) === f.bind
var callable = bindable(call); // callable(f) === f.call
Using the callable method we can now refactor our code as follows:
var toUpperCase = "".toUpperCase;
slow_foo.pipe(callable(toUpperCase));
Since callable(toUpperCase) is equivalent to toUpperCase.call our thunk is now:
function () {
return toUpperCase.call(slow_foo.apply(this, arguments));
}
This is exactly what we want. Hence our final code is as follows:
var bind = Function.bind;
var call = Function.call;
var bindable = bind.bind(bind); // bindable(f) === f.bind
var callable = bindable(call); // callable(f) === f.call
var someobj = {x: "Quick."};
slow_foo.times_called = 0;
Function.prototype.pipe = function (f) {
var g = this;
return function () {
return f(g.apply(this, arguments));
};
};
function lazyget(obj, key, lazydflt) {
return obj.hasOwnProperty(key) ? obj[key] : evaluate(lazydflt);
}
function slow_foo() {
slow_foo.times_called++;
return "Sorry for keeping you waiting.";
}
function evaluate(thunk) {
return typeof thunk === "function" ? thunk() : thunk;
}
Then we define the test case:
console.log(slow_foo.times_called);
console.log(lazyget(someobj, "x", slow_foo()));
console.log(slow_foo.times_called);
console.log(lazyget(someobj, "x", slow_foo.pipe(callable("".toUpperCase))));
console.log(slow_foo.times_called);
console.log(lazyget(someobj, "y", slow_foo.pipe(callable("".toUpperCase))));
console.log(slow_foo.times_called);
console.log(lazyget(someobj, "y", "slow_foo().toUpperCase()"));
console.log(slow_foo.times_called);
And the result is as expected:
0
Quick.
1
Quick.
1
SORRY FOR KEEPING YOU WAITING.
2
slow_foo().toUpperCase()
2
Hence as you can see for most cases you never need to create thunks manually. Either lift functions using the function lazy to make them return thunks or compose functions to create new thunks.
If you want delayed execution you should look in to using setTimeout.
setTimeout(function() {
console.log("I'm delayed");
}, 10);
console.log("I'm not delayed");
>I'm not delayed
>I'm delayed
https://developer.mozilla.org/en-US/docs/Web/API/window.setTimeout
Can I write a function that returns iteself?
I was reading some description on closures - see Example 6 - where a function was returning a function, so you could call func()(); as valid JavaScript.
So I was wondering could a function return itself in such a way that you could chain it to itself indefinitely like this:
func(arg)(other_arg)()(blah);
Using arguments object, callee or caller?
There are 2-3 ways. One is, as you say, is to use arguments.callee. It might be the only way if you're dealing with an anonymous function that's not stored assigned to a variable somewhere (that you know of):
(function() {
return arguments.callee;
})()()()().... ;
The 2nd is to use the function's name
function namedFunc() {
return namedFunc;
}
namedFunc()()()().... ;
And the last one is to use an anonymous function assigned to a variable, but you have to know the variable, so in that case I see no reason, why you can't just give the function a name, and use the method above
var storedFunc = function() {
return storedFunc;
};
storedFunc()()()().... ;
They're all functionally identical, but callee is the simplest.
Edit: And I agree with SLaks; I can't recommend it either
Yes.
Just return arguments.callee;
However, this is likely to result in very confusing code; I do not recommend it.
You can do what you want as following:
// Do definition and execution at the same time.
var someFunction = (function someFunction() {
// do stuff
return someFunction
})();
console.log(someFunction)
arguments.callee is not supported in JavaScript strict mode.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
Even sorter that all the above is:
f=()=>f
There is a simple way to achieve this doing the following:
let intArr = [];
function mul(x){
if(!x){
return intArr.reduce((prev, curr) => prev * curr)
}
intArr.push(x);
return mul;
}
console.log(mul(2)(4)(2)()); => outputs 16
It is also possible just to return the argument the self invokable function like
console.log( (function(a) { return a; })(1) ); // returns 1
Im trying to call functions with same signature.
Example: There are two functions with same name:
<script>
var obj1,obj2,obj3,obj4,obj5;
function OpenBox(obj1,obj2){
// code
}
function OpenBox(obj1,obj2,obj3,obj4,obj5){
// code
}
</script>
When I calling function on click event of link
<a id='hlnk1' href='#' onclick='OpenBox(this,\"abhishek\"); return false;'> Open Box </a>
When I click on the above link it is calling function OpenBox(obj1,obj2,obj3,obj4,obj5){}
It should be call function OpenBox(obj1,obj2){} Instead.
What's going wrong in functions?
mattn has the correct idea. Because javascript has no typing those functions are equivalent. What you could do is something like this:
function OpenBox_impl1(obj1,obj2){
// code
}
function OpenBox_impl2(obj1,obj2,obj3,obj4,obj5){
// code
}
function OpenBox(obj1, obj2, obj3, obj4, obj5) {
if(arguments.length == 2)
return OpenBox_impl1(obj1, obj2);
else
return OpenBox_impl2(obj1,obj2,obj3,obj4,obj5);
}
javascript can't define duplicate function in same scope. check arguments.length are 2 or 5.
You cannot overload functions in JavaScript. Instead, the most recently defined version of the function will be used, which is why in your case the version with 5 parameters is called (the final 3 are just undefined).
There are several ways around this, one if which is shown in Mikola's answer. An alternative is to pass in an object, and then check the contents of that object in the function (see this question):
function foo(a, b, opts) {
}
foo(1, 2, {"method":"add"});
foo(3, 4, {"test":"equals", "bar":"tree"});
Another option is to check arguments.length:
function foo(a, b) {
if(arguments.length > 2) {
var arg3 = arguments[3];
//etc...
}
}
in the polymorphism you can use a different signature method ,in javascript we can simulate polymorphism checking the type of the function parameter and execute certain task.
var input = document.getElementById('data');
polymorphism(input);
polymorphism('Hello word 2');
polymorphism('hello word 3', 5);
function polymorphism(arg,arg1){
var string = null;
var sqr = 0;
if(typeof arg === 'string'){
string = 'arg type String: \n'+arg;
}else if (arg.tagName && arg.tagName === 'INPUT'){
string = 'arg type Input: \n'+arg.value;
}
if(arg1 && typeof arg1 === 'number'){
sqr = arg1*arg1;
alert(string + ' and sqr = '+sqr);
}else {
alert(string);
}
}
Check this example in JSFIDDLE
#abshik ,
There is nothing like that which is similar to c# or java. Javasccript behaves this way
function Test(arg1 ,arg2 , arg3, arg4)
{
}
when you are calling this function you can call in the following ways
Test(arg1);
Test(arg1,arg2);
Test(arg1,arg2,arg3);
Test(arg1,arg2,arg3,arg4);
But sequence matters , so you can the function in the above ways.
The issue is that you are trying to overload a function but that is not supported by Javascript. I think your best option is to use Polymorphism instead. View this article for more details: http://www.cyberminds.co.uk/blog/articles/polymorphism-in-javascript.aspx
Once a function is defined in ecmascript, that name is locked. However, you can pass any number of parameters to that function so you do the rest of the work on the inside.
function foo(arg1, arg2) {
// any code that is needed regardless of param count
if(arg2 !== undefined) {
// run function with both arguments
console.log(arguments);
} else if(arg1 !== undefined) {
// run function with one argument
} else {
// run function with no arguments
}
}
foo(1);
foo(1,2);
foo(1,2,3);
Interesting note: you can pass in extra parameters that aren't in the function declaration. Do a console.log of arguments and you'll see everything in there. arguments is an object which can be accessed like / typecasted to an array.