javascript中的define用法

文章目录

  • 1. AMD的由来
  • 2. AMD是什么
  • 3. AMD实例:如何定义一个模块
  • 4. 匿名模块
  • 5. 仅有一个参数的define
  • 6. Dojo中的AMD
  • 7. 结论

最近由于工作需求只能快速学习JS,但在看代码的时候发现许多东西都有疑问比如说代码刚开始的define关键字的用法,刚好最近看了一篇好文章,分享一下。

1. AMD的由来

前端技术虽然在不断发展之中,却一直没有质的飞跃。除了已有的各大著名框架,比如Dojo,JQuery,ExtJs等等,很多公司也都有着自己的前端开发框架。这些框架的使用效率以及开发质量在很大程度上都取决于开发者对其的熟悉程度,以及对JavaScript的熟悉程度,这也是为什么很多公司的技术带头人都喜欢开发一个自己的框架。开发一个自己会用的框架并不难,但开发一个大家都喜欢的框架却很难。从一个框架迁移到一个新的框架,开发者很有可能还会按照原有框架的思维去思考和解决问题。这其中的一个重要原因就是JavaScript本身的灵活性:框架没办法绝对的约束你的行为,一件事情总可以用多种途径去实现,所以我们只能在方法学上去引导正确的实施方法。庆幸的是,在这个层面上的软件方法学研究,一直有人在去不断的尝试和改进,CommonJS就是其中的一个重要组织。他们提出了许多新的JavaScript架构方案和标准,希望能为前端开发提供银弹,提供统一的指引。

AMD规范就是其中比较著名一个,全称是Asynchronous Module Definition,即异步模块加载机制。从它的规范描述页面看,AMD很短也很简单,但它却完整描述了模块的定义,依赖关系,引用关系以及加载机制。从它被requireJS,NodeJs,Dojo,JQuery使用也可以看出它具有很大的价值,没错,JQuery近期也采用了AMD规范。在这篇文章中,我们就将介绍AMD的性质,用法,优势以及应用场景。从AMD中我们也能学习到如何在更高层面去设计自己的前端应用。

2. AMD是什么

作为一个规范,只需定义其语法API,而不关心其实现。AMD规范简单到只有一个API,即define函数:

define([module-name?], [array-of-dependencies?], [module-factory-or-object]);
  其中:
  module-name: 模块标识,可以省略。
  array-of-dependencies: 所依赖的模块,可以省略。
  module-factory-or-object: 模块的实现,或者一个JavaScript对象。

从中可以看到,第一个参数和第二个参数都是可以省略的,第三个参数则是模块的具体实现本身。后面将介绍在不同的应用场景下,他们会使用不同的参数组合。

从这个define函数AMD中的A:Asynchronous,我们也不难想到define函数具有的另外一个性质,异步性。当define函数执行时,它首先会异步的去调用第二个参数中列出的依赖模块,当所有的模块被载入完成之后,如果第三个参数是一个回调函数则执行,然后告诉系统模块可用,也就通知了依赖于自己的模块自己已经可用。如果对应到dojo1.6之前的实现,那么在功能上可以有如下对应关系:

module-name: dojo.provide

dependencies: dojo.require

module-factory: dojo.declare

不同的是,在加载依赖项时,AMD用的是异步,而dojo.require是同步。异步和同步的区别显而易见,前者不会阻塞浏览器,有更好的性能和灵活性。而对于NodeJs这样的服务器端AMD,则模块载入无需阻塞服务器进程,同样提高了性能。

3. AMD实例:如何定义一个模块

下面代码定义了一个alpha模块,并且依赖于内置的require,exports模块,以及外部的beta模块。可以看到,第三个参数是回调函数,可以直接使用依赖的模块,他们按依赖声明顺序作为参数提供给回调函数。

这里的require函数让你能够随时去依赖一个模块,即取得模块的引用,从而即使模块没有作为参数定义,也能够被使用;exports是定义的alpha 模块的实体,在其上定义的任何属性和方法也就是alpha模块的属性和方法。通过exports.verb = …就是为alpha模块定义了一个verb方法。例子中是简单调用了模块beta的verb方法。

