初学者容易使用全局变量的原因

  • 创建全局变量毫不费力,不需要任何形式的声明(只要在非函数里用var 你就可以得到一个全局变量)
  • 写得代码简单,不涉及到大的项目或配合(写hello world是不会有什么问题的)

使用全局变量的不利之处

  • 污染共享的公共命名空间
  • 导致意外的命名冲突(比如你的代码别人引用了,别人代码里有相同的全局变量的引用)
  • 全局变量不利于模块化,导致程序中独立组件间的不必要的耦合

优秀程序员的作法

  1. 不断地留意程序的结构
  2. 持续地归类相关的功能以及分离不相关的组件
  3. 将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”

这意味着你创建一个全局变量有两种方法可供挑选

  1. 可以在全局作用域中使用var声明变量
  2. 将其加入到全局对象中。

var 声明的好处是更能清楚地表达全局变量在程序范围中的影响。

鉴于引用未绑定的变量会导致运行错误,因此,保持作用域清晰和简洁会使代码的使用者更容易理解程序声明了哪些全局变量。

虽然最好限制使用全局对象,但是它确实提供了一个不可或缺的特殊用途。由于全局对象提供了全局环境的动态反应机制,所以可以使用它来查询一个运行环境,检测在这个平台下哪些特性是可的。

例如:ES5中引入了全局的JSON对象来读写JSON格式的数据。将代码部署到一个不确定是否提供了JSON对象的环境的一个权宜之计是,你可以测试这个全局对象是否存在并提供一个替代实现。

if(!this.JSON){

this.JSON={

parse:….,

stringify:…

}

}

首选宿主环境实现

直接使用自己的实现,也是可以的。但由宿主环境提供的内置实现几乎总是更合适的。因为它们按照一定的标准对正确性和一致性进行了严格检查,并且普遍来说比第三方实现提供了更好的性能。

平台特性检测

  • 使各种各样的浏览器和浏览器版本中可能会执行同样的代码
  • 使得程序在平台特性集合的变化中依旧健壮的相对简单的方法。
  • 也适用于其他地方。例如,此技术使得在浏览器和js服务器环境中共享程序库成为可能。

提示

  • 避免使用全局变量
  • 尽量声明局部变量
  • 避免对全局对象添加属性
  • 使用全局对象来做平台特性检测

[Effective JavaScript 笔记] 第8条:尽量少用全局对象的更多相关文章

  1. [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法

    js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...

  2. [Effective JavaScript 笔记]第51条:在类数组对象上复用通用的数组方法

    前面有几条都讲过关于Array.prototype的标准方法.这些标准方法被设计成其他对象可复用的方法,即使这些对象并没有继承Array. arguments对象 在22条中提到的函数argument ...

  3. [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

  4. [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符

    “1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...

  5. [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码

    函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...

  6. [Effective JavaScript 笔记]第18条:理解函数调用、方法调用及构造函数调用之间的不同

    面向对象编程中,函数.方法.类的构造函数是三种不同的概念. JS中,它们只是单个构造对象的三种不同的使用模式. 三种不同的使用模式 函数调用 function hello(username){ ret ...

  7. [Effective JavaScript 笔记]第45条:使用hasOwnProperty方法以避免原型污染

    之前的43条,44条讨论了属性的枚举,但都没有彻底地解决属性查找中原型污染的问题.看下面关于字典的一些操作 'zhangsan' in dict; dict.zhangsan; dict.zhangs ...

  8. [Effective JavaScript 笔记]第68条:使用promise模式清洁异步逻辑

    构建异步API的一种流行的替代方式是使用promise(有时也被称为deferred或future)模式.已经在本章讨论过的异步API使用回调函数作为参数. downloadAsync('file.t ...

  9. [Effective JavaScript 笔记] 第2条:理解JavaScript的浮点数

    JavaScript数值型类型只有数字 js只有一种数值型数据类型,不管是整数还是浮点数,js都把归为数字. typeof 17;   // “number” typeof 98.6; // “num ...

随机推荐

  1. unity3d 依赖关系获取预制件任意资源

    前段时间策划们想知道UI预制件中使用了哪些音效 N多预制件.N多音效!! 如果纯人工整理的话这还不累成狗? 累成狗不说,还容易出错 所以获取音频剪辑小工具就诞生了,将策划从死亡边缘拉了回来 我们先看一 ...

  2. 用Wireshark抓包分析超过70秒的请求

    超过70秒的请求是通过分析IIS日志发现的: 10.159.63.104是SLB的内网IP. 通过Wireshark抓包分析请求是9:22:21收到的(tcp.stream eq 23080): 09 ...

  3. Mustache.js前端模板引擎源码解读

    mustache是一个很轻的前端模板引擎,因为之前接手的项目用了这个模板引擎,自己就也继续用了一会觉得还不错,最近项目相对没那么忙,于是就抽了点时间看了一下这个的源码.源码很少,也就只有六百多行,所以 ...

  4. RockWare RockWorks的Ollydbg调试过程及注册机(破解)思路

    最近拿到了RockWorks15的安装包,可惜没有破解,试用也只能用14天.用PEiD工具察看了一下,Delphi编写的程序,竟然没加壳.本想用OllyDBG调试进去爆破一下,不意发现注册码很简单,如 ...

  5. [AaronYang]C#人爱学不学[6]

    不要回头,不要将就,做到这两点,人生就会简单很多幸福很多 --Aaronyang的博客(www.ayjs.net)-www.8mi.me 1. 运算符,还有哪些你能学到? 1.1 不安全运算符: si ...

  6. jQuery基础之(五)jQuery自定义添加"$"与解决"$"的冲突

    1.自定义添加$ 从上面四篇文章我们看到jQuery的强大,但无论如何,jQuery都不可能满足所有用户的需求,而且有一些需求十分小众,也不适合放到整个jQuery框架中,正是因为这一点,jQuery ...

  7. jQuery应用之(一)使用jQuery选择器(荐)

    如上文(地址)jQuery预先的javascript的编程,提供了计划所有css3下的标准选择器,开发者可以利用这些选择器轻松选择各种元素,供javascript使用. 重要的是jQuery对这些选择 ...

  8. github的初次体验及管理代码的心得

    周六早上的课上,助教给我们演示了一遍如何上传和下载代码库,新建代码库等等,但是是在linux上的,而我的笔记本的操作系统是win7的.而在教室中的尝试因为网络原因,虽然可以上github的网站,但是下 ...

  9. 在Myeclipse buildpath 加server lib (server runtime)/项目导入时报错:The import javax.servlet.http.HttpServletRequest cannot be resolved

    来源于:http://blog.csdn.net/dingqinghu/article/details/8805922 http://yl-fighting.iteye.com/blog/140946 ...

  10. [转]Oracle中的索引详解

    原文地址:http://www.oschina.net/question/30362_4057 一. ROWID的概念 存储了row在数据文件中的具体位置:64位 编码的数据,A-Z, a-z, 0- ...