函数内函数内的javascript变量范围

时间:2017-02-06 17:41:20

标签: javascript

有人可以解释下面的代码吗?为什么内部函数不能访问同一父函数中的“内部”变量 - 但它们似乎与对等函数共享相同的变量?我知道我可以在子函数中使用“this”来访问父函数中的“inside”变量,但我很困惑为什么需要这样做....我有效地创建了类实例可能想要更静态的东西?我一直在使用这种模式来包装javascript功能,但现在我想知道是否有更好/更简单的模式可以避免变量封装的挑战(更静态的东西)?感谢您的见解。

var wrap = function() {
  var inside = null;

  function showInside() {
    console.log(inside);
  }

  function changeInside() {
    console.log(inside);
    inside += 'test';
  }

  return {
    inside: inside,
    showInside: showInside,
    changeInside: changeInside
  };
}();

wrap.changeInside();
wrap.showInside();
wrap.changeInside();
wrap.showInside();
console.log(wrap.inside);

2 个答案:

答案 0 :(得分:6)

  

为什么不让内部功能访问"内部"同一个父函数中的变量 - 但它们似乎与对等函数共享相同的变量?

他们这样做。

你很困惑,因为当你说:

  return {
    inside:inside,

将变量inside复制到新对象的属性inside。您可以在创建对象时执行此操作。

稍后更改变量的值时,它与属性无关,因此属性不会得到更新。

您需要使用getter / setter将属性链接到变量。



var wrap = function() {
  var inside = null;

  function showInside() {
    console.log(inside);
  };

  function changeInside() {
    console.log(inside);
    inside += 'test';
  }

  return {
    get inside() {
      return inside;
    },
    set inside(value) {
      inside = value;
    },
    showInside: showInside,
    changeInside: changeInside
  };

}();

wrap.changeInside();
wrap.showInside();
wrap.changeInside();
wrap.showInside();
console.log(wrap.inside);




答案 1 :(得分:0)

我认为你有一个概念问题。让我们看看:

var wrap = function(){
    ...
}();

最后()表示您没有将该功能分配给wrap,您调用该功能并指定返回值wrap

返回值为

return {
    inside:inside,  //The value of inside (null) 
    showInside:showInside, //The local function showInside
    changeInside:changeInside //The local function changeInside
};

请参阅inside中的变量wrap.inside,您只需调用该函数时的值。

首先,您可能希望执行以下操作:

var wrap = function() {
    ....      
    return this; //Return the object itself
}();

然后,函数内的变量和函数属于函数的作用域。无法从该范围外访问。因此,您可以改为定义属性

var wrap = function() {      
    this.inside = 1; //property

    var insideVar = 2; //variable

    this.showInside=function() { //property (with a function assigned to it)
        console.log(insideVar);
        console.log(this.inside);   
    }; 

    this.changeInside=function() { //property
        insideVar+=2;
        this.inside+=1;
    };

    return this;
}();

现在:

console.log(wrap.inside); //-> 1
console.log(wrap.insideVar); //-> undefined
console.log(wrap.changeInside());
console.log(wrap.showInside); //-> 4 and 2
console.log(wrap.inside); //-> 2

希望差异很明显。否则只需要更多解释。