一个功能和一个对象同时?

时间:2015-10-13 08:42:05

标签: javascript

在创建函数变量后,您是否可以实际为其分配属性,就像它是常规对象一样?这就是我所做的:

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

然后我在浏览器控制台中键入了这些行:

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

所以现在基本上'example'var作为一个函数同时作为一个对象。这为我提出了一些问题,其中一个是为什么,另一个是 - 有一种方法可以通过创建一个对象文字来做到这一点,因为我无法想到这样的方式。

2 个答案:

答案 0 :(得分:8)

  

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

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

  

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

从根本上说因为这就是Eich决定在1995年5月的那10天里所做的事情。为什么他认为这只是他能回答的问题,但多年来有很多语言也认为没有理由将功能视为特殊的东西和不同的。据推测,他受到了那些人的影响。功能是适当的对象,它非常方便灵活。例如:

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

我可以使用变量f来引用foo,因为foo是一个对象。在许多语言中,例如Java,这样做真的很痛苦(尽管由于最近增加的lambdas,Java现在好一点了。)

由于函数是对象,因此它们具有原型,这意味着我可以向所有函数添加功能。例如:我发现能够接受一个函数并“烘烤”(或“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>

  

有没有办法通过创建对象文字

来做到这一点

不,创建函数的唯一方法是从函数开始。您不能将非功能对象转换为函数。

答案 1 :(得分:3)

函数确实是JavaScript中的对象。与任何其他对象一样,它们也有一个原型,即.call().apply()和&amp;等方法。 .bind()来自。