闭包的进阶思想 & JQ源码环境判断
单例设计模式 & 模块化编程思想
模块化编程历史[当代前端开发,都是模块化编程:公用性&复用性,提高开发效率,方便团队挂历,团队协作开发...]
+ @1 高级单例设计模式[闭包 + 对象] 问题模块之间的依赖,需要明确导入顺寻
+ @2 AMD 按需加载(require.js) 问题:所有的依赖都需要提前导入 "前置依赖"
+ @3 CMD(sea.js) & CommonJS规范(Node.js) 问题: 客户端不支持CommonJS规范(如果导入sea.js是可以支持的) 当代打包工具webpack是支持CommonJs规范的,最后按照CommonJS把各个模块进行打包,编译为浏览器可以支持的代码[webpack本身是基于node环境进行的,基于webpack打包后的代码,是webpack自己实现了一套CMD规范]
+ @4 ES6Module模板规范 特点:webpack中也支持浏览器中也支持 **(html引入js加上type='module')**
扩充:JS代码可以在哪运行
* + 浏览器端 webkit(blink)、gecko、trident...
* + webview「手机端APP中」 webkit
* 「有window,不支持CommonJS规范,支持ES6Module规范」
* -----
* + node环境「没有window、支持CommonJS规范、但是不支持ES6Module规范」
* -----
* + 可以基于webpack进行编译「支持window、也支持CommonJS规范、支持ES6Module规范(可以让ES6Module和CommonJS混合调用)...」:基于node环境进行打包处理,打包后的结果交给浏览器端去渲染和运行
单例模式
/*
立即执行函数 + 对象
*/
// 新闻板块
let newsModule = (function () {
let time = new Date();
const query = function query() {
// ...
};
const handle = function handle() {
// ...
};
// 把供其它板块调用的方法,暴露到全局对象上「局限:暴露的内容比较多,则还会引发全局变量冲突」
// window.query = query;
return {
// query:query
query,
handle
};
})();
// 皮肤板块
let skinModule = (function () {
let time = '2021-05-03';
const handle = function handle() {
// ...
};
newsModule.query();
return {
handle
};
})();
JQ源码环境判断 & 冲突解决
/*
1.typeof module 和 typeof module.exports 判断一下是否支持CommonJS规范=>要么是Node环境或者webpack环境
2.module.exports 基于CommonJS规范的抛出
3.global.document? XXX : XXX 三目运算符 只有global === window才又document 所以一定是再webpack环境下
*/
if ( typeof module === "object" && typeof module.exports === "object" ) {
module.exports = global.document ?
factory( global, true ) :
//4.不是webpack环境就是Node环境 Node环境一定会报错
function( w ) {
if ( !w.document ) {
throw new Error( "jQuery requires a window with a document" );
}
return factory( w );
};
} else {
factory( global );
}
/*window环境直接挂载window*/
if ( typeof noGlobal === "undefined" ) {
window.jQuery = window.$ = jQuery;
}
/*可以使用AMD规范*/
if ( typeof define === "function" && define.amd ) {
define( "jquery", [], function() {
return jQuery;
} );
}
/*
解决冲突
1.记录下之前挂载window的jQuery/$ 存在_jQuery/_$
2.在jQuery上添加个noConflict方法 如果window.$ === jQuery 如果window.$挂的是自己的jQuery就把_jQuery挂到window,把位置让给别人
3.return jQuery;抛出自己作为函数回调
4.let my$ = jQuery.noConflict();接受
*/
var _jQuery = window.jQuery,
_$ = window.$;
jQuery.noConflict = function( deep ) {
if ( window.$ === jQuery ) {
window.$ = _$;
}
if ( deep && window.jQuery === jQuery ) {
window.jQuery = _jQuery;
}
return jQuery;
};
自己封装兼容浏览器端/Node/webpack/webview
/*
1.一般不做ES6module环境适配
2.判断有有window 如果有就挂载window
3.如果是CommonJS规范就 按照commonJS规范抛出
*/
const func1 = function (){
console.log("可以调用");
}
const func2 = function (){
console.log("可以调用1");
}
//判断有有window 如果有就挂载window
if(typeof window !== 'undefined' ){
window.func = window.$ = {func1,func2};
}
//如果是CommonJS规范就 按照commonJS规范抛出
if(typeof module === 'object' && typeof module.exports === 'object'){
module.exports = {
func1,
func2
}
}
自己手写解决冲突代码
const func1 = function (){
console.log("可以调用");
}
const func2 = function (){
console.log("可以调用1");
}
//解决冲突
const noconflict = function (){
//我现在想在window挂载$ 但是我害怕冲突 所以我把之前的window.$保存下来
let _$ = window.$;
if(window.$ === func){
window.$ = _$
}
// 把位置让出去后 把自己的方法返回 在外部就可以 let myfunc = noconflict()
return func;
}
let func = {
func1,
func2,
noconflict
}
if(typeof window !== 'undefined' ){
window.func = window.$ = func;
}
if(typeof module === 'object' && typeof module.exports === 'object'){
module.exports = func
}