2017-02-06 69 views
0

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

+0

究竟是什么问题? –

+1

你的问题与功能无关。这里是你看到的简化版本:'var foo = 42; var obj = {foo:foo}; foo = 21;的console.log(obj.foo);'。 JavaScript是**按值传递**。 '{foo:foo}'将'foo'的值的* copy *赋给属性'foo'。 –

+0

我认为**在JavaScript中传递值**令人困惑,因为您也可以将引用作为值传递。如果'foo'是一个对象,则不会将该对象的副本分配给该对象的引用副本。 –

回答

6

为什么不内部函数访问“内部”变量相同的父函数内 - 但他们似乎也有同感与对等的功能相同的变量?

他们这样做。

return { 
    inside:inside, 

您的变量inside复制到财产inside新对象:

,因为当你说你是困惑。您在创建对象时执行此操作。

当您更改变量的价值后,它与财产没有关联,所以财产没有更新。


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

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);

+0

非常感谢您的帮助,清除我的困惑! :-) – user6096790

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 
}; 

看,你有没有在wrap.inside变量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 

希望的差别是显而易见的。否则,请索取更多解释。

+0

感谢您的帮助!我认为你在我的代码和理解中发现了同样的问题,但接受的答案对我来说更加清晰和有帮助。我使用和喜欢该模式的主要原因是封装和能够选择性地隐藏和暴露函数和变量从我封装在函数中的代码。我开始使用直接对象进行封装,但是它们更加混乱且难以管理,因为可能存在许多所需的函数和变量,这些函数和变量仅在对象内部有用且需要。......再次感谢。 – user6096790