1

目前我正在以下列方式实现一些 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 次?

4

2 回答 2

2

您可以编写一个生成这些函数然后调用它的函数,但我不能说它很漂亮,因为您无法巧妙地访问闭包变量。

不要在生产中使用它,这只是一个概念证明。

我们在这里要做的是在语言中引入一个,该宏将被称为generate. 调用generate(propName)将为您的属性生成您想要的样式的吸气剂。我们将代码包装在一个函数中,然后自己处理宏。这只是为了证明这个概念。

语法类似于:

var graph = Capture(function () {
    var width = 200;
    var height = 300;

    var obj = {
        width: generate(width),
        height:generate(height)
    };
    return obj;
});

首先:

这是一个工作小提琴

我们要做的是:

1) 我们将您的 IIFE 包装在 Capture 函数中,这将处理内容

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)并替换为您想要的具有该属性的功能。这就是替换的作用。

3)我们评估那个函数,然后调用它

由于我们一次评估了它,它可以访问闭包。这给了我们想要的东西和更短的语法。

我们应该怎么做呢?

更好的选择是使用带有_varName符号的私有,并出于这些目的完全避免闭包变量。这是大多数库所做的,很清楚,你没有这些问题,你可以简单地使用括号符号和bind语法糖。

于 2013-07-29T08:42:56.737 回答
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;
})();
于 2013-07-29T14:28:13.893 回答