目前我正在以下列方式实现一些Javascript对象:
var graph = (function(){
var width = 200;
var height = 300;
[...]
var obj={
width: function(value){
if(value===undefined) return width;
width=value;
return obj;
},
height: function(value){
if(value===undefined) return height;
height=value;
return obj;
},[...]
};
return obj;
})();
graph.width(200)
.height(graph.width()*2);
我的访问器都以非常类似的方式定义,主要是为了允许一种链式API。
像这样定义宽度和高度真的很烦人,有什么样的模式可以用来仍然能够利用闭包的东西,而不必复制粘贴相同的函数n次?
答案 0 :(得分:2)
您可以编写一个生成这些函数然后调用它的函数,但我不能说它很漂亮,因为您没有对闭包变量的简洁访问。
请请不要在生产中使用它,这只是一个概念证明。
我们在这里要做的是在语言中引入宏,该宏将被称为generate
。调用generate(propName)
将生成您想要的属性的getter。我们将代码包装在一个函数中,然后自己处理宏。 这只是为了证明这个概念。
语法类似于:
var graph = Capture(function () {
var width = 200;
var height = 300;
var obj = {
width: generate(width),
height:generate(height)
};
return obj;
});
首先:
我们的工作如下:
var graph = Capture(function () {
[..]
});
generate
关键字与适当的内容function Capture(src) {
src = src.toString()
src = src.replace(/generate\((.*?)\)/g, function (a, b) {
return "function(value){"+
"if(value===undefined){ return "+b+"; } "+b+" = value; return obj;}";
});
console.log(src)
return eval("("+src+")")();
}
我们匹配generate(SOMETHING)
并将其替换为您想要的属性。这就是替换所做的。
由于我们一次评估了所有内容,因此它可以访问闭包。这给了我们想要的东西和更短的语法。
更好的选择是使用带有_varName
表示法的私有,并为这些目的完全避免使用闭包变量。这是大多数库所做的,非常清楚,并且你没有这些问题,你可以简单地使用括号表示法和bind
作为语法糖。
答案 1 :(得分:2)
你也可以创造一个私人物品 - 而不是世界上最可怕的东西:
function generate(me, prop) {
return function(value) {
if(arguments.length === 0) return me[prop];
me[prop] = value;
return this;
};
}
var graph = (function() {
var me = {
width: 200,
height: 300
};
var obj = {
width: generate(me, 'width'),
height: generate(me, 'height')
};
return obj;
})();