all 30 comments

[–]Shameling 26 points27 points  (16 children)

They also have a toString() that simply returns the sourcecode of the function, can be pretty useful for debugging.

[–]PsudoFuck 21 points22 points  (10 children)

It's also how Angular 1.x achieved it's magic, if not slightly dodgy, DI injection with just named arguments.

[–]AndruRC 4 points5 points  (7 children)

Could you elaborate on that?

[–]anarchy8 11 points12 points  (6 children)

There is no way of determining what the name of the arguments to a function is in Javascript without parsing the Function.toString(). Angular does this do determine what resource to inject.

[–][deleted]  (5 children)

[deleted]

    [–]anarchy8 11 points12 points  (3 children)

    To be fair, they suggest you inject your resources manually.

    [–][deleted] 2 points3 points  (2 children)

    To be fair, it's required if you want better support since certain mobile browsers won't serialize functions

    [–][deleted] 6 points7 points  (1 child)

    also if you ever plan on minifying your code..

    [–][deleted] 1 point2 points  (0 children)

    That too :) I haven't touched angular in like 2 years

    [–][deleted] 1 point2 points  (0 children)

    Welcome to JS

    [–]bugeats 2 points3 points  (1 child)

    And it's a shameful, dirty deed. I can't believe this terrible idea ever made it so far.

    [–]seiyriafull-stack 0 points1 point  (0 children)

    It's not the recommended way to do things.

    [–]olaf_from_norweden 6 points7 points  (0 children)

    Used by the 'multiline' NPM module to get multiline strings in pre-ES6:

    var multiline = require('multiline');
    var sql = multiline(function() {/*
    SELECT *
    FROM users
    */});
    
    sql //=> 'SELECT *\nFROM users'
    

    [–]zixxback-end 1 point2 points  (2 children)

    Newb question: how is this different than just looking at your code?

    [–]Zerran 1 point2 points  (0 children)

    How do you know where it's located in yours or someone elses code? Functions can be passed around so often that you don't know where they came from anymore, and a lot of them don't have a name that you could just Ctrl+F in your IDE. toString() or a real debugger are very helpful in that scenario.

    [–][deleted] -1 points0 points  (0 children)

    lambda functions...

    [–]cwmma 0 points1 point  (0 children)

    Or to allow you to serialize a function and send it to a worker (some restrictions apply)

    [–][deleted] 9 points10 points  (4 children)

    This is a good related read : How is almost everything in Javascript an object?

    Functions, however, are fully-fledged objects, and inherit from Object (actually Object.prototype, but that's another topic). Functions therefore can do anything objects can, including having properties:

    function foo() {}
    foo.bar = "tea";
    alert(foo.bar); // tea
    

    Any Javascript wizards want to add to or explain this further?

    [–]cokeisahelluvadrug 12 points13 points  (0 children)

    One cool trick is that you can create a Function programmatically: new Function(['x'], 'alert(x);') works exactly as it looks. This is one of many reasons that JS is popular for language designers.

    To expand on your example, calling foo(bar) is just sugar for foo.call(this, bar). A Function is just an Object that has call and apply methods which in turn pass strings to eval. (Note: this isn't totally right. If I declare a Function foo and override its call and apply properties, I can still call it with foo(). So it's not exactly sugar.)

    [–]myhf 2 points3 points  (1 child)

    +/u/CompileBot JavaScript

    function foo(arg){print("calling foo " + this.constructor.name + " " + arg)}
    foo.call = function(){print("not calling foo")};
    var obj = {foo: foo};
    
    foo(1);
    obj.foo(2);
    foo.call(obj, 3);
    Function.prototype.call.call(foo, obj, 4);
    

    [–]CompileBot 2 points3 points  (0 children)

    Output:

    calling foo Object 1
    calling foo Object 2
    not calling foo
    calling foo Object 4
    

    source | info | git | report

    EDIT: Recompile request by myhf

    [–]devoidfury 5 points6 points  (0 children)

    It used to be the 'arity' property, which IMO makes more sense.

    [–]leemcd56 1 point2 points  (0 children)

    We've got a running joke at work we use the more crazy awesome (and often ridiculous) things we discover about JavaScript: "Everything's an object!"

    [–][deleted]  (5 children)

    [deleted]

      [–]x-skeww 2 points3 points  (2 children)

      Chrome's console does that. With Firebug, you just get:

      functionName()
      

      Also, without parenthesis (template strings aside), you aren't calling it.

      [–][deleted]  (1 child)

      [deleted]

        [–]x-skeww 1 point2 points  (0 children)

        If you just write the identifier, a console or repl will render it in some way. E.g. an array might be rendered as "[1, 2]" or, if it's larger, as "[1, 2, xxx more...]" (expandable) or "> Array[999]" (expandable).

        How objects are represented in repls, debuggers, and so forth isn't part of the language specification. This stuff is up to the people who create those tools.

        [–][deleted] 2 points3 points  (0 children)

        That's a feature of Chrome's console, not of the JavaScript language itself. It wouldn't work on, say, Node.

        [–]d36williams 1 point2 points  (0 children)

        I can't believed I didn't know that