Javascript:用于揭示模块模式的通用getter / setter

时间:2016-07-19 21:35:20

标签: javascript properties revealing-module-pattern

基本上我要做的是编写一个可重用的getter / setter来使用模块模式公开变量

// the getter/setter
function pub (variable) {
    return function (value) {
        return (arguments.length ? variable = value : variable);
    }
}

var module = (function () {

    var publicVariable = 0;

    function test () {
        return publicVariable;
    }

    return {
        publicVariable: pub(publicVariable),
        test: test
    }
})();

所需的结果如下:

module.publicVariable();      // 0
module.publicVariable(1);     // 1
module.publicVariable();      // 1
module.test();                // 1

但我得到了:

module.publicVariable();      // 0
module.publicVariable(1);     // 1
module.publicVariable();      // 1
module.test();                // 0

我认为这是因为以下行将publicVariable的当前值传递给pub,因此创建的唯一闭包是pub内的闭包,并且没有指向变量的链接本身。

publicVariable: pub(publicVariable),    // same as "pub(0)"

我知道在javascript中无法通过引用传递。那么我怎样才能完成我想做的事情呢?我不关心道具是否被函数或属性调用。

即。以下任何一种都很好

module.publicVariable = "new value";
module.publicVariable("new value");

我只是厌倦了写作:

function prop1f (value) {  return (arguments.length ? prop1 = value : prop1); }
function prop2f (value) {  return (arguments.length ? prop2 = value : prop2); }
function prop3f (value) {  return (arguments.length ? prop3 = value : prop3); }

return {
    prop1: prop1f,
    prop2: prop2f,
    prop3: prop3f
}

因为这对于具有大量用户可访问属性的大型项目来说非常快速。

1 个答案:

答案 0 :(得分:3)

问题是这段代码:

function pub (variable) {
    return function (value) {
        return (arguments.length ? variable = value : variable);
    }
}

可以完美地作为一个getter,但作为setter:如果你改变参数本身(变量),那将不会影响输入参数的项目。但是如果你改变参数的内部,那将会传播回来。

相反,您可以使用javascript getters / setters

var module = (function () {

    var publicVariable = 0;

    function test () {
        return publicVariable;
    }

    return {
        set publicVariable (value) {
            publicVariable = value;
        },
        get publicVariable () {
            return publicVariable;
        },
        test: test
    }
})();

module.publicVariable = 'New value';
console.log(module.publicVariable);

演示:

var module = (function () {

    var publicVariable = 0;

    function test () {
        return publicVariable;
    }

    return {
    	set publicVariable (value) {
            publicVariable = value;
        },
        get publicVariable () {
        	return publicVariable;
        },
        test: test
    }
})();

module.publicVariable = 'New Value';
console.log(module.publicVariable);
console.log(module.test());

另一个通用替代方案:

var module = (function () {

    var publicVariable = 0;

    function test () {
        return publicVariable;
    }

    return {
        //This function can access `publicVariable` !
        publicVariable: function(value) {
            return (arguments.length ? publicVariable = value : publicVariable);
        },
        test: test
    }

})();

module.publicVariable('new Value');
console.log(module.publicVariable());

演示:

var module = (function () {

    var publicVariable = 0;
    
    function test () {
        return publicVariable;
    }

    return {
        //This function can access `publicVariable` !
    	publicVariable: function(value) {
        	return (arguments.length ? publicVariable = value : publicVariable);
        },
        test: test
    }
    
})();

module.publicVariable('new Value');
console.log(module.publicVariable());