1

How do I interpret this code:

  var element = $compile('<p>{{total}}</p>')(scope);

Taken from https://docs.angularjs.org/api/ng/service/$compile

This is the first time I've seen something like:

var x = someFunction(abc)(d);

I don't know what a set of braces next to each other means in Javascript.

Matt
  • 74,352
  • 26
  • 153
  • 180
Johann
  • 27,536
  • 39
  • 165
  • 279
  • possible duplicate of [What is this (IIFE) construct in javascript?](http://stackoverflow.com/questions/8228281/what-is-this-iife-construct-in-javascript) – Ken Jul 07 '14 at 10:18
  • 3
    @Ken this is a completely different topic...! – Christoph Jul 07 '14 at 10:19

4 Answers4

5

someFunction(abc) returns a function. The (d) immediately calls the returned function, and passes the parameter d to it.

Conceptually, someFunction(abc) could be defined as something like below. Here, someFunction(abc) returns a function which accepts a parameter (d). It alerts the sum of abc + d.

function someFunction(abc) {
    return function (d) {
        alert(abc + d);
    };
}

var adder = someFunction(10);

adder(2); // 12
adder(3); // 13

// ... or
someFunction(10)(2); // 12
someFunction(10)(3); // 13

Experiment here; http://jsfiddle.net/756g3/


In your specific case, $compile('<p>{{total}}</p>') returns a template function. You're immediately calling that template function, passing the scope variable to it.

Matt
  • 74,352
  • 26
  • 153
  • 180
  • So if someFunction ever returns null, an error would get generated. Not sure if using that kind of syntax is a good practice. – Johann Jul 07 '14 at 10:23
  • @AndroidDev: Whilst technically true, you don't gain yourself any extra security by doing `var foo = someFunction(abc); foo(d);`. You'd have to check that *every* returned value is a function; `var foo = someFunction(abc); if (typeof foo === 'function') { foo(d); }`, which is excessive. – Matt Jul 07 '14 at 10:24
  • @AndroidDev Well the argument is not really valid since if you don't know what a function returns then you will end up with errors anyway. You can do checks but then you write lots of unnecessary code IMHO (unless you know a priori that the function may return `null` and that is a bad practice IMHO: to return objects of different type from one function). – freakish Jul 07 '14 at 10:25
  • @freakish Depends. If it's a third party library and you can't necessarily be guaranteed a non-null value, I would not use that syntax. – Johann Jul 07 '14 at 10:26
  • @AndroidDev: it completely depends on the situation. If you *know* the function will *always* return a function (like `$compile`), there's **zero** harm in using it. As I said in my previous comment, it's a *direct* replacement for `var foo = someFunction(abc); foo(d);`. – Matt Jul 07 '14 at 10:27
  • @AndroidDev Well you can read docs of that third party library. If it is purely documented then you're doing this on your own risk. :) – freakish Jul 07 '14 at 10:28
1

Its simply invoke the parameter d on the returned (function) from someFunction

CodeWizard
  • 128,036
  • 21
  • 144
  • 167
1

Functions are first-order citizens, i.e. you can treat them like other objects, pass them to other functions and return them from other functions. Maybe this will clarify?

var fn1 = function(a) {
    var fn2 = function(b) {
        return a+b;
    };
    return fn2;
};

Now

>> fn1(1)(2)
3
>> var bar = fn1(100)
>> bar(3)
103
>> bar(15)
115

What happens is that fn1 takes an argument a and returns a function which will add a passed argument b to a. I'm bad explanation but I hope it is clear.

freakish
  • 54,167
  • 9
  • 132
  • 169
1
function makeFunc() {
    return function (foo) {
        alert(foo);
    };
}

var func = makeFunc();
func('hello');

Or, the shorthand for this:

makeFunc()('hello');

$compile returns a function, which is then being invoked.

deceze
  • 510,633
  • 85
  • 743
  • 889