Javascript 不使用';我不知道属性是变量还是函数
我的对象中的许多属性可能是值,也可能是返回值的函数。访问值不同于调用函数(foo;vs foo();)。我目前采取以下方法。有人能推荐更好的吗Javascript 不使用';我不知道属性是变量还是函数,javascript,function,object,Javascript,Function,Object,我的对象中的许多属性可能是值,也可能是返回值的函数。访问值不同于调用函数(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.
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);保持干燥的方法。如果您不能推荐更好的解决方案,我仍然希望听到您对提供的两种方法的反馈
谢谢。在这种情况下,我通常使用全局实用程序将可能是函数的每个属性转换为一个,然后始终调用函数而不是访问属性:
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());
我不知道这是否是你的选择——你可能想考虑JavaScript的GETT/SETER函数。例如:
var foo = {
get bar() {
return 1;
}
};
通过这种方式,您可以像访问任何属性一样访问bar
,也就是说,通过计算foo.bar
当然,这可能会带来一些浏览器兼容性问题——Javascript getter/setter是相当新的;2009年,它们被添加到ECMA-262的第5版中。在这种情况下,一些库所做的是通过
get
和set
方法来实现所有访问,而不是直接调用任何东西
对象获取(“bar”)
对象集(“条”,4)
然后,在这些方法的实现中,您可以检查底层类型并直接返回值或调用其函数。在set方法中,如果它是一个函数,您可以传递arguments数组,以便在需要时在setter上允许任意数量的参数
这还允许子类根据需要重写这些方法,因为现在基本上已经有了setter和getter。显然,由于放弃了直接设置和检索属性的清洁度,因此在使用这些属性时会有一些牺牲。但是,你要求设计模式,所以这是一个
YUI库使用此方法
与本机setter和getter相比,它的优点是可以在任何浏览器版本中使用(有上述缺点)。我很想使用它,但不幸的是,我需要支持IE。