JavaScript中对象写法

转载 2016年08月29日 12:15:23
随着网站逐渐变成“互联网应用程序”,嵌入网页的JavaScript代码越来越庞大,越来越复杂。
网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测试等等... ...开发者不得不使用软件工程的方法,管理网页的业务逻辑。
JavaScript模块化编程,已经成为一个迫切的需求。理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块。
但是JavaScript不是一种模块化语言,它不支持“类”,更不要说是“模块”了。

1、原始写法

  <script type="text/javascript">
        function m1() { }
        function m2() { }
    </script >
上面的m1()和m2()组成一个模块,使用的时候直接调用就好了。
但是,这种做大的缺点很明显:“污染”了全局变量,无法保证不与其他的模块变量名发生冲突,而且模块成员之间看不吃直接关系。

2、对象写法:

  var module = new Object({
            _count: 10,
            m1: function () {
                alert( "我是方法m1" );
            },
            m2: function () {
                alert( "我是方法m2" );
            }
        });

函数m1() 和 m2()都封装在module对象里,使用的时候直接调用这个对象的属性。

缺点:这样的写法会暴露所有的模块成员,内部状态可以被外部改写。比如,外部代码可以直接改变内部计数器的值。

module._count = 1000; //改变计数器的值


3、立即执行函数

(immediately-invoked function expression,IIFE)可以达到不暴露私有成员的目的。

  <script type="text/javascript">
        var module1 = (function () {
            var _count = 0;
            var m1 = function () {
                //
            };
            var m2 = function () {
                //
            };
            return {
                m1: m1,
                m2: m2
            };
        })();
    </script >
使用上面的写法,外部代码无法直接读取内部的 _count 变量。

4、放大模式 

  <script type="text/javascript">
        var module1 = (function () {
            var count = 0;
            var m1 = function () {
                //
            };
            var m2 = function () {
                //
            };
            return {
                m1: m1,
                m2: m2
            };
        })();

        var module1 = (function (mod) {
            mod.m3 = function () {
                //
            };
            return mod;
        })(module1);
    </script >
上面这段代码为module1添加了一个新的方法m3(),然后返回新的module模块。

5、宽放大模式:(loose augmentation)

在浏览器环境中,模块的各个部分通常都是在网络上获取的,有时候无法知道哪个部分会先加载,如果采用上一节的写法,第一个执行的部分有可能加载一个不存在的空对象,这时候要采用“宽放大模式”。

  <script type="text/javascript">
        var module1 = (function () {
            var count = 0;
            var m1 = function () {
                //
            };
            var m2 = function () {
                //
            };
            return {
                m1: m1,
                m2: m2
            };
        })();

        var module1 = (function (mod) {
            mod.m3 = function () {
                //
            };
            return mod;
        })(window.module1 || {});
    </script >
与“放大模式”相比,“宽放大模式”就是“立即执行函数”的参数可以是空对象

6、输入全局变量

独立性是模块的重要特点,模块内部最好不与程序的其他部分直接交互。
为了在模块内部调用全局变量,必须显式地将其他变量输入模块。

var module1 = (function ($, YAHOO) {
            //
        })(jQuery, YAHOO);
上面的module1模块需要使用jQuery和YUI库,就把这两个库(其实就是两个模块)当做参数输入module1。这样做除了保证模块的独立性,还使得模块之间的依赖关系变得明显。

7、模块的规范

为什么模块很重要?
因为有了模块,我们就可以方便的使用别人的代码,想要什么功能,就加载什么模块。
但是这样做需要有一个前提,那就是大家都必须以同样的方式编写模块,否则你有你的写法,我有我的写法,岂不乱套了!考虑到JavaScript模块现在还没有官方规范,这一点更为重要。
目前通行的JavaScript模块有两种,CommonJS和AMD。

8、CommonJS

2009年,美国程序员Ryan Dahl创造了node.js项目,将javascript语言用于服务器端编程。
这标志“JavaScript模块化编程”正式诞生,在浏览器环境下,没有模块也不是特别大的问题,毕竟网页程序的复杂度有限;但是在服务器端,一定要有模块,与操作系统和其他用应用程序互动,否则根本没办法编程。

node.js的模块系统,就是参照CommonJS规范实现的。在CommonJS中,有一个全局性的方法require(),用于加载模块。假设有一个数学模块math.js,可以像下面这样加载。

var math = require(‘math’); //加载模块
math.add(2,3); //5 调用模块内方法
需要知道require()方法用于加载模块的作用。

9、浏览器环境

