创建具有属性的函数

Mar*_*tin 3 javascript function object javascript-objects

对不起,我不知道这个名字.

我想要一个函数和一个只有一个变量属性的对象.

下面是它的工作原理:

var obj = function() {
    return "foo";
};

obj.prop = "bar";

obj(); // => "foo"
obj.prop; // => "bar"
Run Code Online (Sandbox Code Playgroud)

这很好,但我想改变这个顺序:

var obj = { prop: "bar" };
obj = function() {
    return "foo";
};

obj(); // => "foo"
obj.prop; // => undefined
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?

我想这样做,因为我有很多属性要添加到对象:

var obj = function() {
    return "foo";
};

obj.prop1 = "bar1";
obj.prop2 = "bar2";
obj.prop3 = "bar3";
obj.prop4 = "bar4";
obj.prop5 = "bar5";
obj.prop6 = "bar6";
obj.prop7 = "bar7";
//...
Run Code Online (Sandbox Code Playgroud)

Mat*_*wne 6

这是不可能的,因为当你这样做时:

obj = function() {
    return "foo";
};
Run Code Online (Sandbox Code Playgroud)

...您将变量分配给obj新函数,因此它不再指向您创建的原始对象({ prop: "bar" }).

因此,如果要向函数对象添加属性,则必须始终先创建函数,然后添加属性.

作为替代方案,您可以执行以下操作:

var props = {
    prop1: "bar1",
    prop2: "bar2"
};

var obj = function() {
    return "foo";
};

for (var key in props) {
    obj[key] = props[key];  
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您碰巧有jQuery可用(并且没有Object.assign可用):

jQuery.extend(obj, props);
Run Code Online (Sandbox Code Playgroud)

(当然有可用的垫片Object.assign,这将允许@ Pointy的答案在旧浏览器中工作.)

  • @Martin谢谢......我可能错了,但我不知道你怎么能让它比这更好,除非`Object.assign`的本机实现(在新的浏览器中可用)有一些内部性能优化.在任何情况下我都不会担心 - 最好关注性能差异,这些差异实际上比循环几十个属性的小事情更重要...... (2认同)

Poi*_*nty 5

如果您想使用一个语句执行此操作,ES2015(和一些库)可以让您:

var obj = Object.assign(
  function() { /* ... */ },
  { "hello": "world" }
);
Run Code Online (Sandbox Code Playgroud)

这将为您obj提供属性"hello"的功能.请注意,这与单独的赋值实际上是一样的,但它们都被包装成一个整体表达式,这很好,因为它意味着你可以做类似的事情

return Object.assign(function() { /* whatever */ }, {
  prop: whatever,
  // ...
});
Run Code Online (Sandbox Code Playgroud)