Difference between assigning event handler to method with and without parentheses
You're actually a bit off in your understanding.
window.onload = doStuff;
means that when the onload event is triggered, the doStuff function will be called.
window.onload = doStuff();
means that when that line of code is reached (before the onload event is triggered), doStuff is executed and it's return result is assigned to the onload handler.
You probably want the first one unless doStuff
returns a function to be executed when the onload event is triggered.
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
Closure in event handler
why the variable
counter
get set to 0 when first click occurs.
That is not the moment it gets set to 0. This happens when the assignment to .onclick
happens. At that moment outer
is defined and executed. So that is the moment counter
is set to 0. No click is handled yet.
only the function inner() get executed
Indeed. outer
is only executed once, when the main script is executed on page load, and then never again. inner
is the function that gets assigned to onclick
and thus has the role of event handler. inner
has access to the counter
that is defined in outer
, but outer
is never executed again.
outer
is a so-called immediately executing function.
As a comparison: you could achieve something similar with this code:
var counter = 0;
element.onclick = function inner() {
counter++;
alert('Number of clicks: ' + counter);
};
...but the downside now is that counter
is a global variable, that could be altered by some other code. To make sure counter
is only available to the click handler, a closure is created for it, which you could also do like this:
function outer() {
var counter = 0;
element.onclick = function inner() {
counter++;
alert('Number of clicks: ' + counter);
};
}
outer();
The downside here is that outer
has a so-called side-effect: it assigns to element.onclick
. This is the reason to choose to return inner
and leave it to the caller of outer
to do something with it, e.g. assign it to .onclick
.
Then we get something like this:
function outer() {
var counter = 0;
return function inner() {
counter++;
alert('Number of clicks: ' + counter);
};
}
element.onclick = outer();
This is essentially the same as your code: the function is first defined, and then immediately executed. The function that gets assigned to onclick
is the one that is returned by outer
, i.e. inner
.
Yet another way to achieve this encapsulation of counter
:
function inner() {
this.counter++;
alert('Number of clicks: ' + this.counter);
}
element.onclick = inner.bind({ counter: 0 });
Here the we provide an unnamed object that is always passed as this
-argument to inner
whenever it is called. As we don't retain a reference to that object outside of this construct, we achieve the same principle: the counter's state is maintained, but is not accessible outside the handler.
Input parameter to closure in Swift with brackets
You will need to understand the variable capturing of closure idea.
Consider this example:
struct Calculator {
var a: Int
var b: Int
var sum: Int {
return a + b
}
}
Then you use this as:
let calculator = Calculator(a: 3, b: 5)
// You define a closure where you will use this calculator instance
let closure = {
// closure captures the variables that are declared prior to the declaration of the closure.
// your calculator instance is being captured here
// it's default variable capture
print("The result is \(calculator.sum)")
}
closure() // Prints "The result is 8"
Till now, everything is okay. You get what's expected.
Now consider you declare the calculator instance as var
because in some point you need to mutate it's state. This is the case where complexity arises. Look:
var calculator = Calculator(a: 3, b: 5)
let closure = {
print("The result is \(calculator.sum)")
}
// You change the state of your calculator instance anytime before the closure gets executed
calculator.b = 20
// When the closure actually executes, you will be affected by any changes outside the closure
closure() // Prints "The result is 23"
So, the default variable capture isn't really helping you, instead it's creating problem in your case.
If you want to prevent this behaviour and print 8 even if the properties change after their capturing inside the closure, we can explicitly capture the variable with a capture list like this:
// [calculator] is your capture list
let closure = { [calculator] in
print("The result is \(calculator.sum)")
}
// change anything with calculator instance
calculator.b = 20
// execute the closure
closure() // Prints "The result is 8"
Capture List keeps immutable copy of the variable(s). Thanks to this copy, further changes to calculator, outside the closure, will not affect the closure.
You can capture multiple variables at once, hence it's called Capture List. Example:
let closure = { [variable1, variable2, variable3] in
print(variable1)
print(variable2)
print(variable3)
}
I recommend you read this article Capturing Values In Swift Closures.
Now, in your case spotifyClient
is an instance of a class that may be responsible to make API calls. This instance may need some changes for calling different APIs. So, to prevent the affect of any changes to spotifyClient
outside this closure you capture this instance in a Capture List.
Capture List vs. Parameter List:
You are confusing the parameter list with the capture list. The generic syntax is:
{ [capture list] (parameter list) in
...
...
}
Now take a look at the modified version of the above example:
let closure: (String)-> Void = { [calculator] stringParameter in // When using single parameter, you can always omit the () parentheses
print("\(stringParameter). The result is \(calculator.sum)")
}
// change anything with calculator instance
calculator.b = 20
// execute the closure
closure("Hey") // Prints "Hey. The result is 8"
Calling a swift function right after the closing bracket?
There are three types of closures in Swift:
- Global functions are closures that have a name and do not capture any values.
- Nested functions are closures that have a name and can capture values from their enclosing function.
- Closure expressions are unnamed closures written in a lightweight syntax that can capture values from their surrounding context.
...
Closure expressions are a way to write inline closures in a brief,
focused syntax.
(Source: Closures in the Swift book.)
In your first example:
var test = { () -> String in return "this works" }()
{ ... }
is a closure expression. This expression is evaluated
with an empty argument list ()
. The result is the string
"this works" which is then assigned to the variable.
Your second example is a global function.
Global functions are (named) closures, but not closure expressions.
There is (as far as I know) no similar way to define a function which
is immediately evaluated.
In golang how calling a function with and without trailing brackets works when using net/http
You are not "calling" the function from main, you are providing it as a argument to HandleFunc
, registering it to be called for the path "/" in the mux.Router
. This pattern of providing a function to be called later is typically known as a "callback".
Your ParseSlash
function is of the type http.HandlerFunc
type HandlerFunc func(ResponseWriter, *Request)
Your function is eventually called by the http.Server
via its ServeHTTP
method (here, via the mux.Router
), passing the arguments shown. When the function is called, the http.ResponseWriter
and *http.Request
arguments are for the individual http request being handled.
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 X
var x = Foo();
console.log(x);
// Store >>a reference to the Bar function<< in y
var y = Bar;
// Invoke the referenced method
y('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);
Can't call function with Swift Closure as argument
First and foremost, it looks like you're trying to call an instance method of APIHelper on the class itself. If you wish to do this, you either need to make an instance of the class to be the receiver of the method, or you need to declare your method as a class method to be able to use it in the way that you're trying.
class APIHelper: NSObject {
class func getArticles(completion: (result: NSArray, error: NSError)->()) {
}
}
Additionally, the types of your parameters must be the same as those used as arguments. If you've declared the method to take an NSArray object, you should access it as NSArray, not Array, so you should be calling the method like this.
APIHelper.getArticles( { (result: NSArray, error: NSError) -> Void in
// stuff
})
Which can be simplified down to the following, which allows Swift's type inference to determine the types of the parameters so you don't have to worry about mismatching them.
APIHelper.getArticles { result, error in
// stuff
}
Related Topics
How to Sort an Array of Posts by Their Elements
Where to Place App Delegate Code in App.Swift File
Presenting a Uiviewcontroller from Skscene Shows Black Screen
With Data (Not Nsdata), in Fact How Actually Do You Make a Utf8 Version of a Jpeg
Swift: Download Image from Internet and Cache Them Doesn't Work Properly. Need Suggestions
How to Use a Specific Gmt for a Function Which Will Be Recognised by Other Time Zones
Contacts Not Recognized When Body Is Changed from Circle to Rectangle
How to Add Characters into Dateformatter
New Value Is Only Available in Sendasynchronousrequest - Swift
How Could I Request Text from a Website in Swift
Can the Byte Order of Double Be Safely Reversed
How Is a Global Variable Set to Private Understood in Swift
How to Make a Variable from a String
Checkboxes in Uitableview State Persistence
"Ambiguous Use of 'Children'" When Trying to Use Nstreecontroller.Arrangedobjects in Swift 3.0
Tests for Custom Uitableviewcell, Cellforrowatindexpath Crashes with Nil Outlets