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

  • 创建全局变量毫不费力,不需要任何形式的声明(只要在非函数里用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. 运用Java对微信公众平台二次开发技术——开发者模式接入

    当初我在这碰到了很多问题,市面上以及网络上的资料特别少,所以当初碰了很多壁,所以现在跟大家分享一下,如何用Java,对微信公众平台进行二次开发. 一.开发预备知识: 最基本的JavaSE与JavaWe ...

  2. 程序员"青春饭"问题之我见

      程序员"青春饭"问题之我见 声明:转载请注明出处.http://www.cnblogs.com/hzg1981/ 1. 问题描述 问题1: 什么是程序员? 在本文中程序员的定义 ...

  3. 第六章 prototype和constructor

    首先我们看下面一段代码(第六章 01.htm) function myfun() //定义一个函数myfun { }; console.log(typeof (myfun.prototype)); c ...

  4. shell中的流程控制

    一.if的使用 判断磁盘使用率,如果超过要求值就直接报警 数据库备份 apache服务器启动检测(nmap工具需要安装) 多重条件判断 二.case的使用 三.for使用 字符串循环,in后面的内容以 ...

  5. 第三十四课:jQuery Deferred详解2

    上一课主要分析了jQuery1.51版本的jQuery Deferred.在jQuery1.6中,jQuery Deferred添加了两个方法,always,pipe. always用来添加回调,无论 ...

  6. 【团队项目演示】FZU5BOYS之团队项目链接汇总

    FZU5BOYS      项目冲刺之博客汇总 Alpha版本 Day One Day Two Day Three Day Four Day Five Day Six Day Seven Day Ei ...

  7. iOS边练边学--Http网络再学习,简单介绍

    一.URL 什么是URL URL中常见的协议 二.Http Http的基本通信过程 发送Http请求的方法 GET 和 POST 对比 GET 和 POST 的选择 三.iOS中的Http学习 iOS ...

  8. IntellJ IDEA 所有快捷键

    登录下面网站. http://www.jetbrains.com/idea/documentation/ 下载Keymap for Windows/Linux 后面的PDF文档.

  9. offsetLeft, offsetTop以及postion().left , postion().top有神马区别

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. 关于MyEclipse对Struts2配置文件较检异常 Invalid result location value/parameter

    有时候Struts.xml配置没有错误,完全可以顺利运行,而MyEclipse9以上版本却经常出现一大坨错误标识,错误信息是 Invalid result location value/paramet ...