网站建设那个公司好,数据分析,济南互联网选号网站,一个网站的seo优化有哪些目录
历程
1.几个函数#xff1a;全局变量的污染#xff0c;模块间没有联系
2.对象#xff1a;暴露成员#xff0c;外部可修改
3.立即执行函数#xff1a;闭包实现模块私有作用域
common JS
module和Module
过程
模块依赖#xff1a;深度优先遍历、父 - 子 -…目录
历程
1.几个函数全局变量的污染模块间没有联系
2.对象暴露成员外部可修改
3.立即执行函数闭包实现模块私有作用域
common JS
module和Module
过程
模块依赖深度优先遍历、父 - 子 - 父
导入require
避免重复加载、循环引用Module缓存
先加入缓存 后执行模块内容
动态加载任意位置按需加载
导出
对象exportsmodule.exports
非对象module.exports
区别
CommonJS
运行时加载
ES Module
编译时加载 模块化规范一个模块实现特定功能的一组方法。
全局污染共享时同名变量冲突
依赖管理下层 js 能调用上层 js 的方法但是上层 js 无法调用下层 js 的方法 历程
1.几个函数全局变量的污染模块间没有联系
// 模块A
var ModuleA {func1: function() {// ...},func2: function() {// ...}
};// 模块B
var ModuleB {func3: function() {// ...}
};2.对象暴露成员外部可修改
后面提出了对象通过将函数作为一个对象的方法来实现但是这种办法会暴露所 有的所有的模块成员外部代码可以修改内部属性的值。
3.立即执行函数闭包实现模块私有作用域
现在最常用的是立即执行函数的写法通过利用闭包来实现模块私有作用域的建立同时不会对全局作用域造成污染。
//IIFE立即调用函数表达式
//创建一个私有作用域避免变量之间的冲突。然后通过返回一个对象或函数来暴露模块的公共部分
// 模块A
var ModuleA (function() {var privateVar private;function privateFunc() {// ...}return {publicVar: public,publicFunc: function() {// ...}};
})();common JS
module和Module
module在 commonjs 中每一个 js 文件都是一个单独的模块
module 上保存了 exports 等信息之外还有一个 loadedbool 表示该模块是否被加载。
Module 以 nodejs 为例整个系统运行之后会用 Module 缓存每一个module的信息。
过程
//home.js
const sayName require(./hello.js)
module.exports function say(){return {name:sayName(),}
}
//编译进行首尾包装
(function(exports,require,module,__filename,__dirname){const sayName require(./hello.js)module.exports function say(){return {name:sayName(),}}
})
//包装函数
function wrapper (script) {return (function (exports, require, module, __filename, __dirname) { script \n})
}
//runInThisContext
eavl(包装后的module)(module.exports, require, module, __filename, __dirname)模块依赖深度优先遍历、父 - 子 - 父
//a.js
const getMes require(./b)
console.log(我是 a 文件)
exports.say function(){const message getMes()console.log(message)
}
//b.js
const getMes require(./a)
console.log(我是 b 文件)
exports.say function(){const message getMes()console.log(message)
}
//main.js
const a require(./a)
const b require(./b)console.log(node 入口文件)const say require(./a)
console.log(我是 b 文件)
console.log(打印 a 模块 , say)setTimeout((){console.log(异步打印 a 模块 , say)
},0)exports.say function(){const message getMes()console.log(message)
}导入require
避免重复加载、循环引用Module缓存
先加入缓存 后执行模块内容
加载之后的文件的 module 会被缓存到 Module 上比如一个模块已经 require 引入了 a 模块如果另外一个模块再次引用 a 那么会直接读取缓存值 module 所以a中的代码只会执行一次
动态加载任意位置按需加载
require 本质上就是一个函数那么函数可以在任意上下文中执行来自由地加载其他模块的属性方法。
导出
对象exportsmodule.exports
当 module.exports 导出的是一个对象时对象的引用关系是被保留的这意味着其他模块引入这个对象后即使该对象后续被修改其他模块也能看到这些修改。这是因为对象在 JavaScript 中是引用类型它们的引用关系是保持的。
exports.author 7
exports.say function (){console.log(666)
}
module.exports {author:7,say(){console.log(666)}
}非对象module.exports
在循环引用的时候就容易造成属性丢失的情况发生
module.exports a // 导出变量module.exports [1,2,3] // 导出数组module.exports function(){} //导出方法区别
CommonJS
运行时加载
在服务器端同步加载模块的方式是可行的因为模块通常都在本地。
ES Module
编译时加载 ES模块的结构在编译时就确定下来模块的依赖关系在代码运行前就已经确定。静态导入导出方便 tree shaking
「万字进阶」深入浅出 Commonjs 和 Es Module - 掘金