JS全局变量

2019-10-27  本文已影响0人  贪恋冬天的幸福

JavaScript的两个特性会出人意料地创建全局变量:

  1. 变量即使未声明也可直接使用
  2. 未经声明的变量,默认为全局对象所有(暗示全局变量 implied globals)

这样一来,之后出现的全局变量,就会污染已出现的同名全局变量,导致不可预料的结果。

未经声明的变量,默认为全局对象所有:

var result = 'this is result in global';
console.log(this.result); //this is result in global
function sum(x, y) {
  result = x + y;
  return result;
}
console.log('sum = ' + sum(1, 3)); //4
console.log(this.result); //4   ** 此处改变了全局变量resule的值 **

使用 var 声明变量:

var result = 'this is result in global';
console.log(this.result); //this is result in global
function sum(x, y) {
  var result = x + y;
  return result;
}
console.log('sum = ' + sum(1, 3)); //4
console.log(this.result); //this is result in global   ** 此处没有改变全局变量resule的值 **

创建隐式全局变量的反模式是带有 var/let 声明的链式赋值。在链式赋值中,只有距离声明变量 var/let 最近的变量是局部变量,其余均为全局变量,例如:

var b = 3;
function add2(x){
  var a = b = 2; //   ** a为局部变量,b为全局变量 **
  return x + a;
}
console.log(this.b); //2   ** 此处改变了全局变量b的值 **
var b = 3;
function add2(x){
  let a = b = 2; //   ** a为局部变量,b为全局变量 **
  return x + a;
}
console.log(this.b); //2   ** 此处改变了全局变量b的值 **

显然链式声明并没有得到预期的结果,这是因为从右至左的操作符优先级。首先,优先级比较高的是表达式b=0,此时b未经声明。表达式的返回值是0,它被赋给var声明的局部变量a,如以下代码所示:

var a = (b = 0);

如果对链式赋值的所有变量都进行了声明,就不会创建出不期望的全局变量。

var b = 3;
function add2(x){
 // ** a 、b 均为局部变量**
  var a, b;
  a = b = 2;
  return x + a;
}
console.log(this.b); //3   ** 此处没有改变全局变量b的值 **
var b = 3;
function add2(x){
  // ** a 、b 均为局部变量**
  let a, b;
  a = b = 2;
  return x + a;
}
console.log(this.b); //3   ** 此处没有改变全局变量b的值 **

所以,尽可能少地使用全局变量,是保证程序执行可预见性的必要手段。

参考资料:《JavaScript 模式》 Stoyan Stefanov 著 陈新 译

上一篇 下一篇

猜你喜欢

热点阅读