学习Javascript并对全局变量提出疑问。从我的阅读中,大多数人建议不要使用它们。但是,在基于类的javascripting中,这个不成文的规则是否仍适用?例如:
var width = 0;
var height = 0;
<!-- constructor -->
function Rectangle(){}
<!-- getters/setters -->
Rectangle.prototype.getWidth = function(){
return width;
}
Rectangle.prototype.setWidth = function(w){
width = w;
}
Rectangle.prototype.getHeight = function(){
return height;
}
Rectangle.prototype.setHeight = function(h){
height = h;
}
<!-- methods -->
Rectangle.prototype.area = function(){
return height * width;
}
var myRect = new Rectangle();
myRect.setWidth(5);
myRect.setHeight(4);
console.log(myRect.area()); //20
console.log(myRect.getWidth()); //5
myRect.setWidth(10);
console.log(myRect.getWidth()); //10
console.log(myRect.area()); //40
我熟悉Java以及为类,属性和方法使用访问修饰符的能力。是因为Javascript中不存在访问修饰符,应避免使用全局变量吗?
答案 0 :(得分:2)
不惜一切代价避免全局变量的简单原因是,您永远无法确定哪些其他脚本同时被加载。因此,为了避免可能在真正丑陋的错误场景中出现的冲突,您至少应该将自己的代码包装到一个closured
函数上下文中。
(function() {
// all of your code here
}());
这种简单的模式完全避免了任何冲突。
答案 1 :(得分:2)
为了使您的行为符合预期,您需要创建实例属性,而不是使用全局变量width
和height
。您当前的方法将导致使用相同变量的多个Rectangle
实例。
尝试:
function Rectangle () {
this.width = 0;
this.height = 0;
}
Rectangle.prototype.setWidth = function(w) {
this.width = w;
};
等...
正如其他人所指出的那样,全局变量width
和height
将由当前作用域中的所有其他代码共享(注意:JavaScript只有函数级作用域,而不是块级)。
答案 2 :(得分:2)
您可能会使用此代码
<!-- constructor -->
var Rectangle = function(w, h) {
this.width = w || 0;
this.height = h || 0;
}
<!-- getters/setters -->
Rectangle.prototype.getWidth = function( ) { return this.width; }
Rectangle.prototype.setWidth = function(w) { this.width = w; }
Rectangle.prototype.getHeight = function() { return this.height; }
Rectangle.prototype.setHeight = function(h) { this.height = h; }
<!-- methods -->
Rectangle.prototype.area = function(){
return this.height * this.width;
}
var myRect = new Rectangle(5, 4);
console.log(myRect.area()); //20
console.log(myRect.getWidth()); //5
myRect.setWidth(10);
this.width
和this.height
,否则您将修改全局宽度和高度变量,并且这些值不会绑定到Rectangle的单个实例。var Rectangle = function(w, h) { ... }
而不是function Rectangle() { ... }
。答案 3 :(得分:1)
这条不成文的规则是否仍适用?
是的,您应该始终避免全局变量。我不知道为什么width
和height
在您的代码中在Rectangle
之外声明。您需要大量使用this
:
function Rectangle(h, w) {
this.height = h || 0;
this.width = w || 0;
}
<!-- getters/setters -->
Rectangle.prototype.getWidth = function(){
return this.width;
}
Rectangle.prototype.setWidth = function(w){
this.width = w;
}
Rectangle.prototype.getHeight = function(){
return this.height;
}
Rectangle.prototype.setHeight = function(h){
this.height = h;
}
<!-- methods -->
Rectangle.prototype.area = function(){
return this.height * this.width;
}
是因为Javascript中不存在访问修饰符,应避免使用全局变量吗?
没有。无论编程语言如何,都应该避免全局始终。
答案 4 :(得分:0)
应该避免全球化。你应该将东西包装在封闭中。
只有在想要公开功能时才使用全局变量。
答案 5 :(得分:0)
是的,它仍然是真的。你应该始终避免使用全局变量。
在您的示例width
中,height
是全局的。如果这是完整的代码,那就不是问题了。但是,如果你后来决定引入另一个名为GameField
的“类”,那该怎么办?它自然也有宽度和高度。我在这里闻到了麻烦。
答案 6 :(得分:0)
通常在OOP Javascript中,您可以使用类定义创建一个闭包,以避免污染全局范围。
var Rectangle;
(function() {
var width = 0;
var height = 0;
Rectangle = function (){}
...
})(); // the () execute the function with the closure
通过这种方式,您可以定义私有属性并且仍然具有干净的全局空间:)
另外,为了防止注释中描述的问题MДΓΓБДLL仍然保留私有属性和getter / setter,这是要走的路
function Rectangle() {
// Private properties
var width = 0,
height = 0;
// Public methods using private properties
this.setWidth = function(value) {
width = value;
}
this.setHeight = function(value) {
height = value;
}
}
除非您真正关心width
和height
vars的完整性,否则使用其他答案中所述的公共属性要容易得多。
答案 7 :(得分:0)
它更像是一般编码标准。全局变量是邪恶的,直言不讳。
所以,假设你有以下代码。
var width = 10;
<!-- constructor -->
function Rectangle(){}
<!-- getters/setters -->
Rectangle.prototype.getWidth = function(){
return width;
}
Rectangle.prototype.setWidth = function(w){
width = w;
}
var myRect = new Rectangle();
console.log(myRect.getWidth());
那将完全按照您的预期行事,将10输出到控制台。
但是,现在,让我们说开发人员稍后会出现,并在构建myRect和console.log之间添加一条新行,如:
width=width * 10;
现在,console.log将返回100.嗯,你说,这不是那么糟糕。我还是可以读这个。
但是让我们修改最后两行:
var myRect = new Rectangle();
doSomethingCool();
console.log(myRect.getWidth());
function doSomethingCool() {
LOTS o code;
width = "10px"; // I need this to update the style sheet.
LOTS o code;
}
突然间,弄清楚实际发生的事情要困难得多。
当然console.log会输出10px,但为什么会这样呢?