define(“alpha”, [“require”, “exports”, “beta”], function (require, exports, beta) {

exports.verb = function() {

return beta.verb();

//或者:

return require(“beta”).verb();

}

});

4. 匿名模块

**define 方法允许你省略第一个参数,这样就定义了一个匿名模块,这时候模块文件的文件名就是模块标识。**如果这个模块文件放在a.js中,那么a就是模块名。可以在依赖项中用"a"来依赖于这个匿名模块。这带来一个好处,就是模块是高度可重用的。你拿来一个匿名模块,随便放在一个位置就可以使用它,模块名就是它的文件路径。这也很好的符合了DRY(Don’t Repeat Yourself)原则。

下面的代码就定义了一个依赖于alpha模块的匿名模块:

define([“alpha”], function (alpha) {

return {

verb: function(){

return alpha.verb() + 2;

}

};

});

5. 仅有一个参数的define

前面提到,define的前两个参数都是可以省略的。第三个参数有两种情况,一种是一个JavaScript对象,另一种是一个函数。

**如果是一个对象,那么它可能是一个包含方法具有功能的一个对象;也有可能是仅提供数据。后者和JSON-P非常类似,因此AMD也可以认为包含了一个完整的 JSON-P实现。**模块演变为一个简单的数据对象,这样的数据对象是高度可用的,而且因为是静态对象,它也是CDN友好的,可以提高JSON-P的性能。考虑一个提供中国省市对应关系的JavaScript对象,如果以传统JSON-P的形式提供给客户端,它必须提供一个callback函数名,根据这个函数名动态生成返回数据,这使得标准JSON-P数据一定不是CDN友好的。但如果用AMD,这个数据文件就是如下的形式:

define({

provinces: [

{

name: ‘上海’,

areas: [‘浦东新区’, ‘徐汇区’]},

{

name: ‘江苏’,

cities: [‘南京’, ‘南通’]}

//…

]

});

假设这个文件名为china.js,那么如果某个模块需要这个数据,只需要:

