当前位置: 首页 > news >正文

佛山网站建站推广淮南模板网站建设怎么样

佛山网站建站推广,淮南模板网站建设怎么样,实际网站开发怎样分工,直播平台推荐说到前端模块化#xff0c;就不得不说到循环加载#xff0c;就像混乱背后隐藏着的清晰地秩序。什么叫循环加载#xff1f;我们来看一段代码。12345678910111213const b require(./b);b();module.exports function(){console.log(This is a.js);}//b.jsconst a require(./…说到前端模块化就不得不说到循环加载就像混乱背后隐藏着的清晰地秩序。什么叫循环加载我们来看一段代码。12345678910111213const b require(./b);b();module.exports function(){console.log(This is a.js);}//b.jsconst a require(./a);a()module.exports function(){console.log(This is b.js)}a 加载了 bb 也加载了 a这个时候循环加载就出现了。CommonJS 下的循环加载运行 node a.js 你会发现报错了:123456789101112131415/Users/jackiels/learn/test/b.js:8a()^TypeError: a is not a functionat Object. (/Users/jackiels/learn/test/b.js:8:1)at Module._compile (module.js:571:32)at Object.Module._extensions..js (module.js:580:10)at Module.load (module.js:488:32)at tryModuleLoad (module.js:447:12)at Function.Module._load (module.js:439:3)at Module.require (module.js:498:17)at require (internal/module.js:20:19)at Object. (/Users/jackiels/learn/test/a.js:8:11)at Module._compile (module.js:571:32)为什么会报错我们来 console.log(a:,a)返回的结果显示 a 是一个{}。明明 module.exports 导出的是一个函数为什么就变成了一个空对象以下内容引自CommonJS 的加载原理CommonJS 的一个模块就是一个脚本文件。require 命令第一次加载该脚本就会执行整个脚本然后在内存生成一个对象。123456{id: ...,exports: { ... },loaded: true,...}上面代码中该对象的 id 属性是模块名exports 属性是模块输出的各个接口loaded 属性是一个布尔值表示该模块的脚本是否执行完毕。其他还有很多属性这里都省略了。以后需要用到这个模块的时候就会到 exports 属性上面取值。即使再次执行 require 命令也不会再次执行该模块而是到缓存之中取值。这个时候的 exports 那个字段的值就是 {}之所以这样因为 CommonJS 中非常重要的一个加载模式一旦出现某个模块被”循环加载”就只输出已经执行的部分还未执行的部分不会输出我们回头看看我们的栗子执行 a.jsa 里面require(./b)所以去执行 b.jsb.js 里面require(./a)循环加载出现所以 a.js 会输出已执行的部分a.js 执行完 require(b.js) 之后什么也没做所以 a.js 相当于只是生成了一个 module 对象所以 b.js 继续执行。想深入研究 module 对象看这个这时候 a.js 的 exports 是一个刚刚初始化的对象什么内容都没有所以报错了a is not a function。怎样可以正确运行我们把 a.js 改一下在运行一次。123456module.exports function(){console.log(This is a.js);}const b require(./b);b();运行结果可以正常执行12This is aThis is b再来看看执行流程执行 a.jsmodule.exports function(){...}先定义了module.exports执行require(./b)进入 b.js执行require(./a)循环加载出现所以 a.js 输出已执行的部分a.js 已执行的部分是module.exports function(){...}所以这时候 b.js 中的变量 a 等于function(){...}a()输出This is a.js继续执行 b 里面的module.exports function(){...}b.js 执行完毕回到 a.jsa.js 中的变量 b 等于module.exports function(){...}b()输出 This is b.js 执行完毕整个的流程是一个 程序执行栈先进后出。再看一个官方的栗子123456console.log(a starting);exports.done false;const b require(./b.js);console.log(in a, b.done %j, b.done);exports.done true;console.log(a done);b.js:123456console.log(b starting);exports.done false;const a require(./a.js);console.log(in b, a.done %j, a.done);exports.done true;console.log(b done);main.js:1234console.log(main starting);const a require(./a.js);const b require(./b.js);console.log(in main, a.done%j, b.done%j, a.done, b.done);运行如下123456789$ node main.jsmain startinga startingb startingin b, a.done falseb donein a, b.done truea donein main, a.donetrue, b.donetrue运行过程详解如下(---表示在哪个文件之中)12345678910111213---main require(a) 执行后会直接运行 a 脚本---a exports.done false---a require(b) 执行后会直接运行 b 脚本---b exports.done false---b require(a) 执行后出现循环加载a 模块只会输出已运行的部分, exports.done false 这时候 b.js 中的 a { done:false }---b console.log( 在 b.js 之中a.done %j, a.done); 在 b.js 之中a.done false---b exports.done true;---b console.log(b.js 执行完毕 ) 开始继续执行 a---a console.log( 在 a.js 之中b.done %j, b.done); 这时候b 输出已运行的部分exports.done true这时候 a.js 中的 b { done: true }---a exports.done true;---a console.log(a.js 执行完毕 );---main require(b.js)因为 b.js 在之前已经被 a 执行完了所以相当于内存中的 loaded 已经为 true 了所以不会去在执行一次 b.js 而是直接取到它输出的结果 b { done:true }---main console.log( 在 main.js 之中, a.done%j, b.done%j, a.done, b.done); 在 main.js 之中, a.donetrue, b.donetrue我前面说过程序执行栈用栈的思路捋一下就是执行 main— requrire(a)进栈— 执行 a 并保存结果— require(b) 进栈— 执行 b 并保存结果— require(a),a 已在内存中取当前 a 执行结果— b 执行完毕并保存结果出栈— 执行 a 并保存结果— a 执行完毕并保存结果出栈— 执行 main— require(b),b 已在内存中取当前 b 执行结果— 程序结束以上例子的执行结果都表现出以下两个重点require 命令第一次加载该脚本就会执行整个脚本然后在内存生成一个对象出现某个模块被”循环加载”就只输出已经执行的部分还未执行的部分不会输出ES6 Module 下的循环加载我们来看个代码1234567891011121314// a.jsimport {bar} from ./b.js;export function (){console.log(在 a.js)bar();}foo() // 启动循环加载//b.jsimport {foo} from ./a.js;export function bar(){console.log(在 b.js)foo();}执行这段代码不久之后你就会发现内存爆了。1234567891011RangeError: Maximum call stack size exceededat process.get [as domain] (domain.js:22:16)at process.nextTick (internal/process/next_tick.js:156:22)at onwrite (_stream_writable.js:372:15)at WriteStream.Socket._writeGeneric (net.js:734:5)at WriteStream.Socket._write (net.js:744:8)at doWrite (_stream_writable.js:329:12)at writeOrBuffer (_stream_writable.js:315:5)at WriteStream.Writable.write (_stream_writable.js:241:11)at WriteStream.Socket.write (net.js:671:40)at Console.log (console.js:43:16)WTF我们用 babel 编译一下看看结果a.js 编译之后123456789101112131415;Object.defineProperty(exports, __esModule, {value: true});exports.foo foo;var _b require(./b.js);function (){console.log(在 a.js);(0, _b.bar)(); // 这个语法目的是绑定 bar 的 this 为当前这个 modulebabel 编译的结果与本文关系不大耻略} // a.jsfoo(); // 启动循环加载b.js 编译之后12345678910111213;Object.defineProperty(exports, __esModule, {value: true});exports.bar bar;var _a require(./a.js);function bar(){console.log(在 b.js);(0, _a.foo)();}我们可以清晰地看到所有对函数的执行都是引用方式的相当于就是两个函数互相调用导致了死循环。所以得出一个结论在 ES6 中不会出现所谓的“循环加载”只是会有循环调用而且这种循环调用也是因为写代码的人的思维短路造成的所以我们根本我不用担心循环加载只需要注意自己写代码的逻辑就好了。参考资料
http://www.zqtcl.cn/news/711357/

