JavaScript";“类”&引用;“私人”;可变范围

JavaScript";“类”&引用;“私人”;可变范围,javascript,scope,private,Javascript,Scope,Private,正如我们所知,您可以通过执行以下操作在JavaScript中创建“Class”变量“private”: function ClassName(attribute){ var privateAttribute = attribute; this.accessor = function(){ return privateAttribute; } this.mutator = function(x){ privateAttribute

正如我们所知,您可以通过执行以下操作在JavaScript中创建“Class”变量“private”:

function ClassName(attribute){
    var privateAttribute = attribute;

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

    this.mutator = function(x){
        privateAttribute = x;
    }
}
我知道这很有效,我以前也用过。但这有点破坏了我的理解。局部变量在函数执行结束时不应该超出范围吗?根据JavaScript作用域的工作方式,
var privateAttribute
不应该在尝试从ClassName实例调用访问器时无法访问吗


您缺少的是一个事实,即可以通过多种方式调用函数

如果函数作为函数调用,那么,是的,当函数结束时,其所有本地数据都将消失

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

然后函数创建一个对象的实例,该实例存储在
myObj
对象变量中,函数的所有私有数据都可用(当然是内部数据),直到对象变量超出范围

除此之外,如果一个函数包含一个“闭包”(一个嵌套的作用域,它引用一个来自更高作用域的变量),并且该嵌套函数的生存期比来自更高变量的更高作用域长,那么即使在定义该变量的函数不存在,该变量也不能超出作用域。这个概念一开始让很多人感到困惑,但它有着完美的意义——如果(比方说)返回函数依赖的数据在其块终止时通常会超出范围,但返回函数的寿命长于此,那么数据将不会也不能被垃圾收集

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


只要对象存在,它就一直在对象成员的作用域中。我肯定有人会提供详细的技术解释,说明我目前无法正确表达的原因,但你可以相信,这种行为是明确定义的,并将保持一致。读一读。可能是@user3496058的重复事实上,它一点也不混乱,但需要一点时间来适应,因为JavaScript与大多数其他语言不同。JavaScript有“词法范围”,一旦你了解了这一点,很多事情就会变得清晰起来。
var myObj = new ClassName(data);
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;
}