define([‘china’, function(china){

//在这里使用中国省市数据

});

通过这种方式,这个模块是真正高度可复用的,无论是用远程的,还是Copy到本地项目,都节约了开发时间和维护时间。

如果参数是一个函数,其用途之一是快速开发实现。适用于较小型的应用,你无需提前关注自己需要什么模块,自己给谁用。在函数中,可以随时require自己需要的模块。例如:

define(function(){

var p = require(‘china’);

//使用china这个模块

});

即你省略了模块名,以及自己需要依赖的模块。这不意味着你无需依赖于其他模块,而是可以让你在需要的时候去require这些模块。define方法在执行的时候,会调用函数的toString方法,并扫描其中的require调用,提前帮助你载入这些模块,载入完成之后再执行。这使得快速开发成为可能。需要注意的一点是,Opera不能很好的支持函数的toString方法,因此,在浏览器中它的适用性并不是很强。但如果你是通过build工具打包所有的 JavaScript文件,这将不是问题,构建工具会帮助你扫描require并强制载入依赖的模块。

6. Dojo中的AMD

Dojo 的1.6版本,其中一个重要的变化就是引入了AMD机制,取代了原来的dojo.provide和dojo.require方法。但是现在仍然保持了向后兼容性,你仍然可以用dojo.provide和dojo.require来定义和加载模块。需要注意的是:在 Dojo 1.6 中, 针对 AMD 的重构仍然属于一个过渡期的改动 , 用户自己开发的 AMD 模块还不能被 Dojo 的加载器和 Build 系统支持 . 1.6 中现有的编译系统对AMD的支持还非常局限。 如果你自己开发了 AMD 格式的模块,并且你仍然在使用默认的 Dojo 同步模块加载器,那么你必须严格遵循 Dojo 模块的格式 ( 包括换行的格式 ) 来保证你自己的模块能够成功编译。总结起来有以下三点:

用传统的方法 (dojo.require()/dojo.provide()) – 这些模块,只能被 Dojo 同步加载器 加载,但可以被 Dojo 编译系统(Build System )正确的编译

用 Dojo 同步加载器来加载 AMD 格式 ( define ()) 模块 – 这些模块可以被正常的加载,并且可以被其他兼容 AMD 格式的加载器加载 . 现在虽然 Dojo1.6 还没有正式支持这种用法, 但在目前的 Dojo1.6 编译系统中,是可以正常工作的 . ( 前提是你必须严格遵循 Dojo 模块定义的代码规范 )

使用第三方加载器来加载 AMD 格式( define ())模块 – 模块可以被正常加载,并且可以被其他加载器所使用 . 这些模块可以使用 RequireJS 或 Backdraft 提供的编译系统正常编译,但是 Dojo 还没有正式的测试过和其他加载器的兼容性 .

以Calendar为例,用define方法来定义这个模块:

define(“dijit/Calendar”,

[“dojo”, “dijit”, “text!dijit/templates/Calendar.html”,

“dojo/cldr/supplemental”, “dojo/date”, “dojo/date/locale”,

“dijit/_Widget”, “dijit/_Templated”, “dijit/_CssStateMixin”, “dijit/form/DropDownButton”],

function(dojo, dijit) {

dojo.declare(

“dijit.Calendar”,

[dijit._Widget, dijit._Templated, dijit._CssStateMixin],

{…}

);

return dijit.Calendar;

}

);

可以看到,模块标识就是模块文件的路径,模块本身一般都是dojo.declare定义的类。Dojo1.6中的dojo和dijit命名空间下的模块均已经用AMD的形式进行了重构,但dojox下仍然延用了传统的dojo.provide和dojo.require形式。对AMD的引入是Dojo走向自动化包管理的重要一步,在后续文章中我们也将继续关注Dojo在这方面的进展。

7. 结论

AMD 规范是JavaScript开发的一次重要尝试,它以简单而优雅的方式统一了JavaScript的模块定义和加载机制,并迅速得到很多框架的认可和采纳。这对开发人员来说是一个好消息,通过AMD我们降低了学习和使用各种框架的门槛,能够以一种统一的方式去定义和使用模块,提高开发效率,降低了应用维护成本。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/456829.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决:pip警告!DEPRECATION: The default format will switch to columns in the future.

pip警告! DEPRECATION: The default format will switch to columns in the future. You can use --format(legacy|columns) (or define a format(legacy|columns) in your pip.conf under the [list] section) to disable this warning. pip升级到9.0.1后 查看pi…

PLSQL安装配置

(1)解压:plsql developer Oracle数据库开发工具首先确保有oracle数据库或者有oracle服务器,然后才能使用PLSQL Developer连接数据库。(2)工具---首选项---连接----输入OCI库(设置之后不用再装or…

Mysql 学习笔记2

(1)MySQL查看表占用空间大小 //先进去MySQL自带管理库:information_schema //自己的数据库:dbwww58com_kuchecarlib //自己的表:t_carmodelparamvalue mysql> use information_schema; Database changed mysql&g…

python程序打包为exe可执行文件

大家都知道,Python是一种脚本语言,也就是解释型的语言,需要解释器来进行解释以后才可以执行,而Python源代码需要在Python虚拟机上面运行,但是我们做好的程序,不可能给用户使用的时候还让他安装一个Python环…

Backbone简介

1. 前言 本文的目的,是帮助大家快速理解掌握Backbone的使用,但它并不是API,因此我不会将每一个方法都详细地描述,但是我会告诉你如何学习它们。 这是一篇稍稍较长的技术文章,因为我想将我所了解的东西尽可能详细地分享…

使用Android Studio搭建Android集成开发环境

一、Android Studio简单介绍 2013年GoogleI/O大会首次发布了Android Studio IDE(Android平台集成开发环境)。它基于Intellij IDEA开发环境,旨在取代Eclipse和ADT(Android开发者工具)为开发者提供更好的开发工具。既然G…

[Oracle]UNIX与Windows 2000上Oracle的差异(I)

作者:Ian Adam & David Stien, SAIC Ltd 日期:19-Dec-2003 出处:http://www.dbanotes.net翻译:Fenng -----------------------------------------------------------------------------------------------------------------…

django2.x报错No module named 'django.core.urlresolvers'

解决方法就是: from django.urls import reverse 最近从django1.9迁移到django2.0中出现一个意外的报错: 这个报错的原因在stack overflow上有很直接的解释,但是百度上并没有直接的答案。 简单来说,原因就是:django2.0 把原来…

Underscore简介

5. Underscore.js Underscore封装了常用的JavaScript对象操作方法,用于提高开发效率。它本身与我们介绍的主题“Backbone”没有半毛钱的关系,因此你可以完全不理会“Backbone”的概念来学习它,或将它单独运用到任何一个页面。(另外…

POJ2190 HDU2714 ISBN

USACO 2003 Fall Orange 问题链接:POJ2190 HDU2714 ISBN。 问题简述:参见上述链接。 问题分析: 单纯的计算问题。需要注意以下几点: 1.如果是末尾数,则输出为‘X’; 2.如果能找到对应的值则输出&#xff1b…

Django-安装xadmin的方法及主要配置方法

历经千辛万苦,终于实现了django2.1中xadmin的使用 被论坛里各路神仙带跑N次 准确说是几个小时 直接colne https://github.com/Liu0330/xadmin 工作系统环境:win10Python3.6.xDjango2.1.xXadmin2.0(注意2.2版本就不行!&#xff…

大数据集群搭建之Linux的安装(一)

1、准备工具 VMWare、centos mimal版本系统文件。 2、工具安装 1、安装vmware软件 安装软件地址: VMWare:http://pan.baidu.com/s/1qYnySrE 密码:3t3r centos mimal版本:http://pan.baidu.com/s/1dE5LY6H 密码&#xff1a…

阻止事件冒泡两种方式:event.stopPropagation();和return false;

jQuery提供了两种方式来阻止事件冒泡。 方式一:event.stopPropagation(); $("#div1").mousedown(function (event) {event.stopPropagation(); }); 方式一:return false; $("#div1").mousedown(function (event) {return false; });…

关于电脑的基础单词笔记

chapter01 mouse 鼠标. keyboard 键盘. notepad 记事本 . sava 保存. chapter02 word 文本文档. office 办公软件. copy 复制. past 粘贴. find 复制. table 表格. page 页. picture 图片. chapter03 sheet 工作薄. cell 单元格. number 数字. true 真. …

Python3.6+Django2.0+Xadmin2.0学生信息管理系统

一、创建模型 模型是表示我们的数据库表或集合类,并且其中所述类的每个属性是表或集合的字段,在 app/models.py 中定义。 1、首先,导入models模块 from django.db import models 接下来创建个学生信息类,其中包含学生姓名、性别…

升级 pip版本

安装第三方库:pip install Pillow 出现 You are using pip version 7.1.2, however version 9.0.1 is available. You should consider upgrading via the python -m pip install --upgrade pip comm and. 解决方法1: 输入“python -m pip install -U pi…

大数据集群搭建之节点的网络配置过程(二)

紧接着上一章来设置windows的vmnet8的ip地址和虚拟机中centos的ip地址。 NAT虚拟网络的配置图如下图所示: 1、这里根据VMware中得到的网关地址去设置vmnet8的ip地址。 网关地址查看: 2、得到的网关地址后去设置vmnet8,将网关地址设置为v…

Python3.6+Django2.0+Xadmin2.0学生信息管理系统-2

1、上传图片/文件等资源 有时候需要添加一些附件,例如,新生刚入学,大家相互之间还不熟悉,希望能通过照片来加深印象,并且方便教学管理。 首先,对demo/urls.py文件进行改造,给urlpatterns添加s…

vim自带的练习教程(vimtutor)

声明:本文源于Centos 7.2系统vim自带的练习教程--vimtutor欢迎阅 读《 V I M 教 程 》 - 版本 1.7 Vim 是一个具有很多命令的功能非常强大的编辑器。限于篇幅,在本教程当中就不详细介绍了。本教程的设计目标是讲述一些必要的基本命令,而掌握…

pycharm之no python interpreter configured for project的解决办法

今天由于重装了系统,所以必须得重新配置一些软件,在打开pycharm运行程序时显示“no python interpreter configured for project”提示。根据字面意思是“python没有解释器”。 解决办法: 找到你之前下载python环境支持库如下图所示&#x…