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

the*_*d47 2 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
    }
})();
Run Code Online (Sandbox Code Playgroud)

所需的结果如下:

module.publicVariable();      // 0
module.publicVariable(1);     // 1
module.publicVariable();      // 1
module.test();                // 1
Run Code Online (Sandbox Code Playgroud)

但相反,我得到:

module.publicVariable();      // 0
module.publicVariable(1);     // 1
module.publicVariable();      // 1
module.test();                // 0
Run Code Online (Sandbox Code Playgroud)

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

publicVariable: pub(publicVariable),    // same as "pub(0)"
Run Code Online (Sandbox Code Playgroud)

我知道在 javascript 中无法通过引用传递。那么我还能如何完成我正在尝试做的事情呢?我不在乎 props 是通过函数还是属性调用的。

即以下任何一项都可以

module.publicVariable = "new value";
module.publicVariable("new value");
Run Code Online (Sandbox Code Playgroud)

我只是真的厌倦了写作:

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
}
Run Code Online (Sandbox Code Playgroud)

因为这在具有大量用户可访问属性的大型项目中变得非常快。

Ism*_*OUH 5

问题是这段代码:

function pub (variable) {
    return function (value) {
        return (arguments.length ? variable = value : variable);
    }
}
Run Code Online (Sandbox Code Playgroud)

可以完美地用作 getter,但作为 setter:如果您更改参数本身(变量),则不会影响输入参数的项目。但是,如果您更改参数的内部结构,它将传播回来。

相反,您可以使用 javascript getter / setter

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);
Run Code Online (Sandbox Code Playgroud)

演示:

function pub (variable) {
    return function (value) {
        return (arguments.length ? variable = value : variable);
    }
}
Run Code Online (Sandbox Code Playgroud)

另一个通用替代方案:

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());
Run Code Online (Sandbox Code Playgroud)

演示:

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);
Run Code Online (Sandbox Code Playgroud)