[Effective JavaScript 笔记] 第8条:尽量少用全局对象
初学者容易使用全局变量的原因
- 创建全局变量毫不费力,不需要任何形式的声明(只要在非函数里用var 你就可以得到一个全局变量)
- 写得代码简单,不涉及到大的项目或配合(写hello world是不会有什么问题的)
使用全局变量的不利之处
- 污染共享的公共命名空间
- 导致意外的命名冲突(比如你的代码别人引用了,别人代码里有相同的全局变量的引用)
- 全局变量不利于模块化,导致程序中独立组件间的不必要的耦合
优秀程序员的作法
- 不断地留意程序的结构
- 持续地归类相关的功能以及分离不相关的组件
- 将1,2行为作为编程过程中的一部分
使用全局变量的原因
全局命名空间是js程序中独立的组件进行交互的唯一途径。利用全局命名空间的情况是不可以避免的。
组件或程序库不得不定义一些全局变量,以便程序中的其他部分使用。否则,最好尽量使用局部变量。
即使在很简单的函数中将临时变量定义为全局的,我们都会担心是否有任何其他的代码可能会使用相同的变量名。
下面小例子一个:
var i,n,sum;
function averageScore(players){
sum = 0;
for(i=0,n=players.length;i<n;i++){
sum+=score(plaerys[i]);
}
return sum/n;
}
如果score函数出于自身的目的使用了任何同名的全局变量,averageScore函数的定义将出现问题。
var i,n,sum;
function score(palyer){
sum=0;
for(i=0,n=player.levels.length;i<n;i++){
sum+=palyer.levels[i].score;
}
return sum;
}
保持变量为局部变量仅将其作为需要使用它们的代码的一部分。
function averageScore(players){
var i,n,sum;
sum = 0;
for(i=0,n=players.length;i<n;i++){
sum+=score(plaerys[i]);
}
return sum/n;
}
function score(palyer){
var i,n,sum;
sum=0;
for(i=0,n=player.levels.length;i<n;i++){
sum+=palyer.levels[i].score;
}
return sum;
}
全局对象 window
js的全局命名空间也被暴露为在程序全局作用域中可以访问的全局对象,该对象作为this关键字的初始值。在web浏览器中,全局对象被绑定到全局的window变量。添加或修改全局变量会自动更新全局对象。
this.foo;//undefined
foo=”global foo”;
this.foo;//”global foo”
类似地,更新全局对象也会自动地更新全局命名空间。
var foo=”global foo”;
this.foo=”changed”;
foo;//”changed”
这意味着你创建一个全局变量有两种方法可供挑选。
- 可以在全局作用域中使用var声明变量
- 将其加入到全局对象中。
var 声明的好处是更能清楚地表达全局变量在程序范围中的影响。
鉴于引用未绑定的变量会导致运行错误,因此,保持作用域清晰和简洁会使代码的使用者更容易理解程序声明了哪些全局变量。
虽然最好限制使用全局对象,但是它确实提供了一个不可或缺的特殊用途。由于全局对象提供了全局环境的动态反应机制,所以可以使用它来查询一个运行环境,检测在这个平台下哪些特性是可的。
例如:ES5中引入了全局的JSON对象来读写JSON格式的数据。将代码部署到一个不确定是否提供了JSON对象的环境的一个权宜之计是,你可以测试这个全局对象是否存在并提供一个替代实现。
if(!this.JSON){
this.JSON={
parse:….,
stringify:…
}
}
首选宿主环境实现
直接使用自己的实现,也是可以的。但由宿主环境提供的内置实现几乎总是更合适的。因为它们按照一定的标准对正确性和一致性进行了严格检查,并且普遍来说比第三方实现提供了更好的性能。
平台特性检测
- 使各种各样的浏览器和浏览器版本中可能会执行同样的代码。
- 使得程序在平台特性集合的变化中依旧健壮的相对简单的方法。
- 也适用于其他地方。例如,此技术使得在浏览器和js服务器环境中共享程序库成为可能。
提示
- 避免使用全局变量
- 尽量声明局部变量
- 避免对全局对象添加属性
- 使用全局对象来做平台特性检测
[Effective JavaScript 笔记] 第8条:尽量少用全局对象的更多相关文章
- [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法
js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...
- [Effective JavaScript 笔记]第51条:在类数组对象上复用通用的数组方法
前面有几条都讲过关于Array.prototype的标准方法.这些标准方法被设计成其他对象可复用的方法,即使这些对象并没有继承Array. arguments对象 在22条中提到的函数argument ...
- [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象
js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...
- [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符
“1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...
- [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码
函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...
- [Effective JavaScript 笔记]第18条:理解函数调用、方法调用及构造函数调用之间的不同
面向对象编程中,函数.方法.类的构造函数是三种不同的概念. JS中,它们只是单个构造对象的三种不同的使用模式. 三种不同的使用模式 函数调用 function hello(username){ ret ...
- [Effective JavaScript 笔记]第45条:使用hasOwnProperty方法以避免原型污染
之前的43条,44条讨论了属性的枚举,但都没有彻底地解决属性查找中原型污染的问题.看下面关于字典的一些操作 'zhangsan' in dict; dict.zhangsan; dict.zhangs ...
- [Effective JavaScript 笔记]第68条:使用promise模式清洁异步逻辑
构建异步API的一种流行的替代方式是使用promise(有时也被称为deferred或future)模式.已经在本章讨论过的异步API使用回调函数作为参数. downloadAsync('file.t ...
- [Effective JavaScript 笔记] 第2条:理解JavaScript的浮点数
JavaScript数值型类型只有数字 js只有一种数值型数据类型,不管是整数还是浮点数,js都把归为数字. typeof 17; // “number” typeof 98.6; // “num ...
随机推荐
- java并发:获取线程执行结果(Callable、Future、FutureTask)
初识Callable and Future 在编码时,我们可以通过继承Thread或是实现Runnable接口来创建线程,但是这两种方式都存在一个缺陷:在执行完任务之后无法获取执行结果.如果需要获取执 ...
- php模式设计之 适配器模式
在这个有没有对象都要高呼“面向对象”的年代,掌握面向对象会给我们带来意想不到的方便.学编程的小伙伴从开始能写几行代码实现简单功能到后来懂得将一些重复的操作组合起来形成一个“函数”,再到后来将“函数”和 ...
- MVVM开源框架Knot.js 教程2 - 大幅改变前端框架开发体验的Debugger
Knotjs教程系列 1.CBS初步 2.Knot.js Debugger(本文) ....持续增加中 Knot.js 教程2 - 改变前端框架开发体验的Debugger Debugger只是一个方便 ...
- 一起用HTML5 canvas做一个简单又骚气的粒子引擎
前言 好吧,说是"粒子引擎"还是大言不惭而标题党了,离真正的粒子引擎还有点远.废话少说,先看demo 本文将教会你做一个简单的canvas粒子制造器(下称引擎). 世界观 这个简单 ...
- [Aaronyang] 写给自己的WPF4.5 笔记[3MenuItem中的icon]
敢于尝试,就等于你已经向成功迈出了第一步 --Aaronyang的博客(www.ayjs.net)-www.8mi.me =============时隔两年后再看WPF========== 因为以前的 ...
- [Json.net]Linq to Json
引言 上篇学习了json.net的基本知识,这篇学习linq to json. 上篇文章:[Json.net]快速入门 Linq to Json Linq to Json是用来快速操作json对象的, ...
- (转)在WAMPSERVER下增加多版本的PHP(PHP5.3,PHP5.4,PHP5.5)支持
原文:http://www.cnblogs.com/lyongde/p/3745030.html 此文在原文的基础上改进了几个步骤,因为经本人实践,原文无法正确配置. WAMPServer可以让开发者 ...
- html5_canvas-记忆力卡片游戏
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 【bzoj2463】 谁能赢呢?
www.lydsy.com/JudgeOnline/problem.php?id=2463 (题目链接) 题意 一个n*n的棋盘,开始时左上角有一个棋子,每次可以把棋子向4个方向移动,但不能移动到曾经 ...
- Bzoj3943 [Usaco2015 Feb]SuperBull
3943: [Usaco2015 Feb]SuperBull Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 300 Solved: 185 Desc ...