This question already has answers here:
(1, eval)('this') vs eval('this') in JavaScript?
(4 answers)
Closed 6 years ago.
The community reviewed whether to reopen this question 3 months ago and left it closed:
Original close reason(s) were not resolved
I found this code in someone's code, it sound like this:
(0, function (arg) { ... })(this)
After I try to play around like below,
(0, function (arg) { console.log(arg) })(2);
console.log((0, 1, 2, 3));
(0, function plus1 (arg) { console.log(arg + 1) }, function plus2 (arg) { console.log(arg + 2) })(5);
I found that it will always return last item in the bracket.
I wonder what is the name of this programming pattern and what is the use case?
In this particular case it seems superfluous, but sometimes this approach is useful.
For example, with eval:
(function() {
(0,eval)("var foo = 123"); // indirect call to eval, creates global variable
})();
console.log(foo); // 123
(function() {
eval("var bar = 123"); // direct call to eval, creates local variable
})();
console.log(bar); // ReferenceError
It's also useful when you want to call a method without passing the object as the this value:
var obj = {
method: function() { return this; }
};
console.log(obj.method() === obj); // true
console.log((0,obj.method)() === obj); // false
Also note that, depending on the context, it might be the arguments separator instead of a comma operator:
console.log(
function(a, b) {
return function() { return a; };
}
(0, function (arg) { /* ... */ })(this)
); // 0
In this scenario, (0, function (arg) { /* ... */ }) are the arguments (a=0, b=function (arg) { /* ... */ }) to the function
function(a, b) {
return function() { return a; };
}
rather than the comma operator. (Then, the (this) at the end is function call with argument this to the returned function function() { return a; }. But this part is not relevant to the comma operator/argument separator difference)
It is a comma operator wrapped with a self-executing anonymous function. However, I have no idea as to why the meaningless 0 was included except for obfuscation purposes.
typical example could be,
for(var i=0,j=10; i < j; i++){
// code ...
}
comma operator would evaluate expressions from left-to-right and return result of right most expression
// e.g.
var a = 1, b= 2, c = 3, d = function(){ console.log("a => " + a) }()
Related
can anyone explain to me what is JS doing here? Can anybody explain what is going on here in terms of type coercion, IIFE, and closures?
Function.prototype.toString = (
function() {
const toStringFnRef = Function.prototype.toString;
return function() {
return `start:${toStringFnRef.call(this)}end`;
}
}
)();
console.log(1 + function x() { alert('hi') });
//output: "1start:function x() { alert('hi') }end"
The IIFE is being used to create a local scope where the variable toStringFnRef contains the original value of Function.prototype.toString. Then it redefines this with a function that calls the original function and wraps the result in start: and end.
This could also be done using a lexical block (in ES6 most IIFEs can be refactored like this):
{
const toStringFnRef = Function.prototype.toString;
Function.prototype.toString = function() {
return `start:${toStringFnRef.call(this)}end`;
}
}
When you do 1 + function x() { alert('hi') } it converts both 1 and the function to strings so it can concatenate them. So this calls your redefined Function.prototype.toString(), which surrounds the normal string of the function with those wrappers. This is then concatenated with 1.
This question already has answers here:
Adding custom properties to a function
(10 answers)
javascript adding property to function
(2 answers)
Properties of Javascript function objects
(5 answers)
Closed 1 year ago.
I tried this:
var fun = function(){ console.log("booyah"} , {
hell: function(){
console.log("hello");
},
boy: ()=>{
alert("blah");
}
};
fun.boy();
I want that first I call fun function and then Access functions I have stored as objects. But I am getting errors . How can I fix it? Or is there any other way to do that?
Please help.
You can achieve this kind of result by editing the prototype of the function.
Example:
function foo() {
const something = 'the thing';
return something;
}
const customPrototype = {
greeting: (name) => {
const greetingTemplate = `Hello ${name}`;
return greetingTemplate;
},
randomNumber: () => {
return Math.random();
},
};
// Extending prototype to access our custom prototype functions
Object.assign(foo, customPrototype);
console.log(foo()); // the thing
console.log(foo.greeting('People')); // Hello People
console.log(foo.randomNumber()); // 0.26138311987993545
// Default prototype functions are working as well
console.log(foo.toString()); // [object Function]
EDIT: Thanks to #Bergi for correcting me!
Check the below code, reference taken from Can you create functions with custom prototypes in JavaScript?
function MyFun() {
if (!this || this==window) {
return new MyFun();
}
var f = function() {
return "thanks for calling!";
}
f.__proto__ = MyFun.prototype;
f.constructor = MyFun;
return f;
}
MyFun.prototype = {
foo: function() {
return "foo:" + this();
},
__proto__: Function.prototype
};
var f = new MyFun();
alert("proto method:"+f.foo()); // try our prototype methods
alert("function method:"+f.call()); // try standard function methods
alert("function call:"+f()); // try use as a function
alert('typeof:' + typeof f); // "function", not "object". No way around it in current js versions
alert('is MyFun:' + (f instanceof MyFun)); // true
alert('is Function:' + (f instanceof Function)); // true
This question already has answers here:
Why use named function expressions?
(5 answers)
Closed 7 years ago.
What's the point of naming function expressions if you can't really reference them by the names you give them?
var f = function g() {
console.log("test");
};
g(); // ReferenceError: g is not defined
Oh, but you can reference them by that name. Those names just only exist inside the scope of the function.
var f = function g() {
// In here, you can use `g` (or `f`) to reference the function
return typeof g;
};
console.log( typeof g );
// It only exists as `f` here
console.log( f() );
DOCS: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function#Named_function_expression
One advantage that I find particularly useful is that it helps when debugging.
When an error occurs, you see the function name in the stacktrace in the console. Otherwise the line in the stacktrace would only refer to an anonymous function.
You can also make the purpose of the function clearer by giving it a name.
It's important if you create a recursive function that is passed around. When you name a function it then knows about itself, within its own scope.
Here I've created a sort of factory function that creates recursive functions. For the recursive functions to work properly they need to know about themselves.
You can imagine this applied in a broader sense, like returning a recursive function as a module export.
var
func = (function () {
return function rec (a) {
console.log(a);
return a >= 5 ? 'done' : rec(a + 1);
};
}),
invoke = function (f, args) {
return f.apply(null, args);
};
console.log(
invoke(func(), [1])
);
By very definition, what you have defined is not an anonymous function:
function [name]([param[, param[, ... param]]]) {
statements
}
Name:
The function name. Can be omitted, in which case the function
becomes known as an anonymous function.
Furthermore, a lot of peole would consider
var f = function() {
return 'test';
};
not to be an anonymous function since you can now invoke it by var name f() and can now pass the function as a parameter to other functions by the name functionThatTakesCallback(f).
In my head, a true anonymous function has no name whatsoever such as something passed to a call back:
$('#id').on('click', function(){
console.log("I am anonymous");
});
or as a function run immediately:
(function(when){
console.log("run me :", when);
})("right now");
With the syntax you are using now, in ES6 (most non IE browsers implement this feature), f.name is g. This is useful when debugging
You could use it to recur:
var f = function g (n, m) {
if (n>0) {
return g(n - 1, m = m + 'meta');
}
return m + 'test';
};
console.log(f(10, 'super'));
I saw this shortcut given as an answer on a code Kata but I am having difficulty understanding exactly what the below example is doing.
function func(fn) {
return fn.bind.apply(fn, arguments);
}
So far my understanding is that bind creates a new function similar to doing the following:
function func(fn) {
return function () {
return fn.apply(fn, arguments);
};
}
Is this the case? Any clearer answers or breakdowns of what is going on would be great.
fn.bind
is just
Function.prototype.bind
So we're applying bind to fn, returning
fn.bind(arguments[0]/* doesn't matter, it's fn*/, arguments[1], arguments[2], etc.)
So the bound function is called with arguments being the arguments of func after fn.
Another way to write it would have been:
function func(fn) {
var args = [].slice.call(arguments, 1);
return function () {
var localArgs = [].slice.call(arguments);
return fn.apply(fn, args.concat(localArgs));
};
}
The fact that the context of the call is the initial function (arguments[0]) is most certainly only a side effect. The important thing is we wrap the arguments with the function, but make it possible to dynamically pass other arguments.
Example 1, wrapping all arguments :
function add(a,b){
return a+b
}
var f = func(add, 2 ,3); // f is a function which will always apply add to 2 and 3
console.log(f()) // logs 5
Exemple 2, currying:
function multiply(a,b){
return a*b
}
var multBy2 = func(multiply, 2);
console.log(multBy2(3)) // logs 6
I came across this syntax in "Hey Underscore, You're Doing it Wrong" JavaScript talk (4:15). I would like to know what it means.
var add = function(x,y){
return x + y;
}.autoCurry();//What is happening in this line.
First let's looks at what curry and autocurry actually do. I've annotated the source of these two functions (originally found in the wu.js library):
////
// Type:
//
// ((a,b, ... c) -> d) -> a -> b -> ... -> c -> d
//
// Example:
//
// function add(a, b) { return a + b; }
// add2 = curry(add, 2)
// add2(3)
// // 5
function curry(fn /* variadic number of args */) {
var args = Array.prototype.slice.call(arguments, 1);
function f() { return fn.apply(this, args.concat(toArray(arguments))); }
return f;
}
////
// Example:
//
// function add(a, b) { return a + b; }
// autoCurry(add);
//
// add(2)(3)
// // 5
//
// add(2, 3)
// // 5
function autoCurry(fn, numArgs) {
numArgs = numArgs || fn.length;
function f() {
if (arguments.length < numArgs)
{
return numArgs - arguments.length > 0 ?
autoCurry(curry.apply(this, [fn].concat(toArray(arguments))),
numArgs - arguments.length) :
curry.apply(this, [fn].concat(toArray(arguments)));
}
else
{
return fn.apply(this, arguments);
}
}
f.toString = function() { return fn.toString(); };
f.curried = true;
return f;
}
In other words,
autoCurry(add)
Takes a function that takes two arguments and returns a number, and returns a function A that takes a single argument and returns a function B. Where B is a function that takes a single argument and returns a number:
add(1) -> returns a function add1(), which itself takes a single argument.
Next, the speaker in that talk does the following:
Function.prototype.autoCurry = function(n) { return autoCurry(this, n); }
This simply applies the autoCurry method to any given function (self) so that
var add = function(x,y){
return x + y;
}.autoCurry();
Has the same effect as:
var add = function(x,y) { return x + y; };
add = autoCurry(add)
Well, I can't tell you what, exactly autoCurry is doing... ...but what I can tell you is this:
They've modified the Function constructor's prototype Function.prototype.autoCurry = function () { };
Every new function you make on that page will now have access to this method as one of its properties.
var myFunc = function () { return true; }; myFunc.autoCurry();
You can chain statements together, happily in JS.
var myObj = { run : function () { } }, result = myObj.run(); is the same as
var result = { run : function () { } }.run();, as long as you don't care about myObj after.
So:
You are creating a function, and as soon as it's created, you're running a method on it, and the return statement of that method (the last thing in the chain) is being saved to the variable.
Now, currying is a form of taking a function and wrapping it in other functions, which allows you to call it with only a portion of the arguments needed.
function add_two_numbers = function (x, y) { return x + y; }
Currying would allow you to do this:
var save_x_for_later = curry(add_two_numbers),
save_y_and_add = save_x_for_later(3),
result = save_y_and_add(5);
result; // 8
As for your new title, the answer is the following:
You will get an error thrown in your face:
.autoCurry() is not a part of the language.
It was written, by hand, and put on the Function.prototype as Function.prototype.autoCurry = function () { }
I could go into an implementation of currying, but there's a lot of stuff to wrap your head around, if you haven't done much functional programming, or if "lambda" is a head-scratching term.
In JavaScript, a function instantiation expression:
function name( arg1, arg2, ... ) { /* code */ }
creates a function and results in a reference to the function object. Thus, the .autoCurry() is a reference to a property on that object, which is apparently assumed to be a function.
I suspect that the example you're looking at has some other code that adds "autoCurry" to the Function prototype object. That way, every function object has access to that function as the "autoCurry" property.