A function and an object at the same time?

后端 未结 2 1051
广开言路
广开言路 2021-02-14 01:36

Is it possible that after creating a function variable you can actually assign properties to it as if it\'s a regular object? This is what I did:

var example = f         


        
相关标签:
2条回答
  • 2021-02-14 02:22

    So now basically the 'example' var acts as a function and as an object at the same time.

    It doesn't act as a function and an object, it is a function and an object. Functions are objects in JavaScript.

    This raised some questions for me, one of which is why

    Fundamentally because that's what Eich decided to do in those 10 days in May 1995. Why he decided that is something only he can answer, but there have been many languages through the years that also see no reason to treat functions as something special and different. Presumably he was influenced by those. It's incredibly handy and flexible that functions are proper objects. For instance:

    function foo() {
        // ...
    }
    var f = foo;
    

    I can use the variable f to refer to foo because foo is an object. In many languages, such as Java, it's a real pain to do that (though Java is a bit better now thanks to its recently-added lambdas).

    Since functions are objects, they have a prototype, which means I can add features to all functions. For instance: I find it quite handy to be able to take a function and "bake in" (or "curry") arguments:

    // A simple function
    function foo(a, b) {
        console.log("a is " + a);
        console.log("b is " + b);
    }
    
    // Create a new one that, when called, will call the original passing in
    // 1 as the first argument and then passing in any further arguments,
    // preserving the `this` it was called with
    var f = foo.curry(1);
    
    // Call it
    f(2); // "a is 1" / "b is 2"
    

    Since JavaScript doesn't have a curry function (it has bind, which is similar, but interferes with this), I can add one:

    var slice = Array.prototype.slice;
    Object.defineProperty(Function.prototype, "curry", {
        value: function() {
            var f = this;
            var args = slice.call(arguments);
            return function() {
                return f.apply(this, args.concat(slice.call(arguments)));
            };
        }
    });
    

    And voilà, now I can use curry on any function:

    var slice = Array.prototype.slice;
    Object.defineProperty(Function.prototype, "curry", {
      value: function() {
        var f = this;
        var args = slice.call(arguments);
        return function() {
          return f.apply(this, args.concat(slice.call(arguments)));
        };
      }
    });
    
    // A simple function
    function foo(a, b) {
      snippet.log("a is " + a);
      snippet.log("b is " + b);
    }
    
    // Create a new one that, when called, will call the original passing in
    // 1 as the first argument and then passing in any further arguments,
    // preserving the `this` it was called with
    var f = foo.curry(1);
    
    // Call it
    f(2); // "a is 1" / "b is 2"
    <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
    <script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

    is there a way to do this by creating an object literal

    No, the only way to create a function is to start out with a function. You can't take a non-function object and turn it into a function.

    0 讨论(0)
  • 2021-02-14 02:22

    Functions are indeed objects in JavaScript. As any other object, they also have a prototype, that's where methods such as .call(), .apply() & .bind() come from.

    0 讨论(0)
提交回复
热议问题