【读书笔记】:《编写可维护的JavaScript》第06章 避免使用全局变量(未完)

第06章 避免使用全局变量(未完)

“全局对象”是一个神秘的对象,它表示了脚本的最外层上下文。
在浏览器中,window对象往往重载并等同于全局变量,因此任何在全局作用域中声明的变量和函数都是window对象的属性,比如:

var color = "red";
function sayColor() {
    console.log(color);
}

console.log(window.color); // "red"
console.log(typeof window.sayColor); // "function"

这段代码定义了全局变量color和全局函数sayColor(),两者都是window对象的属性,尽管我们并没有显式的执行给window对象挂载属性的操作。

6.1 全局变量带来的问题

一般来讲,创建全局变量被认为是最为糟糕的实践,尤其是在团队开发的大背景下。全局变量越多,引入错误的概率将会变得越来越高。

6.1.1 命名冲突

当脚本中的全局变量和全局函数越来越多时,发生命名冲突的概率也会随之增高。

6.1.2 代码的脆弱性

一个依赖于全局变量得到函数是深耦合于上下文环境中的。如果环境发生改变,函数很可能就失效了。
定义 函数时,最好尽可能多地将数据置于局部作用域内,在函数内定义的任何“东西”都应当采用这种写法。任何来自函数外部的数据都应当以参数的形式传进来。这样做可以将函数和其外部环境隔离开来,并且你的修改不会对程序其他部分造成影响。

6.1.3 难以测试

确保你的函数不会对全局变量有依赖,这将增强你的代码的可测试性。当然,你的函数可能会依赖原生的(native)JavaScript全局变量,比如Date、Array等。它们是全局环境的一部分,是和JavaScript引擎相关的,你的函数总是会用到这些全局对象。总之,为了保证你的代码具有最佳的可测试性,不要让函数对全局变量有依赖。

6.2 意外的全局变量

JavaScript陷阱之一:不小心创建全局变量。当你给一个未被 var 语句声明过的变量赋值时,JavaScript会自动创建一个全局变量:

function doSomething(){
    var count = 10; // 错误的写成分号
        title = "this is a bad idea"; // 不好的写法,创建了全局变量
}

doSomething();

console.log(title); // 能够输出 因为 这里的 title 是一个全局变量
console.log(count); // 报错

最好的规则就是总是使用 var 来定义变量,哪怕是定义全局变量。这样做能大大降低某些场景里省略 var 所导致错误的可能性。

避免意外的全局变量
当你不小心创建了全局变量时,JavaScript并不会报任何错误。这时就需要诸如JSLint和JSHint 的工具了。如果你给一个未声明的变量赋值,这两个工具都会报警告。

6.3 单全局变量方式

依赖尽可能少的全局变量,即只创建一个全局变量。
单全局变量模式已经在各种流行的JavaScript类库中广泛使用。

  • YUI定义了唯一一个YUI全局对象。
  • jQuery定义了两个全局对象,$和jQuery。
  • Dojo定义了一个dojo全局对象。

“单全局变量”的意思是所创建的这个唯一全局对象名士独一无二的(不会和内置API产生冲突),并将你所有的功能代码都挂载到这个全局对象上。比如,假设我想让一个对象表示本书的一章,代码看起来会像下面这样:

function Book(title) {
    "use strict";
    this.title = title;
    this.page = 1;
}

Book.prototype.trunPage = function (direction) {
    "use strict";
    this.page += direction;
};

var Chapter1 = new Book("第一章");
var Chapter2 = new Book("第二章");
var Chapter3 = new Book("第三章");

这段代码创建了4个全局对象:Book,Chapter1,Chapter2,Chapter3。单全局变量则只会创建一个全局对象,并将这些对象都赋值为它的属性。

var MaintinableJS = {};
MaintinableJS.Book = function (title) {
    "use strict";
    this.title = title;
    this.page = 1;
};

MaintinableJS.Book.prototype.trunPage = function (direction) {
    "use strict";
    this.page += direction;
};

MaintinableJS.Chapter1 = new MaintinableJS.Book("第一章");
MaintinableJS.Chapter2 = new MaintinableJS.Book("第二章");
MaintinableJS.Chapter3 = new MaintinableJS.Book("第三章");

这段代码只有一个全局变量,即MaintinableJS,其他任何信息都挂载到这个对象上。因为团队的每个人都知道这个全局对象,因此很容易做到继续为它添加属性以避免全局污染。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值