相关文章:

  • 有什么在线做文档的网站网站开发需要用到哪些技术
  • 网站套餐可以分摊吗吗移动登录网页模板免费下载
  • asp网站会员注册不了但是打不开网页
  • wordpress 中文网店杭州排名优化公司
  • wordpress建站安全吗wordpress企业主题教程
  • 网站构建的开发费用信息管理系统网站开发教程
  • 自己做网站怎么维护wordpress素材模板
  • 如何选择一个好的优质网站建设公司wordpress 主题小工具
  • mysql数据库做网站广州网站seo地址
  • 福建省住房和城乡建设厅网站电话网站开发项目步骤
  • 网站注册域名多少钱淘宝网商城
  • 做架构图的网站网站和网店的区别
  • 做红包网站简单个人网站设计
  • 新手学做网站pdf手wordpress修改搜索框
  • 做湲兔费网站视颍如何通过查询网站注册时间
  • 重庆cms建站模板南通网站建设推广优化
  • 合肥网站建设的公司新闻类网站如何做量化统计
  • 好用的在线地图网站十六局集团门户网
  • 网站开发数据库连接失败广州网站建站平台
  • 鄂尔多斯北京网站建设加盟网站建设的内容
  • 网站 被 抄袭不属于营销型网站的特点
  • 浙江英文网站建设互联网公司排名2021完整版
  • 完美代码的网站python开发工具
  • 餐饮网站开发参考文献网站建设500错误代码
  • 网站开发关键技术网站自动推广软件免费
  • 前端学习网站南阳东莞网站建设公司哪家好
  • 关于做网站的了解点wordpress小程序插曲
  • PHP网站开发与管理设计心得个人可以做聊天网站备案吗
  • 开公司可以在哪些网站做推广上海画册设计
  • 成都高新区规划建设局网站网络营销方式有哪些?举例说明