javascript 减少全局变量的方法和好处

以前我基于谷歌地图封装过一个很大型的船舶监控的JS插件。当时由于入行时间不够,加之经验不足,导致js写得不好,全局变量到处都是。到后面居然前面的会覆盖前面的全局变量。今天就来研究下使用太多全局变量导致的问题。

一、全局变量是如何产生的



我们知道全局变量都是挂载在window对象上面的。它的产生方式有很多种,下面就列出来。

1、人为定义的

人为定义很简单,你这样写的代码就定义了一个全局变量person:


1

2

3

<script type="text/javascript">

    var person = ‘刘备‘;

</script>

2、漏写var

很多人以为在函数内部写的变量只是函数内有效。实际上javascript并不是这样。如果在函数内定义变量的时候没写var,那么它依然是全局变量。


1

2

3

4

5

6

7

<script type="text/javascript">

    function sayName() {

        name = ‘刘备‘;

    }

    sayName();

    alert(name);    //弹出刘备

</script>

注意到,调用了一次name之后,就创建了name的全局变量,到处都可以访问。

只有在严格模式下,浏览器才会提示错误:name未定义;

有一个消防法,使用JSLint或JSHint扫描代码能够理清楚这些无意创建的全局变量。

二、全局变量太多会带来哪些问题



当然,少量的全局变量不会造成太大影响。但是如果js代码庞大了之后,到处都是全局变量会造成什么问题呢?

1、命名冲突

全局变量太多时,可能我们无意之中声明的一个全局变量,其实之前已经存在。这是可能就会造成后面的值覆盖掉前面的值。

2、代码脆弱

比如,在函数内部依赖一个全局变量,一旦这个全局变量被删除或被修改,都会影响到这个函数的执行是否正确。


1

2

3

4

5

6

7

8

var name = ‘刘备‘;

function sayName() {

    alert(name)

}

//改为参数传入好于依赖全局对象

function sayName2(name) {

    alert(name);

}

如,对于上面两个函数的写法,依赖参数存入要好于依赖全局变量。

3、难以测试

依赖全局变量之后,整个框架要依赖于全局变量才能运行。所以要想进行局部测试或单元测试就必须要创建好完整的全局环境。

三、减少全局变量的方法



减少全局变量的方法有好多,下面就推荐几种。

1、单全局变量

单全局变量的意思是,只创建一个全局变量。然后其他的全局变量作为属性挂载到这个全局变量上面。

比如:

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

比如,我想需要实现如下逻辑:


1

2

3

4

5

6

7

8

9

10

function Person(id, name)

{

    this.id = id;

    this.name = name;

}

Person.prototype.sayAge = function (age) {

    alert(age);

}

var p1 = new Person(1, ‘刘备‘);

var p2 = new Person(2, ‘关羽‘);

以上代码逻辑创建了1个全局函数,2个全局对象:Person、p1、p2。

实际上,完全可以只创建一个对象就能完成同样的功能。


1

2

3

4

5

6

7

8

9

10

11

var myjs = {};

myjs.Person = function(id, name)

{

    this.id = id;

    this.name = name;

}

myjs.Person.prototype.sayAge = function (age) {

    alert(age);

}

myjs.p1 = new myjs.Person(1, ‘刘备‘);

myjs.p2 = new myjs.Person(2, ‘关羽‘);

以上代码,将所有的全局函数与全局对象都挂载到myjs这个全局对象上了。

实际上,你还可以挂载更多的变量、对象、函数等等。

2、命名空间

基于单全局变量,当变量太多时,只有一级也可能会造成同名覆盖的问题。这时候,我们就命名空间的方式来创建多级别的变量挂载。

命名空间这个概念在javascript中是不存在的,实际上是巧妙利用javascript的代码特性实现的功能划分。

雅虎的YUI就是依照命名空间的思路来管理它的代码。

比如Y.DOM下的所有方法都是与DOM操作相关的,Y.Event下的所有方法都是和事件相关的。

在javascript中,我们可以轻松地使用对象来创建自己的命名空间。

如,假设基于地图封装了一个船舶监控系统:


1

2

3

var myjs = {};

myjs.map = {};  //地图操作相关的

myjs.ship = {}; //船舶操作相关的

对于这种命名空间的方式,要特别注意的是,使用之前,要判断命名空间是否存在。

例如:


1

2

3

MyGlobal.Person.Say.SayHello = function () {

    alert(‘hello‘);

}

使用MyGlobal.Person.Say这个命名空间,当MyGlobal下不存在Person这个对象,就会报错。这个可以为MyGlobal写一个函数,当没有这个命名空间时逐级创建,如果这个命名空间已存在则直接返回。这样就可以省略掉使用命名空间要判断的问题了:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

var MyGlobal = {

    namespace: function (ns) {

        var parts = ns.split(‘.‘);

        var object = this;

        var i;

        var len;

        for(i = 0, len = parts.length; i < len; i++)

        {

            if(!object[parts[i]])

            {

                object[parts[i]] = {};

            }

            object = object[[parts[i]]]

        }

        return object;

    }

}

