我的对象中的许多属性可能是值或返回值的函数。访问值与调用函数(foo; vs foo();)不同。我目前采取以下方法。任何人都可以推荐更好的东西吗?
var foo = {
bar: function(){
return 1;
},
// bar: 1, // bar may also be a standard value
GetBar: function(){
return $.isFunction(this.bar) ? this.bar() : this.bar;
},
Get: function(property){
return $.isFunction(property) ? property() : property;
}
}
foo.GetBar();//1
foo.Get(foo.bar);//1
我目前正在使用foo.GetBar();方法,但因为我必须为每个属性写一个新函数而不是值或函数,我认为最好使用foo.Get(foo.bar);保持干燥的方法。如果您不能推荐更好的解决方案,我仍然希望听到您对这两种方法的反馈。
感谢。
答案 0 :(得分:1)
在这种情况下,我通常使用全局实用程序将每个可能是函数的属性转换为一个,然后始终调用函数而不是访问属性:
function functor(v) {
return typeof v == "function" ? v : function() { return v; };
};
unknown = functor(unknown);
var myVar = unknown();
在这个例子中看起来有点傻,但很容易将它合并到像你这样的对象中:
var foo = {
bar: "some value or function",
get: function(key) {
return functor(this[key])();
}
};
我通常将这种方法用于可能是值或函数的配置变量 - 在这种情况下,我在途中调用functor
而不是出路:
function Foo(height, width) {
this.height = functor(height);
this.width = functor(width);
}
// make a new object with a fixed height and a width dependent
// on the current window size
var foo = new Foo(10, function() { return $(window).width() - 100; } );
// now always assume functions
console.log(foo.height(), foo.width());
答案 1 :(得分:1)
我不知道这是否适合您 - 您可能需要考虑Javascript getter / setter函数。例如:
var foo = {
get bar() {
return 1;
}
};
通过这种方式,您可以像访问任何媒体一样访问bar
,也就是说,通过评估foo.bar
。
当然这可能会引入一些浏览器兼容性问题 - Javascript getter / setter是相当新的;它们被添加到2009年的第5版ECMA-262中。
答案 2 :(得分:0)
在这种情况下,某些库所做的是通过get
和set
方法进行所有访问,而不是直接调用任何内容。
obj.get( “条”) obj.set(“bar”,4);
然后,在这些方法的实现中,您可以检查基础类型,并直接返回值或调用它的函数。在set方法中,如果它是一个函数,你可以传递arguments数组,以便在需要时在setter上允许任意数量的参数。
这也允许子类在需要时覆盖这些方法,因为你现在基本上有setter和getter。显然,由于您放弃了直接设置和检索属性的清洁度,因此在使用这些方面会有一些牺牲。但是,你要求设计模式,所以这是一个。
YUI库使用此方法。
这比原生的setter和getter的优势在于它适用于任何浏览器版本(具有上述缺点)。