有了服务器模块后,很自然的,大家就想要客户端模块。而且最好两者能够兼容,一个模块不用修改,在服务器和浏览器都可以运行。
但是,由于一个重大的局限,使得CommonJS规范不使用于浏览器。
问题来了,还是这段代码:

var math = require(‘math’); //加载模块
math.add(2,3); //5 调用模块内方法
运行到第二行的时候,必须等待math.js加载完成。也就是说,如果加载时间很长,整个应用就会停在那里。也就是说,如果加载时间很久,整个应用就会停在那里等待。
这对服务器端不是问题,因为所有的模块都存在本地硬盘,可以同步加载完成,等待时间就是硬盘读取的时间。但是,对于浏览器这却是个大问题,因为模块都在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于“假死”状态。

因此,浏览器端的模块,不能采用“同步加载”(synchronize),只能采用“异步加载”(asynchronous)。这就是AMD规范诞生的背景。

10、AMD

AMD是“asynchronous Module Definition”的缩写,意思是“异步模块定义”。它采用异步方式加载模式,模块的加载不影响他后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成后,这个回调函数才会运行。

AMD也采用require()语句加载模块,但是不同于CommonJS,他要求两个参数:
require([module],callback);
第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。如果将前面的代码改成AMD形式,就是下面这样:

require(['math'],function(math){
math.add(2,3);
});

math.add()与math模块加载不上同步的,浏览器不会发生假死。所以很显然,AMD比较适合浏览器环境。
目前,主要有两个JavaScript库实现了AMD规范:require.js和curl.js。


javaScript封装的各种写法

javaScript封装的各种写法       在javascript的世界里,写法是个神奇的现象,真是百家齐开放啊!每次看到老外写的js组件,思想和写法都怪异,就没看到一个js...
  • AlbenXie
  • AlbenXie
  • 2017年04月17日 10:36
  • 488

JS 创建对象的5种写法

//定义Circle类,拥有成员变量r,常量PI和计算面积的成员函数area() //第1种写法 function Circle(r) { this.r ...
  • Inuyasha1121
  • Inuyasha1121
  • 2015年06月29日 22:48
  • 2461

Javascript类的写法

Javascript中function即为类,在function内部用this设置类的public成员变量与方法,例如:function myclass(name){    var str = "pr...
  • Byron0914
  • Byron0914
  • 2010年04月17日 23:40
  • 3348

一段js面向对象的写法

var PaperListPage = {}; PaperListPage.TimeOutID = null; PaperListPage.REPORTTYPE = 2 ; PaperListPage...
  • jianfpeng241241
  • jianfpeng241241
  • 2017年02月09日 09:09
  • 598

JavaScript定义对象的2代码种风格和对象属性有两种寻址方式

JavaScript定义对象 var person={firstname:"王",lastname:"鹏鹏",age:22}; document.write(person.las...
  • u012110719
  • u012110719
  • 2015年08月05日 14:20
  • 761

详细讲解js中静态对象和构造函数的区别

平常我们会经常使用JSON形式,或者var obj=function(){}亦或function(){}这么几种对象的构建办法,有时会认为这是等价的办法,然而他们还有不同。 来看下下面的对比代码...
  • wu_qionglei
  • wu_qionglei
  • 2012年02月06日 21:43
  • 2357

Javascript中点击(click)事件的3种写法

方法一: Javascript中点击事件方法一 click var btn = document.getElementById("btn"); btn.onclick=...
  • h5css3_linhuai
  • h5css3_linhuai
  • 2017年02月20日 12:23
  • 644

javascript定义对象写法

javascript定义对象的几种简单方法 1.构造函数方式,全部属性及对象的方法都放在构造方法里面定义 优点:动态的传递参数 缺点:每创建一个对象就会创建相同的方法函数对象,占用大...
  • zhuyingya
  • zhuyingya
  • 2014年07月14日 21:35
  • 164

Javascript 模块化编程(对象写法)

Javascript 模块化编程(对象写法)
  • timchen525
  • timchen525
  • 2017年09月18日 22:47
  • 178

javascript中对象的属性名为变量的场景

今天帮伙伴解决一个问题,开发功能中对象的属性名是一个变量。按照他编写的代码赋值后的对象,直接将变量名作为了属性名。以下是其编写代码: var aa = "ok"; var bb = "no"; var...
  • ernijie
  • ernijie
  • 2017年01月06日 18:00
  • 1050
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JavaScript中对象写法
举报原因:
原因补充:

(最多只允许输入30个字)