//使用
module1.foo();
module2();
module3.foo();
module3.bar();
举例2:
// file greeting.js 定义一个模块
var helloInLang = {
en: ‘Hello world!’,
es: ‘¡Hola mundo!’,
ru: ‘Привет мир!’
};
var sayHello = function (lang) {
return helloInLang[lang];
}
// 对外输出
module.exports.sayHello = sayHello;
// file hello.js 引入一个模块
var sayHello = require(‘./lib/greeting’).sayHello;
var phrase = sayHello(‘en’);
console.log(phrase);
举例3:
// a.js
module.exports = {
moduleFunc: function() {
return true;
};
}
// 或
exports.moduleFunc = function() {
return true;
};
// 在 b.js 中引用
var moduleA = require(‘a.js’);
// 或
var moduleFunc = require(‘a.js’).moduleFunc;
console.log(moduleA.moduleFunc());
console.log(moduleFunc())
2.AMD规范
2.1说明
-
CommonJS规范出现后,在Node开发中产生了非常好的效果,开发者希望借鉴这个经验来解决浏览器JS的模块化
-
但是大部分人认为浏览器和服务器的环境差别太大,毕竟浏览器JS时通过网络动态以此加载的,而服务器的JS是保存在本地磁盘中。因此浏览器需要实现异步加载,模块在定义的时候就必须先知名它所需要依赖的模块,然后把本模块的代码写在回调函数中执行,最终衍生出了AMD规范
-
AMD的主要思想时异步模块,主逻辑在函数回调中执行
2.2 标准内容
1.定义没有依赖的模块
module1.js
define(function(require,exports.module){
return 模块
}
2.定义具有依赖的模块
module2.js
define([‘module1’,‘module2’],function(m1,m2){
return 模块
}
3.引入模块
main.js
require([‘module1’,‘module2’],function(m1,m2){
})
2.3 举例使用:
//module.js
define(function (require, exports, module) {
console.log(‘module.js’)
exports.name = “jack” //暴露
})
//module2.js
define(function (require, exoprts, module) {
console.log(‘module2.js’);
exports.desc = “hello world”
})
//main.js
require([‘module1’, ‘module2’], function (m1, m2) {
console.log(‘main.js’);
console.log(m1.name + ‘,’ + m2.desc); //引入module1和module2之后,直接使用其暴露的属性
})
// 执行顺序:
// module1.js
// module2.js
// main.js
人无完人,AMD/RequireJS 也存在饱受诟病的缺点。按照 AMD 的规范,在定义模块的时候需要把所有依赖模块都罗列一遍(前置依赖)
,而且在使用时还需要在 factory 中作为形参传进去。
CMD/RequireJS模块化的顺序是这样的:模块化加载=》全部模块预执行=》主逻辑中调用模块
所以是依赖加载完成后会先预先将模块执行一遍,这种方式会使得程序效率低;
define([‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’], function(a, b, c, d, e, f, g){ … });
3.CMD规范
3.1 说明
- AMD/RequireJS的JS模块实现有很多不优雅的地方,主要原因不能以一种更好的管理模块的依赖加载和执行;
那么就出现了SeaJS,SeaJs遵循的是CMD规范,CMD规范在AMD的基础上改进的一种规范,解决了AMD对依赖模块的执行时机的问题;
-
SeaJS模块化的顺序是:
模块化预加载=》主逻辑调用模块时才执行模块中的代码
-
SeaJS的用法和AMD基本相同,并且融合了
CommonJS的写法:
3.2 使用
(对于模块的引入,具有同步和异步两中方式)
//module1.js
define(function (require, exports, module) {
console.log(‘module1.js’)
// module.exports = value;
// exports.xxx = value
exports.name=“i am module1”
})
//main.js
define(function (require, exports, module) {
//引入依赖模块(同步)
var module2 = require(‘./module2’);
console.log(module2.name)
//引入依赖模块(异步1)
require.async(‘./module3’, function (m3) {
//这里m3对应module3
})
//引入依赖模块(异步2)
var module4=require.async(‘./module4’);
console.log(module4.name)
})
总结:
SeaJS的出现,是CommonJS在浏览器的践行者,并吸收了RequireJS的优点
4. ES6中的Module模块
4.1 标准内容
-
模块功能主要由两个命令构成:
export
和import
-
export
用于暴露接口,import
用于引入模块
4.2 模块的定义
有如下3中方式
- 方式1-----分别暴露
//module1.js
export var m=1
export var arr=[1,2,4]
export function fun(){
console.log(‘i am a fun’)
}
//引入与使用(结构引入):
import {m,arr,fun} from ‘./module1’
console.log(m);
fun()
- 方式2—统一暴露
//module2.js
var m=1;
var arr=[1,2,4]
function fun() {
console.log(‘i am a fun’)
}
export {m,arr,fun}
//引入与使用(结构引入):
import {m,arr,fun} from ‘/module2.js’
console.log(arr);
fun()
- 方式3----默认暴露
//这里默认暴露对象
//module3.js
//export default其实是导出一个叫做default的变量,所以其后面不能跟变量声明语句。
//错误
export default var a = 1;
//正确
export default {
m:1,
fun(){
console.log(‘i am a fun from export defalut’)
}
}
//person.js
export default function getName(){
…
}
//引入和使用(module为自定义任意名字)
import module from ‘./module3.js’
module.fun()
4.4 模块的引入
// 解构引入
import { firstName, lastName, year } from ‘a-module’;
// 为输入的变量重新命名
import { lastName as surname } from ‘a-module’;
// 引出模块对象(引入所有)
import * as ModuleA from ‘a-module’;
- 在使用 ES Module 值得注意的是:import 和 export 命令只能在模块的顶层,在代码块中将会报错,这是因为 ES Module 需要在编译时期进行模块静态优化,import 和 export 命令会被 JavaScript 引擎静态分析,先于模块内的其他语句执行,这种设计有利于编译器提高效率,但也导致无法在运行时加载模块(动态加载)。
对于这个缺点,TC39 有了一个新的提案 – Dynamic Import,提案的内容是建议引入 import()
方法,实现模块动态加载。
// specifier: 指定所要加载的模块的位置
import(specifier)
- import()方法返回一个Promise对象
import(‘b-module’)
.then(module => {
module.helloWorld();
})
.catch(err => {
console.log(err.message);
});
PS:
import()
函数可以用在任何地方,不仅仅是模块,非模块的脚本也可以使用。
它是运行时执行,也就是说,什么时候运行到这句话,就会加载到指定的模块。另外,import()
函数所加载的模块没有静态链接关系,这点也是与import
语法不同
- 注意的时ES6 的Module语法有些浏览器是不支持的,因此需要Babel先进性转码,将import和export命令转成ES5语法才能被浏览器解析。
这里举例之前做过的一个小项目,就是使用了ES6语法中的module模块化思想结合axios库,将需要向服务端发送请求的操作封装到一个模块中,然后对于不同的请求数据操作,直接导入该模块调用即可
1)封装ajax请求函数(使用的时默认暴露)
//首先向外暴露一个函数
//默认为GET请求
import axios from ‘axios’
export default function ajax(url,data={},type=‘GET’) {
return new Promise(function (resolve, reject) {
//这里的return主要时结果的回调函数,即成功了则回调sesolve函数,失败了则回调reject函数
//即异步返回的数据是response.data
let promise
if (type === ‘GET’) {
//这里的目的主要是想将参数拼接成url?username=xx&password=XX
let dataString = ‘’;
Object.keys(data).forEach(key => {
dataString += key + ‘=’ + data[key] + ‘&’
})
if (dataString != null) {
dataString = dataString.substring(0, dataString.length - 1);
url = url + ‘?’ + dataString;
}
//使用axios发送get请求
promise = axios.get(url)
///console.log(promise)
} else {
//使用axios发送post请求
//post请求不用
promise = axios.post(url, data)
}
//response是axios发送请求后得到的promise对象中的response,
//最后因为响应体的数据杂多,这里只取response中的data
promise.then(function (response) {
//成功了则调用resolve
resolve(response.data);
}).catch(function (error) {
//失败了则调用reject
reject(error)
})
})
}
2)封装接口请求函数----使用的时分别暴露
(这个接口函数需要导入上面封装的ajax请求函数,调用,发送请求)
import ajax from ‘./ajax’
const BASE_URL=‘/api’
//注册接口
//注册时即向后台传送username与password---->一个user对象—参数
//需要ajax为桥梁发送请求,ajax返回的结果就是现所需要的结果
//再ajax中需要指定参数
//url—只需要指定后面部分
//2.获取食品分类列表
export const reqFootCategory=()=>ajax(BASE_URL+‘/index_category’)
//3.商店数组对象
export const reqShops=(longitude,latitude)=>ajax(BASE_URL+‘/shops’,{longitude,latitude})
//1.根据经纬度获取地址详情
export const reqAddress=(geohash)=>ajax(${BASE_URL}/position/${geohash}
)
//4.根据经纬度和关键字搜索商铺列表
export const reqSearchShop = (geohash, keyword) => ajax(BASE_URL+‘/search_shops’, {geohash, keyword})
//5.获取一次性验证码
export const reqGetcaptcha=()=>ajax(BASE_URL+‘/captcha’)
//6.用户名密码登录
export const reqPwdLogin=({name,pwd,captcha})=>ajax(BASE_URL+‘/login_pwd’,{name,pwd,captcha},‘POST’)
//7.发送短信验证码
export const reqSendCode=(phone)=>ajax(BASE_URL+‘/sendcode’,{phone})
//8.手机号验证码登录
export const reqSmsLogin=(phone,code)=>ajax(BASE_URL+‘/login_sms’,{phone,code},‘POST’)
//18813216310
//9.根据会话获取用户信息
export const reqUserInfo=()=>ajax(BASE_URL+‘/userinfo’)
//10.用户登出
export const reqLogout=()=>ajax(BASE_URL+‘logout’)
3)当其他模块需要调用发送请求时,直接使用import结构导入封装的接口函数即可
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
const reqUserInfo=()=>ajax(BASE_URL+‘/userinfo’)
//10.用户登出
export const reqLogout=()=>ajax(BASE_URL+‘logout’)
3)当其他模块需要调用发送请求时,直接使用import结构导入封装的接口函数即可
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-2LNjuvr1-1715542731844)]
[外链图片转存中…(img-zDvcUc1l-1715542731845)]
[外链图片转存中…(img-6Ud5Qwuu-1715542731845)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!