2017-06-15 11 views
0

我们知道,你可以做一个“类”变“私”在JavaScript如下:JavaScript的“类”,“私人做”变量的作用域

function ClassName(attribute){ 
    var privateAttribute = attribute; 

    this.accessor = function(){ 
     return privateAttribute; 
    } 

    this.mutator = function(x){ 
     privateAttribute = x; 
    } 
} 

我知道这个工作的,我我以前用过它。但它有点破坏我的理解有点。在函数执行结束时,本地变量是否应该超出范围?不应该,根据JavaScript范围应该如何工作,var privateAttribute是不可访问的,当你尝试从ClassName的实例调用访问器?

https://www.w3schools.com/js/js_scope.asp

+1

只要存在,它就保留在对象成员的范围内。我敢肯定,有人会提供一个详细的技术说明,解释为什么我目前无法表达清楚,但你可以确信,这种行为是明确的,并将保持一致。 – CollinD

+1

https://stackoverflow.com/q/500431/215552给它一个阅读。 –

+0

[JavaScript中的变量范围是什么?](https://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript) –

回答

1

你所缺少的是一个事实,即功能可以以多种方式被称为...

如果你的函数被调用的函数,那么,是的,当函数结束时,所有的本地数据都消失了。

但是,如果该功能被称为“构造函数”:

var myObj = new ClassName(data); 

然后函数创建一个对象,它存储在myObj对象变量和实例函数的所有私人数据可用(当然内部)直到对象变量超出范围。除此之外,如果一个函数包含一个“闭包”(一个嵌套的作用域引用一个来自更高作用域的变量),并且嵌套函数的寿命比较高变量的较高作用域的寿命更长from,则该变量即使在它定义的函数时也不能超出范围。这个概念一开始就让很多人知道,但它非常有意义 - 如果一个(比方说)返回函数依赖通常在块终止时超出范围的数据,但返回的函数的寿命比这更长,那么数据将不会被垃圾收集。

最后,真的只是要清楚,JavaScript实际上并没有类。它有原型,对象将继承这些原型。由于原型和继承是如何在JavaScript中工作的,因此您的示例代码实际上将使用附加到原型的方法编写,以便该对象的所有实例(通过构造函数调用创建)不必存储相同的函数(从而减少这些实例的内存占用)。

function ClassName(attribute){ 
    // A regular variable will act as a private "class field" 
    var privateAttribute = attribute; 

    // But members that are attached to 'this' become instance fields 
    this.exposedPrivateData = privateAttribute; 
} 

// Methods get attached to the underlying prototype object that 
// all instances of your object will inherit from 
ClassName.prototype.accessor = function(){ 
     return this.exposedPrivateData; 
}; 

ClassName.mutator = function(x){ 
     this.exposedPrivateData = x; 
} 
+0

Javascript真的有混乱up view scoping system ... – HumbleWebDev

+0

@ user3496058实际上,它并没有搞砸,但它需要一点时间才能适应,因为JavaScript不像大多数其他语言。 JavaScript具有“词法范围”,一旦你了解了这一点,很多事情就会变得清晰起来。 –