揭示模块模式是不是设置我的私有变量,为什么?

时间:2015-01-09 16:31:39

标签: javascript scope

function stapler() {

    var color = "black";

    function setColor(newColor) {
        console.log(color); //2. - black
        color = newColor;
        console.log(color); //3. - brown
    }

    function displayColor() {
        console.log(color);
    }

    return {
        c: color,

        set: setColor,

        display: displayColor
    }
}

thing = stapler();

console.log(thing.c); //1. - black
thing.set('brown');
console.log(thing.c); //4. - black, why doesn't this print brown?

从上面可以看出,thing.c(最后一行)返回黑色,但为什么不是棕色?为什么不保存更改?我错过了什么?

编辑:

请参阅http://repl.it/7gs以获取以下代码的工作副本。

function stapler() {

    var color = "black";

    function setColor(newColor) {
        console.log(color); //2. - black
        color = newColor;
        console.log(color); //3. - brown
    }

    function getColor() {
        return color;
    }

    return {
        get: getColor(),

        set: setColor,
    }

}

thing = stapler();

console.log(thing.get); //1. - black
thing.set('brown');
console.log(thing.get); //4. - black, why isn't this brown?

最后,要真正使这复杂化......请查看以下示例 -

(可在http://replit.com/7hD查看)

function stapler() {

    var color = "black";

    function setColor(newColor) {
        console.log(color); //2. - black, 6. - brown, why now has it changed?
        color = newColor;
        console.log(color); //3. - brown, 7. - purple
    }

    function getColor() {
        return color;
    }

    return {
        get: getColor(),

        set2: function(newColor) {
            setColor(newColor);
        },

        set: setColor,
    }

}

thing = stapler();

console.log(thing.get); //1. - black
thing.set('brown');
console.log(thing.get); //4. - black, why isn't this brown?
console.log(thing.get); //5. - black, why isn't this brown

console.log('-----');

thing.set2('purple');
console.log(thing.get); //8. - black

这里发生了什么?

2 个答案:

答案 0 :(得分:3)

你需要添加一个getter - return {c:color/*...*/第一次将颜色的副本放入该变量,但它并没有直接链接到内存。对私有color变量的任何更改都没有链接到c元素(这实际上很好 - 如果它以这种方式工作,您可以使用thing.c='magenta';在外部更改颜色)你需要:

function getColor() {return color; }
/*...*/
return { get: getColor, set: setColor, display: displayColor };

答案 1 :(得分:0)

将代码的两行更改为

function stapler() {

  var color = "black";

  function setColor(newColor) {
    console.log(color); //2. - black
    // color = newColor; CHANGE TO
    this.color = newColor;
    console.log(color); //3. - brown
  }

  function displayColor() {
    //console.log(color); CHANGE TO
    console.log(this.color);
  }

  return {
    c: color,

    set: setColor,

    display: displayColor
  }
}

你会没事的。

现在,当然,这不再是揭示模块模式,因为你正在使用"这个",但the Revealing Module Pattern is an anti-pattern无论如何,恕我直言。