JavaScript中Require调用js实例讲解

本文主要为大家带来一篇javascript中require调用js的实例分享。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。

在我最初开始写 JavaScript 函数时,通常是这样的:

function fun1() { // some code here}function fun2() { // some other code here}...

登录后复制

函数全写在全局环境中,项目很小时,通常不会有什么冲突问题。

但代码多了后,渐渐就发现,函数名称(英文词汇)有点不够用了。于是引入命名空间的概念,开始模块化代码。

命名空间下的函数

立即学习“Java免费学习笔记(深入)”;

在命名空间下,我的代码这样写:

var com = com || {};com.zfanw = com.zfanw || {};com.zfanw.module1 = (function() { // some code here return { func1: func1, ... };}());com.zfanw.module2 = (function() { // some other code here return { func1: func1, ... };}());...

登录后复制

本着要面向对象的原则,执行函数通常我要这么写的:

com.zfanw.module1.func1.apply({},['arg1',arg2]);...

登录后复制

当然,为了少打些字符,我还会在闭包中导入1公共 API 接口:www.jb51.net

(function($, mod1) { // some code here mod1.func1.apply({},['arg1',arg2]);}(jQuery, com.zfanw.module1));...

登录后复制

至此,代码冲突的可能性已经很小,但代码依赖的问题,多脚本文件管理、阻塞的问题,渐渐浮出水面 – 命名空间的办法开始捉急。

于是 Require.js2 出场。

Require.js

首先了解下 require.js 里模块的概念3:

A module is different from a traditional script file in that it defines a well-scoped object that avoids polluting the global namespace. It can explicitly list its dependencies and get a handle on those dependencies without needing to refer to global objects, but instead receive the dependencies as arguments to the function that defines the module.

简单地说,有两点,一、模块作用域自成一体,不污染全局空间;二、模块指明依赖关系,并且依赖是通过参数传递的形式导入的,无需通过全局对象引用 – 依赖同样不污染全局空间。

定义模块

与上面的老长的命名空间方式不同,require.js 用全局方法 define 来定义模块,形式如下:

define(id?, dependencies?, factory); // ? 表示可选项

登录后复制

我且把模块分两种。

无依赖的模块

假如一个模块并不依赖其他模块,那么定义起来是很简单的,比如模块 hello 放在 hello.js 文件中:

define(function() { // some code here return { // some public api };});

登录后复制

有依赖的模块

有依赖的模块要稍稍复杂点,define 时,我们需要罗列出模块的依赖情况:

define(['jquery'], function($) { // 比如这个模块,代码的执行依赖 jQuery,require.js 会先加载 jquery 模块代码,并加以执行,然后将依赖模块 以 $ 的参数形式传入回调函数中,回调函数将执行结果注册为模块 // maybe some code here return { // some public api };});

登录后复制

这里,依赖中的 ‘jquery’ 是模块相对于 baseUrl 的路径,等效于模块 ID。

现在,再回过头,看看上面写过的闭包中导入公共 API 的代码,跟 define 函数做个对比:

(function($, mod1) { // some code here mod1.func1.apply({},['arg1',arg2]);}(jQuery, com.zfanw.module1));

登录后复制

这段代码里,我同样把 jQuery 导入了,在闭包里,我同样是通过 $ 这个外部传入的参数来访问 jQuery。可以说,它「定义依赖」的方式跟 define 方法很相似,不同的是,define 导入的 jquery 不是全局变量,所以不会污染全局环境。

关于模块名称

define 函数有三个参数,第一个 id 即模块名称,这个名称的格式是相对于 baseUrl 的路径除去文件格式,比如 baseUrl 为 js 目录,一个模块放在 js/libs/hi.js 里,则如果名称是这样定义的:

define('libs/hi', ['jquery'], function($){......});

登录后复制

这样的定义形式的好处是,模块不可能冲突,因为同一目录下不允许同名文件。但也因此 require.js 建议我们不要设置模块名称,因为设置了 ‘libs/hi’ 的模块名称后,模块就必须放在 js/libs 目录下的 hi.js 文件中,要移动位置的话,模块名称要跟着改变。至于后期利用 r.js 优化时生成了模块名称,那已经是另外一回事。

使用模块

在定义好「有依赖」、「没依赖」的各种模块后,我们该怎么用它?Require.js 提供了一个函数,require(与 requirejs 等效)。

require 函数加载依赖并执行回调,与 define 不同的是,它不会把回调结果4注册成模块:

require(['jquery'], function($) { // 这个函数加载 jquery 依赖,然后执行回调代码 console.log($);});

登录后复制

举一个简单的例子。我有一个文件夹,文件结构如下:

index.html js/  main.js  require.js  jquery.js

登录后复制

这里 jquery.js 已经注册为 AMD 模块,则 HTML 文件里这样引用 require.js:


登录后复制

require.js 会检查 data-main 属性值,这里是 js/main,根据设定,它会加载 js 目录下的 main.js 文件。

main.js 文件里,我只干一件事,用 jQuery 方法取得当前窗口的宽度:

require(['jquery'], function($) { var w = $(window).width(); console.log(w);});

登录后复制

执行代码就这么简单。

非 AMD 规范的模块

但事情远没有我们想像中那么美好,AMD 只是一种社区规范,并非标准,而且在它出现以前,已经有各种各样的流行库存在,更不用说我们自己早期写的代码,所以我们一定会碰上一堆非 AMD 规范的模块。为了让 require.js 能够加载它们,并且自动识别、载入依赖,我们有两种选择,一、给它们全穿上一个叫 define 的函数;二、使用 Require.js 提供的配置选项 shim,曲线救国。

比如我手上一个项目,因为某种原因,还在用 jQuery 1.4.1 版本,而 jQuery 是从1.7版本开始才注册为 AMD 模块的,我要在 require.js 中使用,就需要先做 shim:

require.config({ shim: {  'jquery-1.4.1': { // 

写完 shim,发现 jquery-1.4.1、libs/jquery-throttle-debounce.min 这样的名称有点长。这里我们又有两种选择,一是直接打开修改 js 文件名,或者使用 require.js 提供的配置项 paths 给模块 ID 指定对应的真实文件路径:


require.config({ paths: {  'jquery': 'jquery-1.4.1', // 

这样,引用起来就方便多了。

另外,需要注意 shim 中的 exports 项,它的概念更接近 imports,即把全局变量导入。我们如果把 exports 值改成非全局变量名,就会导致传入回调的对象变成 undefined,举个例子:


require.config({ paths: {  'jquery': 'jquery-1.4.1', }, shim: {  'jquery': {   exports: 'hellojQuery' // 这里我把 exports 值设置为 jQuery/$ 以外的值  } }});require(['jquery'], function($){ console.log($);// 这里,会显示 undefined});

登录后复制

其他模块在做 shim 时同理,比如 underscore 需要 exports 成 _。

Require.js 的好处

说了这么多,Require.js 到底有什么好处?

并行加载

我们知道, 标签会阻塞页面,加载 a.js 时,后面的所有文件都得等它加载完成并执行结束后才能开始加载、执行。而 require.js 的模块可以并行下载,没有依赖关系的模块还可以并行执行,大大加快页面访问速度。

不愁依赖

在我们定义模块的时候,我们就已经决定好模块的依赖 – c 依赖 b,b 又依赖 a。当我想用 c 模块的功能时,我只要在 require函数的依赖里指定 c:

require(['c'], function(c) {...});

至于 c 依赖的模块,c 依赖的模块的依赖模块… 等等,require.js 会帮我们打理。

而传统的 script 办法,我们必须明确指定所有依赖顺序:

  

登录后复制

换句话说,传统的 script 方法里,我们极可能要靠记忆或者检查模块内容这种方式来确定依赖 – 效率太低,还费脑。

减少全局冲突

通过 define 的方式,我们大量减少了全局变量,这样代码冲突的概率就极小极小 – JavaScript 界有句话说,全局变量是魔鬼,想想,我们能减少魔鬼的数量,我想是件好事。

关于全局变量

有一点需要说明的是,require.js 环境中并不是只有 define 和 require 几个全局变量。许多库都会向全局环境中暴露变量,以 jQuery 为例,1.7版本后,它虽然注册自己为 AMD 模块,但同时也向全局环境中暴露了 jQuery 与 $。所以以下代码中,虽然我们没有向回调函数传入一份引用,jQuery/$ 同样是存在的:

require(['jquery'], function(){ console.log(jQuery); console.log($);});

登录后复制

相关推荐:

a标签不能调用js方法的问题

iframe子父页面调用js函数示例

php如何调用js方法

以上就是JavaScript中Require调用js实例讲解的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2790205.html

(0)
上一篇 2025年3月8日 18:52:35
下一篇 2025年3月6日 03:28:11

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 详解JavaScript自执行函数和jQuery扩展方法

    本文主要为大家详细介绍了javascript自执行函数和jquery扩展方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能帮助到大家。 我们通常将JS代码写在一个单独的JS文件中,然后在页面中引入该文件。但是,有时候引入后会碰到…

    编程技术 2025年3月8日
    200
  • 三种JavaScript模拟实现封装的方式及写法区别分享

     继承是使用一个子类继承另一个父类,那么子类可以自动拥有父类中的所有属性和方法,这个过程叫做继承!  js中有很多实现继承的方法,今天我给大家介绍其中的三种吧。下面通过本文来了解下js模拟实现封装的三种方法,需要的朋友参考下吧,希望能帮助到…

    编程技术 2025年3月8日
    200
  • javascript浏览器用户代理检测脚本方法详解

    本文主要为大家带来一篇javascript浏览器用户代理检测脚本实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。 以下是完整的用户代理字符串检测脚本,包括检测呈现引擎、平台、Wind…

    编程技术 2025年3月8日
    200
  • javascript中的typeof和类型判断详解

    本文主要为大家带来一篇基于javascript中的typeof和类型判断(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。 typeof ECMAScript 有 5 种原始类型(pr…

    编程技术 2025年3月8日
    200
  • AngularJs用户登录交互及验证、阻止FQ处理详解

    本文主要为大家详细介绍了angularjs用户登录问题处理,包括交互及验证、阻止fq处理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能帮助到大家。 1. 静态页面搭建及ng的form表单验证实现:               登…

    编程技术 2025年3月8日
    200
  • Angular js综合操作方法详解

    本文主要介绍了angular js 实现添加用户、修改密码、敏感字、下拉菜单的综合操作方法,需要的朋友可以参考下,希望能帮助到大家。 小编在上篇文章给大家介绍了AngularJS模糊查询功能实现代码(过滤内容下拉菜单排序过滤敏感字符验证判断…

    编程技术 2025年3月8日
    200
  • Vue.js 2.5新特性分享

    本文主要和大家分享vue.js 2.5新特性,vue 2.5 level e 已发布,在原来2.x的基础上做了很多相应改进和对 bug 的修复,目前 2.5 系列最新的版本为 2.5.2,本文给大家介绍vue 2.5 新特征,需要的朋友参考…

    2025年3月8日
    200
  • Angular.js排序查询功能的实现

    本文主要介绍了angularjs添加排序查询功能的实例代码,需要的朋友可以参考下,希望能帮助到大家。 废话不多说了,直接给大家贴代码了,具体代码如下所示: var app=angular.module(“myapp”,[]); app.co…

    编程技术 2025年3月8日
    200
  • Vue.js2.0变化小结分享

    有小伙伴觉得vue更新太快了导致课程所讲知识和现在vue的版本不符,从而报错,本文主要和大家分享vue.js2.0变化小结,希望能帮助到大家。 1.关于Vue中$index获取索引值已经取消,多用于多个元素的操作,像ul中的li,通过v-f…

    编程技术 2025年3月8日
    200
  • 使用PM2管理nodejs进程详解

    本文主要介绍了详解使用pm2管理nodejs进程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。 pm2 是一个带有负载均衡功能的Node应用的进程管理器. 当你要把你的独立代码利用全部的服务…

    2025年3月8日
    200

发表回复

登录后才能评论