众所周知,你可以制作一个" Class"变量"私人"在JavaScript中执行以下操作:
function ClassName(attribute){
var privateAttribute = attribute;
this.accessor = function(){
return privateAttribute;
}
this.mutator = function(x){
privateAttribute = x;
}
}
我知道这是有效的,我之前使用过它。但这有点打破了我的理解。在函数执行结束时,Aren的局部变量是否会超出范围?不应该根据JavaScript范围的工作原理,当你尝试从ClassName实例调用访问器时,var privateAttribute
是不可访问的吗?
答案 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;
}