Invoking a function without parentheses
There are several different ways to call a function without parentheses.
Let's assume you have this function defined:
function greet() {
console.log('hello');
}
Then here follow some ways to call greet
without parentheses:
1. As Constructor
With new
you can invoke a function without parentheses:
new greet; // parentheses are optional in this construct.
From MDN on the new
oprator:
Syntax
new constructor[([arguments])]
2. As toString
or valueOf
Implementation
toString
and valueOf
are special methods: they get called implicitly when a conversion is necessary:
var obj = {
toString: function() {
return 'hello';
}
}
'' + obj; // concatenation forces cast to string and call to toString.
You could (ab)use this pattern to call greet
without parentheses:
'' + { toString: greet };
Or with valueOf
:
+{ valueOf: greet };
valueOf
and toString
are in fact called from the @@toPrimitive method (since ES6), and so you can also implement that method:
+{ [Symbol.toPrimitive]: greet }
"" + { [Symbol.toPrimitive]: greet }
2.b Overriding valueOf
in Function Prototype
You could take the previous idea to override the valueOf
method on the Function
prototype:
Function.prototype.valueOf = function() {
this.call(this);
// Optional improvement: avoid `NaN` issues when used in expressions.
return 0;
};
Once you have done that, you can write:
+greet;
And although there are parentheses involved down the line, the actual triggering invocation has no parentheses. See more about this in the blog "Calling methods in JavaScript, without really calling them"
3. As Generator
You could define a generator function (with *
), which returns an iterator. You can call it using the spread syntax or with the for...of
syntax.
First we need a generator variant of the original greet
function:
function* greet_gen() {
console.log('hello');
}
And then we call it without parentheses by defining the @@iterator method:
[...{ [Symbol.iterator]: greet_gen }];
Normally generators would have a yield
keyword somewhere, but it is not needed for the function to get called.
The last statement invokes the function, but that could also be done with destructuring:
[,] = { [Symbol.iterator]: greet_gen };
or a for ... of
construct, but it has parentheses of its own:
for ({} of { [Symbol.iterator]: greet_gen });
Note that you can do the above with the original greet
function as well, but it will trigger an exception in the process, after greet
has been executed (tested on FF and Chrome). You could manage the exception with a try...catch
block.
4. As Getter
@jehna1 has a full answer on this, so give him credit. Here is a way to call a function parentheses-less on the global scope, avoiding the deprecated __defineGetter__
method. It uses Object.defineProperty
instead.
We need to create a variant of the original greet
function for this:
Object.defineProperty(window, 'greet_get', { get: greet });
And then:
greet_get;
Replace window
with whatever your global object is.
You could call the original greet
function without leaving a trace on the global object like this:
Object.defineProperty({}, 'greet', { get: greet }).greet;
But one could argue we do have parentheses here (although they are not involved in the actual invocation).
5. As Tag Function
Since ES6 you can call a function passing it a template literal with this syntax:
greet``;
See "Tagged Template Literals".
6. As Proxy Handler
Since ES6, you can define a proxy:
var proxy = new Proxy({}, { get: greet } );
And then reading any property value will invoke greet
:
proxy._; // even if property not defined, it still triggers greet
There are many variations of this. One more example:
var proxy = new Proxy({}, { has: greet } );
1 in proxy; // triggers greet
7. As instance checker
The instanceof
operator executes the @@hasInstance
method on the second operand, when defined:
1 instanceof { [Symbol.hasInstance]: greet } // triggers greet
Difference of calling a function with and without parentheses in JavaScript
With parentheses the method is invoked because of the parentheses, and the result of that invocation will be stored in before_add.
Without the parentheses you store a reference (or "pointer" if you will) to the function in the variable. That way it will be invoked whenever someone invokes before_add().
If that didn't clear things up, maybe this will help:
function Foo() { return 'Cool!';}
function Bar(arg) { console.log(arg);}
// Store the >>result of the invocation of the Foo function<< into Xvar x = Foo();console.log(x);
// Store >>a reference to the Bar function<< in yvar y = Bar;// Invoke the referenced methody('Woah!');
// Also, show what y is:console.log(y);
// Now, try Bar **with** parentheses:var z = Bar('Whut?');
// By now, 'Whut?' as already been output to the console; the below line will// return undefined because the invocation of Bar() didn't return anything.console.log(z);
Javascript function call with/without parentheses
setTimeout(foo, 2000)
passes the function foo
and the number 2000
as arguments to setTimeout
. setTimeout(foo(), 2000)
calls foo
and passes its return value and the number 2000
to setTimeout
.
In the first example, you’re not calling the function at all, just passing it as an argument like any other value.
As a simpler example, just log it:
function foo() {
return 5;
}
console.log(foo); // console.log is passed a function and prints [Function]
console.log(foo()); // foo() is called and returns 5; console.log is passed 5
// and prints 5
call function without parenthesis
the jquery identifier $ can be called without its parenthesis.
No. The function isn't being called.
Functions are objects. Objects can have properties. This is simply accessing a property of the function object.
function foo() { return 1;}
foo.bar = 2;
alert(foo.bar);alert(foo());
What is the difference between calling the function without parentheses and with parentheses
_incrementCounter
inside onPressed
is a function reference, which basically means it is not executed immediately, it is executed after the user clicks on the specific widget.(callback)
_incrementCounter()
is a function call and it is executed immediately.
Therefore, inside onPressed
you can either pass a function reference or an anonymous function that will act as a callback.
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
or
floatingActionButton: FloatingActionButton(
onPressed: () {
// Add your onPressed code here!
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
The is not something specific to dart, it is also done in javascript
and many other languages:
What is the difference between a function call and function reference?
Javascript function call with/without parentheses
Related Topics
How to Get Elements with Multiple Classes
Is There a Built-In Way to Loop Through the Properties of an Object
Check If All Values of Array Are Equal
React-Router: No Not Found Route
JavaScript Event Handler with Parameters
How to Remove All Listeners in an Element
What Is This JavaScript Pattern Called and Why Is It Used
How to Link Each User to Their Data in Firebase
When and Why to 'Return False' in JavaScript
Does Never Resolved Promise Cause Memory Leak
Get First and Last Date of Current Month with JavaScript or Jquery
Making Custom Right-Click Context Menus for My Web-App
Convert Hh:Mm:Ss String to Seconds Only in JavaScript