//不用判断命名空间是否存在的情况下直接使用;

MyGlobal.namespace("Person.Say");  //namespace函数当明明空间存在时会返回,不存在时会创建再返回,

MyGlobal.Person.Say.SayHello = function () {

    alert(‘hello‘);

}

在想使用任意命名空间前,只需要调用一下:MyGlobal.namespace("Person.Say");

3、模块化

这个东西得长篇大论,要独立一篇文章来写。

4、零全局变量(闭包)

使用闭包的场景不多,当我需要一段JS,并且这段JS不需要被其他JS访问,只是为了实现单一的功能而创建的。向轻松学会闭包的可以查看这篇文章《javascript闭包》。

最简单的闭包:


1

2

3

4

(function(win)

{

    //...自己的代码逻辑,有权访问外部。

}(window));

你可以在"自己的代码逻辑",写上你自己的逻辑。这种方式有如下两个要求:

  • 代码不需要被其他代码所依赖;
  • 代码不需要被经常扩展;

即,脚本非常短,且不需要与其他的JS进行交互,才可以使用这种闭包的方式。实际上它真正用上的场景不多的。

出处:javascript 减少全局变量的方法和好处

时间: 2024-10-10 07:22:35

javascript 减少全局变量的方法和好处的相关文章

HTML-HTML链接JavaScript的几种方法

把JavaScript文件放在head中 标准方法是把JavaScript文件放到head标签内. <head> <script type="text/javascript" src="dreamdu.js"></script> </head> 如果浏览器不支持JavaScript,将忽略script标签里面的内容,可以避免使用<!-- ... //-->(内部引用). 当JavaScript有任何HTML

JavaScript 覆盖document.createElement 方法

题:软件项目报价方法 广告:========================================================== 欢迎使用[豆瓣读书] 管理你的阅读,查阅书评,编写读书笔记等. ^^ app下载:http://itunes.apple.com/cn/app/id695492935 ================================================================= 软件项目一般包括解决方案.开发.维护.系统集成等.以下

JavaScript声明全局变量的三种方式

JavaScript声明全局变量的三种方式 JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为全局变量,否则在function声明的是局部变量.该方式即为显式声明详细如下: var test = 5; //全局变量 function a() { var cc=3; //局部变量 alert(test); } function b(){alert(test);} 声明方式二: 没有使用var,直接

JavaScript中的工厂方法、构造函数与class

JavaScript中的工厂方法.构造函数与class 本文转载自:众成翻译 译者:谢于中 链接:http://www.zcfy.cc/article/1129 原文:https://medium.com/javascript-scene/javascript-factory-functions-vs-constructor-functions-vs-classes-2f22ceddf33e#.wby148xu6 在ES6出现之前,人们常常疑惑JavaScript中的工厂模式和构造函数模式到底有

JavaScript document属性和方法

JavaScript document属性和方法 --------------------------------------------属性: 1. Attributes     存储节点的属性列表(只读) 2. childNodes     存储节点的子节点列表(只读) 3 .dataType     返回此节点的数据类型 4. Definition     以DTD或XML模式给出的节点的定义(只读) 5. Doctype     指定文档类型节点(只读) 6 .documentEleme

将JavaScript 插入网页的方法

将JavaScript 插入网页的方法 使用Javascript代码. 插入JavaScript 与在网页中插入CSS的方式相似.使用下面的代码可以在网页中插入JavaScript: ... 其中的...就是代码的内容.JavaScript的插入位置不同,效果也会有所不同,还可以像CSS一样,将JavaScript保存成一个外部文件,这些内容会在下一节讨论. 用JavaScript在网页中输出内容 JavaScript使用document.write来输出内容.例如  document.writ

javascript中的toString()方法

javascript中的toString()方法,主要用于Array.Boolean.Date.Error.Function.Number等对象.下面是这些方法的一些解析和简单应用,做个纪律,以作备忘. (1)Array.toString():将数组转换成一个字符串,并且返回这个字符串.描述:当数组用于字符串环境中时,javascript会调用这一方法将数组自动转换成一个字符串.toString()在把数组转换成字符串时,首先要将数组的每个元素都转换成字符串(通过调用这些元素的toString方

nodejs 全局变量和方法,以及console使用

A.nodejs的console有很多种类型: console.log(1),console.error(2),console.dir(3),console.time(4),console.timeEnd(5),console.trace(6).console.asstert(7). 眼花了吧,哈哈哈,这里经过使用以后我觉得,似乎console.log,可以替代2,3.可能因为语义的缘故吧. a.console.dir()主要用来输出一个object的结构信息. b.console.time('

python2.7 跨文件全局变量的方法

有关python实现跨文件全局变量的方法. 在使用Python编写的应用的过程中,有时会遇到多个文件之间传递同一个全局变量的情况.文件1:globalvar.py #!/usr/bin/env python2.7 class GlobalVar: db_handle = None mq_client = None def set_db_handle(db): GlobalVar.db_handle = db def get_db_handle(): return GlobalVar.db_han