JavaScript" Class" "私人"可变范围

时间:2017-06-15 20:55:18

标签: javascript scope private

众所周知,你可以制作一个" Class"变量"私人"在JavaScript中执行以下操作:

function ClassName(attribute){
    var privateAttribute = attribute;

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

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

我知道这是有效的,我之前使用过它。但这有点打破了我的理解。在函数执行结束时,Aren的局部变量是否会超出范围?不应该根据JavaScript范围的工作原理,当你尝试从ClassName实例调用访问器时,var privateAttribute是不可访问的吗?

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

1 个答案:

答案 0 :(得分:1)

您缺少的是可以通过多种方式调用函数......

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

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

var myObj = new ClassName(data);

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

除此之外,如果一个函数包含一个“闭包”(一个嵌套的作用域引用来自更高作用域的变量),并且嵌套函数的生命周期比较高的作用域更高,而较高的变量来自,那么该变量即使在它定义的函数时也不会超出范围。这个概念起初很多人都会参与其中,但它很有意义 - 如果一个(假设)返回的函数依赖于当它的块终止时通常会超出范围的数据,但是返回的函数比这更长,那么数据不会也不会被垃圾收集。

最后,实际上只是要清楚,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;
}