读《编写可维护的JavaScript》第六章总结
第六章 避免使用全局变量
JavaScript执行环境在很多方面都有其独特之处,全局变量就是其中之一。“全局变量”是一个神秘的对象,它表示了脚本的最外层上下文。
在浏览器中,windows对象往往重载并等同于全局对象,因此任何在全局作用域声明的变量和函数都是windows对象的属性。
6.1 全局变量带来的问题
这个就不用照着书详谈了,当我们进入团队合作编写代码时,若大家自定义的变量都是直接挂载在windows对象上(也就是全局变量),很容易发生命名冲突。像这样:
function sayColor() {
alert(color); // 不好的做法: color是从哪来的?
}
so, 尽量避免定义全局变量
如果这样写函数,也是有问题的,这是一个依赖于全局变量的函数。如果环境发生变化,函数很可能就失效了。
如果color被当做参数传入,代码可维护性会变得更佳。
function sayColor(color) {
alert(color);
}
so, 定义函数的时候,最好尽可能多的将数据置于局部作用域内,在函数内定义的任何“东西”都应当采用这种做法,任何来自函数外部的数据都应当以参数的形式传进来。
6.2 意外的全局变量
JS有个特性大家应该都懂: 就是没有使用var声明的变量会被当做全局变量。
这个特性导致了有些人用一个单var语句声明俩个变量,结果在第一个变量后不小心敲了分号而不是逗号从而把第二个变量自动创建成了全局变量。(不过我的IDE都提示了)
function doSomething() {
var count = 10;
title = "Maintainable JavaScript"; // 不好的写法:创建了全局变量
}
so, 这个问题解决的方法有很多,依靠现代的许多智能IDE(如:WebStorm之类的)或者JSLine和JSHint工具也可以检查出来并警告,或者直接将代码采用严格模式。
"use strict";
foo = 10; // 引用错误: foo未被定义
6.3 单全局变量方式
为了解决前面的问题,最佳的办法就是依赖尽可能少的全局变量,即只创建一个全局变量。
单全局变量模式已经在各种流行的JavaScript类库中广泛使用了。
- YUI定义了唯一一个YUI全局对象。
- jQuery定义了俩个全局对象,$和jQuery。只有在$被其他的类库使用了的情况下:为了避免冲突,应当使用jQuery。
- Dojo定义了一个dojo全局对象。
“单全局变量”的意思是所创建的这个唯一全局对象名是独一无二的(不会和内置的API产生冲突),并将你所有的功能代码都挂载到这个全局对象上。
因此每个可能的全局变量都成为你唯一全局变量的属性。从而不会创建多个全局变量。
// 这段代码创建了4个全局对象:Book、Chapter1、Chapter2和Chapter3.
function Book(title) {
this.title = title;
this.page = 1;
}
Book.prototype.turnPage = function(direction) {
this.page += direction;
}
var Chapter1 = new Book("Introduction to Style Guidelines");
var Chapter2 = new Book("Bssic Formatting");
var Chapter3 = new Book("Comments");
单全局变量则只会创建一个全局对象并将这些对象都赋值为它的属性。
var MaintainableJS = {};
MaintainableJS.Book = function(title) {
this.title = title;
this.page = 1;
}
MaintainableJS.Book.prototype.turnPage = function(direction) {
this.page += direction;
}
MaintainableJS.Chapter1 = new MaintainableJS.Book("Introduction ti Style Guidelines");
MaintainableJS.Chapter2 = new MaintainableJS.Book("Basic Formatting");
MaintainableJS.Chapter3 = new MaintainableJS.Book("Comments");
这段代码已有一个全局对象,即 MaintainableJS, 其他任何信息都挂载到这个对象上。因为团队中的每个人都知道这个全局对象,因此很容易做到继续为它添加属性以避免全局污染。
作者还介绍了关于命名空间(namespace)和模块(modules)的概念。
命名空间我这里就不说了。。因为这个概念就是很老的YUI框架运用的概念。现在的框架大多数是模块化的,所以我重点做模块的总结。
6.3.2 模块
模块这一节包含了大量我听过但不没有去弄懂的知识。
首先介绍模块:另外一种基于单全局变量的扩充方法是使用模块,模块是一种通用的功能片段,他并没用创建新的全局变量或命名空间。
相反,所有的这些代码都存放于一个表示执行一个任务或发布一个接口的单函数中。可以用一个名称来表示这个模块,同样这个模块可以依赖其他模块。
因为JavaScript本身不包含正式的模块概念,自然也没有模块语法(期待ECMAScript6), 目前,世界上,有两种比较流行的 JavaScript 模块化体系,
一个是 Node 实现的 CommonJS,另外一个是 AMD。
对于这俩者:了解他们也算是了解前端的历史了。。我在这里只将 看过的大神的解释 抛出,因为这确实不是一篇帖子就能说明的。
首先是了解CMD,它是前端界的名人玉伯在写完SeaJS后的推广过程中对模块定义的规范化产出。(这是一种思想- -SeaJS已经没落了)
接下来是AMD,它是 RequireJS 在推广过程中对模块定义的规范化产出。
他本人在知乎上的回答就概括了俩个规范:点这里
另一个是前端界的名人阮一峰对这俩个规范的解释:点这里
6.4 零全局变量
完全独立的脚本才会用到这种情形(注意:完全无依赖)。
(function() {
"use strict";
var doc = win.document;
// 在这里定义其他的变量
// 其他相关代码
}(Window));
读《编写可维护的JavaScript》第六章总结的更多相关文章
- 读《编写可维护的JavaScript》第一章总结
第一章 基本的格式化 1.4 ① 换行 当一行长度到达了单行最大的字符限制时,就需要手动将一行拆成俩行.通常我们会在运算符后换行,下一行会增加俩个层级的缩进. // 好的做法: 在运算符后换行,第二行 ...
- [已读]编写可维护的javascript
13年4月份出版,作者是大名鼎鼎的Zakas,他的另两本书<javascript高级程序设计>与<高性能javascript>你一定听过或者读过. 这本书重点讲了编码风格和编码 ...
- 【读书笔记】读《编写可维护的JavaScript》 - 编程实践(第二部分)
本书的第二个部分总结了有关编程实践相关的内容,每一个章节都非常不错,捡取了其中5个章节的内容.对大家组织高维护性的代码具有辅导作用. 5个章节如下—— 一.UI层的松耦合 二.避免使用全局变量 三.事 ...
- 拯救一切强迫症 - 读《编写可维护的 JavaScript》(一)
拯救一切强迫症 - 读<编写可维护的 JavaScript>(一) 本文写于 2020 年 4 月 24 日 我在小学的时候就有接触过编程,所以读大一的时候 C 语言还算是轻车熟路.自然会 ...
- 《编写可维护的javascript》读书笔记(上)
最近在读<编写可维护的javascript>这本书,为了加深记忆,简单做个笔记,同时也让没有读过的同学有一个大概的了解. 一.编程风格 程序是写给人读的,所以一个团队的编程风格要保持一致. ...
- 编写可维护的JavaScript 收纳架
如果你看过Nicolas C.Zakas写过的任何作品,你必须承认他是个不折不扣的天才.也只有天才级的才能写出<JavaScript高级程序设计>让所有的前端攻城师人手一本.Nicolas ...
- 推荐一本好书:编写可维护的JavaScript(可下载)
目录 推荐一本好书:编写可维护的JavaScript(可下载) 书摘: 下载: 有些建议: 推荐一本好书:编写可维护的JavaScript(可下载) 书摘: 很多设计模式就是为了解决紧耦合的问题.如果 ...
- 《编写可维护的JavaScript》之编程实践
最近读完<编写可维护的JavaScript>,让我受益匪浅,它指明了编码过程中,需要注意的方方面面,在团队协作中特别有用,可维护性是一个非常大的话题,这本书是一个不错的起点. 本书虽短,却 ...
- 编写可维护的Javascript读书笔记
写在前面:之前硬着头皮参加了java方面的编程规范培训,收货良多,工作半年有余的时候,总算感觉到一丝丝Coding之美,以及造轮子的乐趣,以至于后面开发新功能的时候,在Coding style方面花了 ...
- 《编写可维护的javascript》读书笔记(中)——编程实践
上篇读书笔记系列之:<编写可维护的javascript>读书笔记(上) 上篇说的是编程风格,记录的都是最重要的点,不讲废话,写的比较简洁,而本篇将加入一些实例,因为那样比较容易说明问题. ...
随机推荐
- AngularJS 2.0
https://angular.io/docs/ts/latest/guide/learning-angular.html QuickStart: git clone https://github.c ...
- (转)小心FPGA的JTAG口(上电和下电顺序)
同志们,根据ALTERA官方FAE(现场应用工程师)的强烈建议,请注意不要随意带电插拔你的JTAG下载接口,否则会损坏FPGA芯片的JTAG口信号管脚.现象:在排除了下载线的问题后,还是不能访问FPG ...
- ubuntu14.04下安装python3.4.2
1. python安装包的下载地址:https://www.python.org/downloads/ 我的python安装包下载地址:https://www.python.org/ftp/pytho ...
- LoadRunner连接Genymotion
- oracle 9i相关问题
Oracle 9i在连接数据库的时候需要加上双引号,如sqlplus “sys/oracle@orcl as sysdba” Oracle 9i不支持bigfile大的表空间创建,oracle9i或以 ...
- vue-cli安装失败问题
1.尝试 管理员权限 安装,看是否能解决问题 2.仍未解决问题, 系统变量增加: C:\Program Files\nodejs\node cache\node_modules\vue-cli\bi ...
- Oracle EBS FND User Info API (转) EBS用户账号密码职责相关
. 与用户信息相关API PKG. --和用户处理有关的API FND_USER_PKG; --和用户密码处理有关的API FND_WEB_SEC; --和用户职责处理有关的API FND_USER_ ...
- .NET 泛型分析
.NET 泛型解析 一.问题背景 我们在编程的时候往往因为需要处理不同类型的数据或者对象,重复编写很多类似的代码,造成代码的冗余,代码也显得不那么优雅,泛型的出现,正好是为了解决这个问题,实现继承. ...
- 指令的Link函数和Scope
指令生成出的模板其实没有太多意义,除非它在特定的scope下编译.默认情况下,指令并不会创建新的子scope.更多的,它使用父scope.也就是说,如果指令存在于一个controller下,它就会使用 ...
- (function(){})()是什么意思?
JS里面(function(){})()function外面的括号是什么意思? 定义了一个函数,并马上执行这个函数.这是js中常用的方式.好处呢.参考:js 闭包