【问题标题】:Creating a function with properties创建具有属性的函数
【发布时间】:2015-11-30 23:26:36
【问题描述】:

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

我想要一个函数和一个对象,其属性只存在一个变量中。

这是它的工作原理:

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

obj.prop = "bar";

obj(); // => "foo"
obj.prop; // => "bar"

这工作正常,但我想改变这个顺序:

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

obj(); // => "foo"
obj.prop; // => undefined

有没有办法做到这一点?

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

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

【问题讨论】:

  • 从技术上讲,你可以,但它会比你这里的代码多得多。为了简单地做到这一点,我同意@Grundy。你不能。
  • @aaronfrost 什么意思,先定义属性(在创建函数之前),然后再将它们复制到函数对象中?
  • @Martin 查看我的更新答案(回答您更新的问题)。
  • @torazaburo,就像下面的答案一样。你能行的。但是,它需要代码来完成。
  • @torazaburo 你说得对,我应该这样做,但就像你在另一条评论中所说的那样,这没关系,因为我只想分配大约 20 个属性。

标签: javascript function object javascript-objects


【解决方案1】:

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

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

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

所以如果你想给一个函数对象添加属性,你必须总是先创建函数,然后再添加属性。

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

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

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

for (var key in props) {
    obj[key] = props[key];  
}

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

jQuery.extend(obj, props);

(当然有可用于Object.assign 的填充程序,这将允许@Pointy 的答案在旧版浏览器中工作。)

【讨论】:

  • 在你的循环中,你应该检查props.hasOwnProperty(key)stackoverflow.com/a/921808/1913729
  • 是的,这可以使用很少的代码。我会接受这个答案,如果没有更好的解决方案(性能)。
  • @blex 我认为在这种情况下没有必要...... OP 没有说明props 对象将是某个原型的实例(即它会继承可枚举属性)。
  • @Martin 谢谢...我可能是错的,但我不知道你怎么能让它表现得比这更好,除非 Object.assign 的本机实现(在较新的浏览器中可用)有一些内部性能优化...在任何情况下我都不会担心它 - 最好关注性能差异实际上比循环几十个属性之类的小事情...
【解决方案2】:

如果你想用一个语句做到这一点,ES2015(和一些库)让你这样做:

var obj = Object.assign(
  function() { /* ... */ },
  { "hello": "world" }
);

它将为您提供obj 作为具有“hello”属性的函数。请注意,这实际上与单独的赋值是一样的,但它都封装为一个整体表达式,这很好,因为这意味着您可以执行类似的操作

return Object.assign(function() { /* whatever */ }, {
  prop: whatever,
  // ...
});

【讨论】:

  • 是的,这可行,但我需要一个也适用于 IE8 的解决方案
  • 我同意@torazaburo 的观点......无论他的回答还是我的回答都应该同样为您服务。性能差异是微不足道的。避免过早优化。
  • @MattBrowne 对。不是我的答案,但无论如何。
【解决方案3】:

我也同意 Grundy,但你可以这样做:

var x = function(){
var obj = {};
  return {
    objToReturn: obj,
    objFunction: function(){return 'foo';},
    addItemsToObject: function (key, value) {
      obj[decodeURIComponent(key)] = value;
    }
   }
};    

老实说,我不知道这是否是你真正想要的,但在这种情况下,你可以执行“x”函数,然后你就可以访问 “objFunction”、“objToReturn”或“addItemsToObject”函数。

所以它会是这样的:

var y = x();

for (propertie in yourProperties){      
  y.addItemsToObject
    (propertie, yourProperties[decodeURIComponent(propertie)]);
}

然后:

y.objFunction();

'foo'

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    • 2013-09-15
    • 2015-05-07
    • 1970-01-01
    • 2019-12-28
    • 1970-01-01
    相关资源
    最近更新 更多