模块模式中的私有变量
Private Variables in Module Pattern
我不是很清楚private的概念,如果我仍然可以通过public方法访问它并重新定义模块的属性。我的意思是,我完全可以做到:
var aModule = (function() {
var privateVar = 1;
return {
publicFunction: function() {
return privateVar;
}
}
})();
aModule.publicFunction = function() {
privateVar = function() {
console.log('a new content');
}
privateVar();
};
aModule.publicFunction(); // 'a new content'
我知道如果我用 let 或 const 在 ES6 中写它是不可能的,因为它会给我错误尝试覆盖私有变量的值,但它在 ES5 中有什么意义?
您正在覆盖 public 函数并且无法访问模块私有变量
考虑以下创建为 aModule
的 属性 的新函数,它试图仅更改 var privateVar
的值
作用域因调用位置不同而不同,并且无法访问该私有变量
var aModule = (function() {
var privateVar = 1;
return {
publicFunction: function() {
return privateVar;
}
}
})();
aModule.newFunction = function() {
// try to change privateVar in aModule
privateVar = 3
};
aModule.newFunction();
console.log(aModule.publicFunction()); //still 1 not 3
// here's where it actually ended up
console.log(window.privateVar)
私有变量不能被模块外部的代码或拥有私有变量的 class 访问或更改。
例如,您不能做 aModule.privateVar
并期望它会给您任何回报。
您的 publicFunction
就是 Java(和其他编程语言)世界所说的 "getter"。简单地说,它允许访问私有变量的值,但不允许对其进行写访问。
在你的最后一个例子中,你实际上并没有覆盖私有变量。您只是在 publicFunction
的范围内创建一个新变量并为其赋值。仅仅因为它也被命名为 privateVar
并不意味着它是相同的内存区域。
我已添加到您的代码中以证明这一点
var aModule = (function() {
var privateVar = 1;
return {
publicFunction: function() {
return privateVar;
},
getPrivateVar() {
return privateVar;
}
}
})();
aModule.publicFunction = function() {
privateVar = function() {
console.log('a new content');
}
privateVar();
};
aModule.publicFunction(); // 'a new content'
console.log(aModule.getPrivateVar()); //outputs 1
为了更详细地说明这是为什么,一切都与范围有关。 privateVar 存在于匿名函数的范围内。这个匿名函数 returns 一个对象,上面定义了几个函数。当函数被调用时,这个对象被分配给 aModule,但保留对 privateVar 的访问,因为它们共享范围。
但是,在该函数之外,我们处于不同的作用域,该作用域无法访问 aModule 的变量,返回对象中公开的变量除外
我不是很清楚private的概念,如果我仍然可以通过public方法访问它并重新定义模块的属性。我的意思是,我完全可以做到:
var aModule = (function() {
var privateVar = 1;
return {
publicFunction: function() {
return privateVar;
}
}
})();
aModule.publicFunction = function() {
privateVar = function() {
console.log('a new content');
}
privateVar();
};
aModule.publicFunction(); // 'a new content'
我知道如果我用 let 或 const 在 ES6 中写它是不可能的,因为它会给我错误尝试覆盖私有变量的值,但它在 ES5 中有什么意义?
您正在覆盖 public 函数并且无法访问模块私有变量
考虑以下创建为 aModule
的 属性 的新函数,它试图仅更改 var privateVar
作用域因调用位置不同而不同,并且无法访问该私有变量
var aModule = (function() {
var privateVar = 1;
return {
publicFunction: function() {
return privateVar;
}
}
})();
aModule.newFunction = function() {
// try to change privateVar in aModule
privateVar = 3
};
aModule.newFunction();
console.log(aModule.publicFunction()); //still 1 not 3
// here's where it actually ended up
console.log(window.privateVar)
私有变量不能被模块外部的代码或拥有私有变量的 class 访问或更改。
例如,您不能做 aModule.privateVar
并期望它会给您任何回报。
您的 publicFunction
就是 Java(和其他编程语言)世界所说的 "getter"。简单地说,它允许访问私有变量的值,但不允许对其进行写访问。
在你的最后一个例子中,你实际上并没有覆盖私有变量。您只是在 publicFunction
的范围内创建一个新变量并为其赋值。仅仅因为它也被命名为 privateVar
并不意味着它是相同的内存区域。
我已添加到您的代码中以证明这一点
var aModule = (function() {
var privateVar = 1;
return {
publicFunction: function() {
return privateVar;
},
getPrivateVar() {
return privateVar;
}
}
})();
aModule.publicFunction = function() {
privateVar = function() {
console.log('a new content');
}
privateVar();
};
aModule.publicFunction(); // 'a new content'
console.log(aModule.getPrivateVar()); //outputs 1
为了更详细地说明这是为什么,一切都与范围有关。 privateVar 存在于匿名函数的范围内。这个匿名函数 returns 一个对象,上面定义了几个函数。当函数被调用时,这个对象被分配给 aModule,但保留对 privateVar 的访问,因为它们共享范围。
但是,在该函数之外,我们处于不同的作用域,该作用域无法访问 aModule 的变量,返回对象中公开的变量除外