同时是一个函数和一个对象

A function and an object at the same time?

本文关键字:一个 函数 一个对象      更新时间:2023-09-26

是否有可能,在创建一个函数变量后,您实际上可以将属性分配给它,就像它是一个常规对象一样?我是这样做的:

var example = function(a, b){
    console.log(a, b);
}
example.someProperty = 'hi there';

然后在浏览器控制台中输入这些行:

example('Hello', 'world') // Hello world
example.someProperty // hi there

所以现在基本上'example' var同时充当函数和对象。这给我提出了一些问题,其中一个是为什么,另一个-是否有办法通过创建对象字面量来做到这一点,因为我想不出这样的方法。

所以现在基本上'example' var同时作为一个函数和一个对象。

不充当函数和对象,它函数和对象。函数在JavaScript中是对象。

这给我提出了一些问题,其中之一就是为什么

从根本上说,这就是埃奇在1995年5月的那10天里决定要做的事情。为什么他决定这么做,这是只有他自己才能回答的问题,但是这些年来,有很多语言也没有理由把函数当作特殊的、不同的东西来对待。他大概是受到了这些人的影响。函数作为合适的对象是非常方便和灵活的。例如:

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

我可以使用变量f来指代foo,因为foo是一个对象。在许多语言中,比如Java,这样做是非常痛苦的(尽管由于最近添加了lambdas, Java现在稍微好了一点)。

由于函数是对象,它们有一个原型,这意味着我可以向所有函数添加特性。例如:我发现能够接受一个函数和"bake in"(或"curry")参数是非常方便的:

// 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"

由于JavaScript没有curry函数(它有bind,这是类似的,但干扰this),我可以添加一个:

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)));
        };
    }
});

现在我可以在任何函数上使用curry了:

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>

是否可以通过创建对象字面值 来实现这一点?

不,创建函数的唯一方法是从函数开始。你不能把一个非函数对象变成函数

函数在JavaScript中确实是对象。和任何其他对象一样,它们也有一个原型,这就是.call(), .apply() &.bind() from。