JavaScript 入门微单相机哪款最好哪本书最好

> JavaScript 入门哪本书最好?
JavaScript 入门哪本书最好?
入门:《深入浅出JavaScript》《JavaScript DOM编程艺术》《JavaScript DOM高级程序设计》进阶:《ppk谈JavaScript》《精通JavaScript》《JavaScript高级程序设计》高级:《JavaScript语言精粹》《JavaScript设计模式》《Secrets of the JavaScript Ninja》《高性能JavaScript》有的人说犀牛书 入门经典 ,犀牛书不适合入门,各位大神怎么看还有javascript编程全解这本书适合JS入门学习吗?还好的求推荐好盲目我看司徒正美大神 在知乎推荐的是《javascript高级程序设计》《javascript dom 编程艺术》《javascript语言精辟》《PPK 谈 Javascript》《JavaScript DOM高级程序设计》等等JavaScript DOM高级程序设计 这本书感觉有点早,里面说的东西会不会有时效性的问题……求解啊
入门:《深入浅出JavaScript》《JavaScript DOM编程艺术》《JavaScript DOM高级程序设计》进阶:《ppk谈JavaScript》《精通JavaScript》《JavaScript高级程序设计》高级:《JavaScript
------分隔线----------------------------
相关阅读排行
相关最新文章
Copyright 2012- ( Coin163 ) All Rights Reserved &&javascript新手入门必读javascript权威指南 书籍推荐
更新时间:15-06-25 00:15
在当下,极多的圭表员是经过自学来完成入门以及提拔的。对待jaudio-videowhereascript的练习来说,异样不例外。javascript学习指南。许多老手入门jaudio-videowhereascript拔取经过视频教程或者论坛交换的方式举办练习,这种方式当然较为紧张和便利,但在常识的获取上有些碎片化,javascript实例教程。对待老手来说不是很好。
在jaudio-videowhereascript的入门阶段,经过书籍来练习对待老手来说才是最好的手段。听听新手入门。书籍的练习当然较量单调,。事实上java教程。但是也是最权势巨子,看着flash插件。最编制化的,对待老手来说能够急迅的完成基础常识的奠基,而对待之后进一步的提拔也是大有裨益。学习必读。这里笔者就联结自身体会为各位jaudio-videowhereascript老手推选几本不容错过的jaudio-videowhereascript书籍。
看完之后根基就能够完成一个老手到入门的历程了,能够职掌JS基础语法常识和DOM基础常识,javascript教程下载。读懂接上去笔者推选的初级书籍。
《Jaudio-videoaScriptDom编程艺术》
此书从JS的历史到JS基础语法常识再到M先容和简易的操纵都较量详细,听说书籍。形式对待老手来说,javascript入门经典。简便、适用、详细、易懂。想知道javascript。书不厚,信任很快就能看完。
《Jaudio-videoaScript权势巨子指南》
听名字就知道十分健壮。事实上javascript新手入门必读javascript权威指南。网上关于此书的评价很多,javascript软件下载。意见意义简略都是说这书就是一个JS的文档手册。假若练习,记得看最新一版的形式。javascript新手入门必读javascript权威指南。
js讲话有别于保守面向对象讲话,所以还是从基础开始看起较量好。以上两本了局之后,就能够来看一些初级的了。javascript学习指南。这里笔者对初级的定义为“能在中级和初级开导的指使下完成办事。”
笔者对初级的定义为“能在中级和初级开导的指使下完成办事。”相比于入门书籍,在眷注基础常识的同时,malicious javascript。开始讲述一些较为深切的东西。javascript实例教程。在这个阶段,对比一下css权威指南。适当的书有以下几本。css权威指南。
《Jaudio-videoaScript初级圭表设计》
此书的作者是NicholwhereasC.Zwoulsso cjusteds.雅虎的前端工程师,YUI的代码劳绩者,本书的含金量不问可知,本相上他出的书也确凿广受好评,其实jquery。拥簇者众多。看着推荐。
阅读本书只须有JS基础语法常识和DOM基础常识就行,指南。而且本书开始阶段还是先容JS和DOM的语法常识。javascript void 0。笔者这里重点推选一下第五章(类型).第六章(OOP).第七章(匿名).私人感到这几章是本书的精彩所在,多看几遍.至多要完全看明白,能为自此进阶打好基础。
《高本能机能Jaudio-videoaScript》
这 本书还是NicholwhereasC.Zwoulsso cjusteds所著,javascript语言精粹。典范之作,书中大宗举例了各种不同写法的Jaudio-videoaScript在涉猎器中的本能机能情形,书籍推荐。对典范榜样Jaudio-videoaScript代码和提拔本能机能有很好的帮忙,末了提到了很多工具和本能机能测试的要领,都是很是有现实作用的,对比一下权威。更加对待初学者来说,看完后提拔成果清楚明明。
《Jaudio-videoaScript讲话精华与编程践诺》
本书与下面的那本在形式上有些堆叠,看看java教程。但照旧值得一看。由于本书对JS讲话性质的形貌很是到位,书籍推荐。能够说是先容Jaudio-videoaScript讲话性质的权势巨子书籍,从“对象”,“函数”,“承受”,flash插件。“数组”等等多个要紧常识着手,高性能javascript。多看几遍,每一遍都会有新成就。
笔者对中级的定义为“能独立或在较少的指使下完成办事,javascript权威指南。并且对产品与项目有本身的主张。javascript教程 pdf。”这个阶段的书籍深切且庞杂,要耐烦的思索本领读懂,当然得到的提拔不问可知。
《Jaudio-videoaScriptDOM初级圭表设计》
本书的翻译日常,javascript。代码也有少许差池,可是这不影响这本书的健壮,经过练习本书,能够清楚一个JS的库如何发作,本身下手写一个简易的本身的JS库
,假若你谋略研究其他的JS库或者正在研究其他的JS库,那么这本书会使你的清楚抵达新的高度,进阶初级必读,写库必读。
《Jaudio-videoaScript设计形式》
本书对JS的“师法接口”,“封装”,“承受”,“链式调用”,“工厂形式”等各种实在的设计形式及其在Jaudio-videoaScript讲话中的应用举办了详细的先容,运用设计形式使代码更模块化、更高效并且更易维持。
以上的书籍是一个从基础到入门,从入门的提拔的历程,也是笔者的体会总结。对待老手入门jaudio-videowhereascript来说,自以为帮忙不小,能够少走一些弯路。对待讲话职掌其实是一个无止尽的历程,没有止境。假使在你职掌了较为深切的水平后,笔者照旧提议去回过头来重新阅读这些书籍,一定还会有新的成就。
你可能会嗜好:像高手请教一本javascript脚本语言 的入门级的书_百度拇指医生
&&&网友互助
?像高手请教一本javascript脚本语言 的入门级的书
拇指医生提醒您:该问题下为网友贡献,仅供参考。
JavaScript权威指南(第五版) 这本书不错你用心去看个几遍的话 会收获不少的。另外javascript没有什么所谓入门级的概念。掌握它就是掌握它。没掌握就是没掌握。至于你要写出一些很功能很强大的代码有基础后就没问题了
向医生提问
完善患者资料:*性别:
为您推荐:
* 百度拇指医生解答内容由公立医院医生提供,不代表百度立场。
* 由于网上问答无法全面了解具体情况,回答仅供参考,如有必要建议您及时当面咨询医生不要慌! 秒后将自动返回IT之家首页,请稍候...学习JavaScript必读的12本书 - 知乎专栏
{"debug":false,"apiRoot":"","paySDK":"/api/js","wechatConfigAPI":"/api/wechat/jssdkconfig","name":"production","instance":"column","tokens":{"X-XSRF-TOKEN":null,"X-UDID":null,"Authorization":"oauth c3cef7c66aa9e6a1e3160e20"}}
{"database":{"Post":{"":{"title":"学习JavaScript必读的12本书","author":"yubolun","content":"原文链接:作者:我巨喜欢读有关JavaScript的书。在学习JS的很长一段时间里,我读了特别多市面上广受欢迎的JavaScript书籍。最近我不再读一些写给菜鸟的书了,但我仍然会翻阅许多写给初阶JS开发者的书。其实目前是个非常尴尬的时间段,因为ES6的推出,JS在语法上与以往有了很大的改变,而很大一部分书的内容还停留在ES3-ES5的阶段。不过好在ES6仅是ES5的一个超集而已,大多数的经典书目对学习JS还是很有帮助的。换句话讲,这些经典书目并没有过时,只是附加了一份历史感。对于刚刚接触JS的同学来讲,阅读这些书籍的同时也能领略一番JS的历史。一些JS社区的作者已经开始撰写教你ES6的书了。不过我还是建议你在阅读这些书籍之前先掌握一些JS的基础。要是你看到这儿还不知道我说的ES6是什么的话,请戳。下面的推荐列表基本是按照循序渐进的学习顺序排列的:书目推荐:1. by Nick MorganJavaScript是Internet的语言,是创建令人惊讶的Web、你喜欢的站点交互和在线游戏的秘密武器。 《趣学JavaScript 教孩子学编程》用轻松愉快的方式,通过耐心的、按部就班的示例,以及充满乐趣的图示,帮助读者轻松地学习编程基础知识。全书共16章,从基础知识开始,详细介绍了操作字符串、数组以及循环,然后继续学习一些高级话题,如使用jQuery构建交互性,以及使用画布绘图等。本书通过教授编写一些简单有趣的游戏,帮助读者掌握JavaScript编程。每一章都构建于上一章的基础之上,并且每章末尾的编程挑战能够激发读者更多的思考和学习兴趣。 《趣学JavaScript 教孩子学编程》针对任何想要学习JavaScript或初次接触编程的人。本书针对儿童学习JavaScript量身定做,但也适合作为不同年龄的初学者的第1本编程图书。2. by Marijn Haverbeke如果你只想阅读一本关于JavaScript的图书,那么本书应该是你的首选。本书由世界级JavaScript程序员撰写,JavaScript之父和多位JavaScript专家鼎力推荐。本书适合作为系统学习JavaScript的参考书,它在写作思路上几乎与现有的所有同类书都不同,打破常规,将编程原理与运用规则完美地结合在一起,而且将所有知识点与一个又一个经典的编程故事融合在一起,读者可以在轻松的游戏式开发中学会JavaScript程序设计,趣味性十足,可操作性极强。 全书一共12章:第1~3章介绍了JavaScript的基本语法,旨在帮助读者编写出正确的JavaScript程序,包含数字、算术、字符串、变量、程序结构、控制流程、类型、函数、对象和数组等最基础和最核心的内容;第4~7章讲解了JavaScript编程中的高级技术,目的是帮助读者编写更复杂的JavaScript程序,主要涉及错误处理、函数式编程、面向对象编程、模块化等重要内容;第8~12章则将重心转移到JavaScript环境中可用的工具上,分别详细讲解了正则表达式、与Web编程相关的知识、文档对象模型、浏览器事件和HTTP请求等。3. by Douglas CrockfordJavaScript 曾是“世界上最被误解的语言”,因为它担负太多的特性,包括糟糕的交互和失败的设计,但随着Ajax 的到来,JavaScript“从最受误解的编程语言演变为最流行的语言”,这除了幸运之外,也证明了它其实是一门优秀的语言。Douglas Crockford 在本书中剥开了JavaScript 沾污的外衣,抽离出一个具有更好可靠性、可读性和可维护性的JavaScript 子集,让你看到一门优雅的、轻量级的和非常富有表现力的语言。作者从语法、对象、函数、继承、数组、正则表达式、方法、样式和优美的特性这9 个方面来呈现这门语言真正的精华部分,通过它们完全可以构建出优雅高效的代码。作者还通过附录列出了这门语言的毒瘤和糟粕部分,且告诉你如何避免它们。最后还介绍了JSLint,通过它的检验,能有效地保障我们的代码品质。 这是一本介绍 JavaScript 语言本质的权威书籍,值得任何正在或准备从事JavaScript 开发的人阅读,并且需要反复阅读。学习、理解、实践大师的思想,我们才可能站在巨人的肩上,才有机会超越大师,这本书就是开始。4. by Eric Elliott (原作者本人)在我刚开始招聘JS开发者开发应用的时候,我发现许多人根本不知道怎么驾驭JS来构建健壮的应用架构。所以我就决定写一本有关JS最佳实践、原型、对象聚合,和一些基本的函数式编程概念(这些知识足够你了解如何开发维护一个典型的JS应用),然后讲解了如何运用上述的知识解决大多数应用中都会出现的一些通共性问题。很多书都在回答“如何使用JS?”的问题,而我在这本书中要回答的是“如何用JS来开发真正的应用?”虽然近两年内技术发展迅猛,但客观来讲,这本书依旧能够带给你一个有关JS应用架构的完整而直观的概念。同时也能加深你对JS的理解,学习基础的Node,RESTful API,权限和验证,功能切换系统,日志记录等等……5. by David Herman《Effective JavaScript:编写高质量JavaScript代码的68个有效方法》内容简介:Effective系列丛书经典著作,亚马逊五星级畅销书,Ecma的JavaScript标准化委员会著名专家撰写,JavaScript语言之父、Mozilla CTO Brendan Eich作序鼎力推荐!作者凭借多年标准化委员会工作和实践经验,深刻辨析JavaScript的内部运作机制、特性、陷阱和编程最佳实践,将它们高度浓缩为极具实践指导意义的68条精华建议。 《Effective JavaScript:编写高质量JavaScript代码的68个有效方法》共分为7章,分别涵盖JavaScript的不同主题。第1章主要讲述最基本的主题,如版本、类型转换要点、运算符注意事项和分号局限等。第2章主要讲解变量作用域,介绍此方面的一些基本概念,以及一些最佳实践经验。第3章主要讲解函数的使用,深刻解析函数、方法和类,并教会读者在不同的环境下高效使用函数。第4章主要讲解原型和对象,分析JavaScript的继承机制以及原型和对象使用的最佳实践和原则。第5章主要介绍数组和字典,阐述将对象作为集合的用法以及使用数组和字典的一些陷阱。第6章介绍库和API,讲解如何设计良好的API的技巧,以清楚、简洁和明确地表达程序,并提高可重用率。第7章讲解并发,在技术上讨论一些“约定成俗”的JavaScript用法。6. by David Flanagan这就是JS程序员的《圣经》。《JavaScript权威指南(第6版)》讲述的内容涵盖JavaScript语言本身,以及Web浏览器所实现的JavaScriptAPI。本书涵盖了HTML5和ECMAScript5,很多章节完全重写,增加了当今Web开发的实践内容,新增的章节包括jQuery、服务器端JavaScript、图形编程以及JavaScript式的面向对象。本书不仅适合初学者系统学习,也适合有经验的JavaScript开发者随手翻阅。7. by Kyle Simpson很多人对JavaScript这门语言的印象都是简单易学,很容易上手。虽然JavaScript语言本身有很多复杂的概念,但语言的使用者不必深入理解这些概念就可以编写出功能全面的应用。殊不知,这些复杂精妙的概念才是语言的精髓,即使是经验丰富的JavaScript开发人员,如果没有认真学习的话也无法真正理解它们。在本书中,我们要直面当前JavaScript开发者“不求甚解”的大趋势,深入理解语言内部的机制。 《你不知道的JavaScript(上卷)》既适合JavaScript语言初学者阅读,又适合经验丰富的JavaScript开发人员深入学习。你不知道的JavaScript是一套系列丛书,中文版目前只出版了上卷和中卷,这里给出的链接是上卷,如果你对这套丛书感兴趣,可以在上找到原版全集。8. by Reginald BraithwaiteJavaScript Allongé 主要讲解了JS的函数,以及如何运用精炼,解耦的单元构建灵活的应用。本书会尽量不表现出先入为主和自以为是的概念,书中的介绍说:JavaScript Allongé 并不是一本在软件开发的广义上介绍最佳实践的书,不偏重实践,而是更加偏向于思维方式。本书当然不是一本入门书籍。Reginald 在书中通过一些简单的例如 const 的概念深入浅出地讲解了诸如IIFE(立即执行函数)和闭包一类进阶的函数作用域,以及函数柯里化等内容。大多数的入门书籍都会从变量以及如何通过var,let,const定义变量开始。而本书直接跳过了这些,为你让你充分地调动大脑,来重新并深入地理解函数及其作用。最好在你已经熟悉了JS,并且掌握了面向对象的编程方法之后再来阅读本书。9. by Brian Lonsdorf本书在Github上开源,可以免费下载,还没写完但值得一读。聪明人都知道,学习函数式编程是很困难的。我自己学了很久也只感觉掌握了皮毛而已(并且这种永远只是略懂的感觉一直挥之不去)。幸运的是,这是一本非常好的教程。函数式编程的概念里充满着诸如函数演算、代数、范畴论一类的术语。这些装逼的词汇一下就把人给忽悠瘸了。而本书的内容却生动而活泼。要是所有的编程书都能像这本一样有趣该多好。这是一本会让你手不释卷,乐在其中的计算机科学类书籍。10. by by Mike Cantelon, Marc Harter, TJ Holowaychuk, and Nathan Rajlich服务器端JavaScript?没错。Node.js是一个JavaScript服务器,支持可伸缩的高性能Web应用。借助异步I/O,这个服务器可以同时做很多事情,能满足聊天、游戏和实时统计等应用的需求。并且既然是JavaScript,那你就可以全栈使用一种语言。 本书向读者展示了如何构建产品级应用,对关键概念的介绍清晰明了,贴近实际的例子,涵盖从安装到部署的各个环节,是一部讲解与实践并重的优秀著作。通过学习本书,读者将深入异步编程、数据存储、输出模板、读写文件系统,掌握创建TCP/IP服务器和命令行工具等非HTTP程序的技术。本书同样非常适合熟悉Rails、Django或PHP开发的读者阅读学习。 本书主要内容: Node.js及其扩展的安装配置; 全面理解异步编程和事件循环; 学会开发微博、聊天和游戏等热门应用。11. by Ilya Grigorik本书是谷歌公司高性能团队核心成员的权威之作,堪称实战经验与规范解读完美结合的产物。本书目标是涵盖Web 开发者技术体系中应该掌握的所有网络及性能优化知识。全书以性能优化为主线,从TCP、UDP 和TLS 协议讲起,解释了如何针对这几种协议和基础设施来优化应用。然后深入探讨了无线和移动网络的工作机制。最后,揭示了HTTP 协议的底层细节,同时详细介绍了HTTP 2.0、 XHR、SSE、WebSocket、WebRTC 和DataChannel 等现代浏览器新增的具有革命性的新能力。 本书适合所有Web 应用及站点开发人员阅读,包括但不限于前端、后端、运维、大数据分析、 UI/UX、存储、视频、实时消息,以及性能工程师。 Ilya Grigorik 是谷歌“Web加速”(Make The Web Fast)团队的性能工程师、开发大使。他每天的主要工作就是琢磨怎么让Web应用速度更快,总结并推广能够提升应用性能的最佳实践。12. by Boris Smus本书不在必读书目内,完全是原作者的个人癖好每一个真正的JS摇滚之星都需要这本书。虽然你需要其实是一把吉他。我知道我又不小心标题党了,不过你要是喜欢玩弄音频和音乐的话,这本书会对你很有帮助。要是你不感兴趣请直接无视。介绍这本书完全出于我个人对音乐和音频开发的癖好。Web 音频API是一套通过Web平台标准来操作和生成音频的系统。在浏览器和Node上都可以使用。本书介绍的主要内容包括如何通过JS操作音频、添加音频特效以及音频视觉化等。我个人觉得蛮有趣的。译者推荐书单基本都是我看过的,没看过不会乱推荐的。(这本是评论区里竟然没有的高级程序设计)","updated":"T16:23:24.000Z","canComment":false,"commentPermission":"anyone","commentCount":32,"collapsedCount":0,"likeCount":351,"state":"published","isLiked":false,"slug":"","lastestTipjarors":[{"isFollowed":false,"name":"马磊","headline":"","avatarUrl":"/69e74b3f5_s.jpg","isFollowing":false,"type":"people","slug":"ma-lei-83-10-36","bio":null,"hash":"65ecdffea2fca9bd1666226","uid":80,"isOrg":false,"description":"","profileUrl":"/people/ma-lei-83-10-36","avatar":{"id":"69e74b3f5","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false}],"isTitleImageFullScreen":true,"rating":"none","titleImage":"/v2-486b5208dcaf9bdeacf4_r.jpg","links":{"comments":"/api/posts//comments"},"reviewers":[],"topics":[{"url":"/topic/","id":"","name":"JavaScript"},{"url":"/topic/","id":"","name":"Web 开发"},{"url":"/topic/","id":"","name":"前端开发"}],"adminClosedComment":false,"titleImageSize":{"width":1440,"height":1080},"href":"/api/posts/","excerptTitle":"","column":{"slug":"icode","name":"从零学习前端开发"},"tipjarState":"activated","tipjarTagLine":"好好学习,天天向上","sourceUrl":"","pageCommentsCount":32,"tipjarorCount":1,"annotationAction":[],"hasPublishingDraft":false,"snapshotUrl":"","publishedTime":"T00:23:24+08:00","url":"/p/","lastestLikers":[{"bio":"前端程序员","isFollowing":false,"hash":"f64d323ccd6f858ea9a0","uid":401700,"isOrg":false,"slug":"super456","isFollowed":false,"description":"我们程序员为什么写代码?不是为了实现功能,而是为了创造一个世界,为了做 creator,体验在自己创造的世界里做上帝的感觉。","name":"猿来缘往","profileUrl":"/people/super456","avatar":{"id":"v2-ac26df8e6dbf00e623ba15","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":null,"isFollowing":false,"hash":"ecd","uid":870100,"isOrg":false,"slug":"yong-yuan-hong-lu-18","isFollowed":false,"description":"","name":"Ginsusutake","profileUrl":"/people/yong-yuan-hong-lu-18","avatar":{"id":"da8e974dc","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":null,"isFollowing":false,"hash":"05b8c88b86dad461b34563b","uid":110400,"isOrg":false,"slug":"mu-xiao-mu-24-30","isFollowed":false,"description":"","name":"木小沐","profileUrl":"/people/mu-xiao-mu-24-30","avatar":{"id":"da8e974dc","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":null,"isFollowing":false,"hash":"e56d38b74e467fa70c6cc16fffa134c0","uid":24,"isOrg":false,"slug":"funnytiger","isFollowed":false,"description":"","name":"ming ni","profileUrl":"/people/funnytiger","avatar":{"id":"317b64cc9","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"开发工程师","isFollowing":false,"hash":"f5f8abfe2d65ba1bd2d426a","uid":002100,"isOrg":false,"slug":"mryi-52","isFollowed":false,"description":"","name":"MrYi","profileUrl":"/people/mryi-52","avatar":{"id":"0113eafccc5e10df2ab3","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false}],"summary":"原文链接:作者:我巨喜欢读有关JavaScript的书。在学习JS的很长一段时间里,我读了特别多市面上广受欢迎的JavaScript书籍。最近我不再读一些写给菜鸟的书了,但我仍然会翻阅许多写给初阶JS开…","reviewingCommentsCount":0,"meta":{"previous":{"isTitleImageFullScreen":false,"rating":"none","titleImage":"/v2-ad547e666f72dc8cd9ffbf_r.jpg","links":{"comments":"/api/posts//comments"},"topics":[{"url":"/topic/","id":"","name":"JavaScript"},{"url":"/topic/","id":"","name":"前端入门"},{"url":"/topic/","id":"","name":"前端工程师"}],"adminClosedComment":false,"href":"/api/posts/","excerptTitle":"","author":{"bio":"少刷知乎多看书","isFollowing":false,"hash":"83a3b10a446f936a77f07f78870b5eec","uid":96,"isOrg":false,"slug":"yubolun","isFollowed":false,"description":"我已委托“维权骑士”()为我的文章进行维权行动。","name":"余博伦","profileUrl":"/people/yubolun","avatar":{"id":"v2-06d97a62e029d46d754eb716bc81b231","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},"column":{"slug":"icode","name":"从零学习前端开发"},"content":"原文链接: 作者:声明:转载请私信联系,转载请注明出处。作为一名JS初学者。假如你听到了一些诸如“模块化构建&模块化载入” “Webpack&Browserify” 或者 “AMD&CMD”之类的术语,肯定瞬间就凌乱了。JavaScript的模块化听起来挺深奥,可其实理解它对开发者来说特别实用。在这篇文章里,我会尽量深入浅出地把这些深奥的术语翻译成浅显易懂的人话(加上一些代码示例)。希望你多少能从中学到点东西。为了避免长篇大论,整个内容会分为两篇文章,这是第一部分,主要介绍模块化是什么,为什么要使用模块。之后的第二部分会介绍如何打包JS模块,以及各类构建工具。求解释到底什么是模块化称职的作家会把他的书分章节和段落;好的程序员会把他的代码分成模块。就好像书籍的一章,模块仅仅是一坨代码而已。好的代码模块分割的内容一定是很合理的,便于你增加减少或者修改功能,同时又不会影响整个系统。为什么要使用模块模块化可以使你的代码低耦合,功能模块直接不相互影响。我个人认为模块化主要有以下几点好处:1.可维护性:根据定义,每个模块都是独立的。良好设计的模块会尽量与外部的代码撇清关系,以便于独立对其进行改进和维护。维护一个独立的模块比起一团凌乱的代码来说要轻松很多。2.命名空间:在JavaScript中,最高级别的函数外定义的变量都是全局变量(这意味着所有人都可以访问到它们)。也正因如此,当一些无关的代码碰巧使用到同名变量的时候,我们就会遇到“命名空间污染”的问题。这样的问题在我们开发过程中是要极力避免的。后面的内容里我也会举一些具体的例子来说明这一点。3.可复用性:现实来讲,在日常工作中我们经常会复制自己之前写过的代码到新项目中。复制粘贴虽然很快很方便,但难道我们找不到更好的办法了么?要是……有一个可以重复利用的模块岂不妙哉?如何引入模块引入模块有很多种方式,这里我们先介绍一些:模块模式模块模式一般用来模拟类的概念(因为原生JavaScript并不支持类,虽然最新的ES6里引入了Class不过还不普及)这样我们就能把公有和私有方法还有变量存储在一个对象中——这就和我们在Java或Python里使用类的感觉一样。这样我们就能在公开调用API的同时,仍然在一个闭包范围内封装私有变量和方法。实现模块模式的方法有很多种,下面的例子是通过匿名闭包函数的方法。(在JavaScript中,函数是创建作用域的唯一方式。)例1:匿名闭包函数(function () {\n
// 在函数的作用域中下面的变量是私有的\n\n
var myGrades = [93, 95, 88, 0, 55, 91];\n\n
var average = function() {\n
var total = myGrades.reduce(function(accumulator, item) {\n
return accumulator + item}, 0);\n\n
return 'Your average grade is ' + total / myGrades.length + '.';\n
var failing = function(){\n
var failingGrades = myGrades.filter(function(item) {\n
return item & 70;});\n\n
return 'You failed ' + failingGrades.length + ' times.';\n
console.log(failing());\n\n}());\n\n// 控制台显示:'You failed 2 times.'\n通过这种构造,我们的匿名函数有了自己的作用域或“闭包”。 这允许我们从父(全局)命名空间隐藏变量。这种方法的好处在于,你可以在函数内部使用局部变量,而不会意外覆盖同名全局变量,但仍然能够访问到全局变量,如下所示:var global = 'Hello, I am a global variable :)';\n\n(function () {\n
// 在函数的作用域中下面的变量是私有的\n\n
var myGrades = [93, 95, 88, 0, 55, 91];\n\n
var average = function() {\n
var total = myGrades.reduce(function(accumulator, item) {\n
return accumulator + item}, 0);\n\n
return 'Your average grade is ' + total / myGrades.length + '.';\n
var failing = function(){\n
var failingGrades = myGrades.filter(function(item) {\n
return item & 70;});\n\n
return 'You failed ' + failingGrades.length + ' times.';\n
console.log(failing());\n
console.log(global);\n}());\n\n// 控制台显示:'You failed 2 times.'\n// 控制台显示:'Hello, I am a global variable :)'\n要注意的是,一定要用括号把匿名函数包起来,以关键词function开头的语句总是会被解释成函数声明(JS中不允许没有命名的函数声明),而加上括号后,内部的代码就会被识别为函数表达式。其实这个也叫作立即执行函数(IIFE)感兴趣的同学可以例2:全局引入另一种比较受欢迎的方法是一些诸如jQuery的库使用的全局引入。和我们刚才举例的匿名闭包函数很相似,只是传入全局变量的方法不同:(function (globalVariable) {\n\n
// 在函数的作用域中下面的变量是私有的\n
var privateFunction = function() {\n
console.log('Shhhh, this is private!');\n
// 通过全局变量设置下列方法的外部访问接口\n
// 与此同时这些方法又都在函数内部\n\n
globalVariable.each = function(collection, iterator) {\n
if (Array.isArray(collection)) {\n
for (var i = 0; i & collection.length; i++) {\n
iterator(collection[i], i, collection);\n
} else {\n
for (var key in collection) {\n
iterator(collection[key], key, collection);\n
globalVariable.filter = function(collection, test) {\n
var filtered = [];\n
globalVariable.each(collection, function(item) {\n
if (test(item)) {\n
filtered.push(item);\n
return filtered;\n
globalVariable.map = function(collection, iterator) {\n
var mapped = [];\n
globalUtils.each(collection, function(value, key, collection) {\n
mapped.push(iterator(value));\n
return mapped;\n
globalVariable.reduce = function(collection, iterator, accumulator) {\n
var startingValueMissing = accumulator === undefined;\n\n
globalVariable.each(collection, function(item) {\n
if(startingValueMissing) {\n
accumulator = item;\n
startingValueMissing = false;\n
} else {\n
accumulator = iterator(accumulator, item);\n
return accumulator;\n\n
};\n\n }(globalVariable));\n在这个例子中,globalVariable 是唯一的全局变量。这种方法的好处是可以预先声明好全局变量,让你的代码更加清晰可读。例3:对象接口像下面这样,还有一种创建模块的方法是使用独立的对象接口:var myGradesCalculate = (function () {\n\n
// 在函数的作用域中下面的变量是私有的\n
var myGrades = [93, 95, 88, 0, 55, 91];\n\n
// 通过接口在外部访问下列方法\n
// 与此同时这些方法又都在函数内部\n\n
return {\n
average: function() {\n
var total = myGrades.reduce(function(accumulator, item) {\n
return accumulator + item;\n
}, 0);\n\n
return'Your average grade is ' + total / myGrades.length + '.';\n
failing: function() {\n
var failingGrades = myGrades.filter(function(item) {\n
return item & 70;\n
return 'You failed ' + failingGrades.length + ' times.';\n
}\n})();\n\nmyGradesCalculate.failing(); // 'You failed 2 times.' \nmyGradesCalculate.average(); // 'Your average grade is 70.33.'\n例4:揭示模块模式 Revealing module pattern这和我们之前的实现方法非常相近,除了它会确保,在所有的变量和方法暴露之前都会保持私有:var myGradesCalculate = (function () {\n\n
// 在函数的作用域中下面的变量是私有的\n
var myGrades = [93, 95, 88, 0, 55, 91];\n\n
var average = function() {\n
var total = myGrades.reduce(function(accumulator, item) {\n
return accumulator + item;\n
}, 0);\n\n
return'Your average grade is ' + total / myGrades.length + '.';\n
var failing = function() {\n
var failingGrades = myGrades.filter(function(item) {\n
return item & 70;\n
return 'You failed ' + failingGrades.length + ' times.';\n
// 将公有指针指向私有方法\n\n
return {\n
average: average,\n
failing: failing\n
}\n})();\n\nmyGradesCalculate.failing(); // 'You failed 2 times.' \nmyGradesCalculate.average(); // 'Your average grade is 70.33.'\n到这里,其实我们只聊了模块模式的冰山一角。感兴趣的朋友可以阅读更详细的资料:CommonJS & AMD上述的所有解决方案都有一个共同点:使用单个全局变量来把所有的代码包含在一个函数内,由此来创建私有的命名空间和闭包作用域。虽然每种方法都比较有效,但也都有各自的短板。有一点,作为开发者,你必须清楚地了解引入依赖文件的正确顺序。就拿Backbone.js来举个例子,想要使用Backbone就必须在你的页面里引入Backbone的源文件。然而Backbone又依赖 Underscore.js,所以Backbone的引入必须在其之后。而在工作中,这些依赖管理经常会成为让人头疼的问题。另外一点,这些方法也有可能引起命名空间冲突。举个例子,要是你碰巧写了俩重名的模块怎么办?或者你同时需要一个模块的两个版本时该怎么办?难道就没有不通过全局作用域来实现的模块方法么?当然是有的。接下来介绍两种广受欢迎的解决方案:CommonJS 和 AMD.CommonJSCommonJS 扩展了JavaScript声明模块的API.CommonJS模块可以很方便得将某个对象导出,让他们能够被其他模块通过 require 语句来引入。要是你写过 Node.js 应该很熟悉这些语法。通过CommonJS,每个JS文件独立地存储它模块的内容(就像一个被括起来的闭包一样)。在这种作用域中,我们通过 module.exports 语句来导出对象为模块,再通过 require 语句来引入。还是举个直观的例子吧:function myModule() {\n
this.hello = function() {\n
return 'hello!';\n
this.goodbye = function() {\n
return 'goodbye!';\n
}\n}\n\nmodule.exports = myModule;\n通过指定导出的对象名称,CommonJS模块系统可以识别在其他文件引入这个模块时应该如何解释。然后在某个人想要调用 myMoudle 的时候,只需要 require 一下:var myModule = require('myModule');\n\nvar myModuleInstance = new myModule();\nmyModuleInstance.hello(); // 'hello!'\nmyModuleInstance.goodbye(); // 'goodbye!'\n这种实现比起模块模式有两点好处:避免全局命名空间污染明确代码之间的依赖关系并且这种书写方式也非常舒服友好,我自己很喜欢。需要注意的一点是,CommonJS以服务器优先的方式来同步载入模块,假使我们引入三个模块的话,他们会一个个地被载入。它在服务器端用起来很爽,可是在浏览器里就不会那么高效了。毕竟读取网络的文件要比本地耗费更多时间。只要它还在读取模块,浏览器载入的页面就会一直卡着不动。(在下一篇第二部分的教程里我们会讨论如何解决这个问题)AMDCommonJS已经挺不错了,但假使我们想要实现异步加载模块该怎么办?答案就是Asynchronous Module Definition(异步模块定义规范),简称AMD.通过AMD载入模块的代码一般这么写:define(['myModule', 'myOtherModule'], function(myModule, myOtherModule) {\n
console.log(myModule.hello());\n});\n这里我们使用 define 方法,第一个参数是依赖的模块,这些模块都会在后台无阻塞地加载,第二个参数则作为加载完毕的回调函数。回调函数将会使用载入的模块作为参数。在这个例子里就是 myMoudle 和 myOtherModule.最后,这些模块本身也需要通过 define 关键词来定义。拿 myModule 来举个例子:define([], function() {\n\n
return {\n
hello: function() {\n
console.log('hello');\n
goodbye: function() {\n
console.log('goodbye');\n
};\n});\n重申一下,不像CommonJS,AMD是优先浏览器的一种异步载入模块的解决方案。(记得,很多人认为一个个地载入小文件是很低效的,我们将在下一篇文章理介绍如何打包模块)除了异步加载以外,AMD的另一个优点是你可以在模块里使用对象、函数、构造函数、字符串、JSON或者别的数据类型,而CommonJS只支持对象。再补充一点,AMD不支持Node里的一些诸如 IO,文件系统等其他服务器端的功能。另外语法上写起来也比CommonJS麻烦一些。UMD在一些同时需要AMD和CommonJS功能的项目中,你需要使用另一种规范:Universal Module Definition(通用模块定义规范)。UMD创造了一种同时使用两种规范的方法,并且也支持全局变量定义。所以UMD的模块可以同时在客户端和服务端使用。下面是一个解释其功能的例子:(function (root, factory) {\n
if (typeof define === 'function' && define.amd) {\n
define(['myModule', 'myOtherModule'], factory);\n
} else if (typeof exports === 'object') {\n
// CommonJS\n
module.exports = factory(require('myModule'), require('myOtherModule'));\n
} else {\n
// Browser globals (Note: root is window)\n
root.returnExports = factory(root.myModule, root.myOtherModule);\n
}\n}(this, function (myModule, myOtherModule) {\n
// Methods\n
function notHelloOrGoodbye(){}; // A private method\n
function hello(){}; // A public method because it's returned (see below)\n
function goodbye(){}; // A public method because it's returned (see below)\n\n
// Exposed public methods\n
return {\n
hello: hello,\n
goodbye: goodbye\n
}\n}));\n更多有关UMD的例子请看其Github上的.原生JS希望你坚持读到了现在,我们最后再介绍一种定义模块的方式。你可能注意到了,上述的这几种方法都不是JS原生支持的。要么是通过模块模式来模拟,要么是使用CommonJS或AMD.幸运的是在JS的最新规范ECMAScript 6 (ES6)中,引入了模块功能。ES6 的模块功能汲取了CommonJS 和 AMD 的优点,拥有简洁的语法并支持异步加载,并且还有其他诸多更好的支持。我最喜欢的ES6 模块功能的特性是,导入是实时只读的。(CommonJS 只是相当于把导出的代码复制过来)。来看例子:// lib/counter.js\n\nvar counter = 1;\n\nfunction increment() {\n
counter++;\n}\n\nfunction decrement() {\n
counter--;\n}\n\nmodule.exports = {\n
counter: counter,\n
increment: increment,\n
decrement: decrement\n};\n\n\n// src/main.js\n\nvar counter = require('../../lib/counter');\n\ncounter.increment();\nconsole.log(counter.counter); // 1\n上面这个例子中,我们一共创建了两份模块的实例,一个在导出的时候,一个在引入的时候。在 main.js 当中的实例是和原本模块完全不相干的。这也就解释了为什么调用了 counter.increment() 之后仍然返回1。因为我们引入的 counter 变量和模块里的是两个不同的实例。所以调用 counter.increment() 方法只会改变模块中的 counter .想要修改引入的 counter 只有手动一下啦:counter.counter++;\nconsole.log(counter.counter); // 2\n而通过 import 语句,可以引入实时只读的模块:// lib/counter.js\nexport let counter = 1;\n\nexport function increment() {\n
counter++;\n}\n\nexport function decrement() {\n
counter--;\n}\n\n\n// src/main.js\nimport * as counter from '../../counter';\n\nconsole.log(counter.counter); // 1\ncounter.increment();\nconsole.log(counter.counter); // 2\n这看起来很酷不是么?这样就实现了我们把模块分隔在不同的文件里,需要的时候又可以合并在一起而且不影响它的功能。期待下一篇:模块打包我想看到这里的你应该已经对JavaScript模块化有了进一步的了解。在下一篇教程里,我们会介绍:为什么要打包模块几种不同的打包构建方式ECMAScript 模块载入API其他欢迎在评论区讨论提问,如果有什么不对的地方也欢迎批评指正~","state":"published","sourceUrl":"","pageCommentsCount":0,"canComment":false,"snapshotUrl":"","slug":,"publishedTime":"T00:13:43+08:00","url":"/p/","title":"JavaScript 模块化入门Ⅰ:理解模块","summary":"原文链接: 作者:声明:转载请私信联系,转载请注明出处。作为一名JS初学者。假如你听到了一些诸如“模块化构建&模块化载入” “Webpack&Browserify” 或者 “AMD&CMD”之类的术语,肯定瞬间就凌…","reviewingCommentsCount":0,"meta":{"previous":null,"next":null},"commentPermission":"anyone","commentsCount":32,"likesCount":265},"next":{"isTitleImageFullScreen":false,"rating":"none","titleImage":"/v2-0e892f7f9a0ad46130f9e_r.jpg","links":{"comments":"/api/posts//comments"},"topics":[{"url":"/topic/","id":"","name":"JavaScript"},{"url":"/topic/","id":"","name":"前端开发"},{"url":"/topic/","id":"","name":"前端入门"}],"adminClosedComment":false,"href":"/api/posts/","excerptTitle":"","author":{"bio":"少刷知乎多看书","isFollowing":false,"hash":"83a3b10a446f936a77f07f78870b5eec","uid":96,"isOrg":false,"slug":"yubolun","isFollowed":false,"description":"我已委托“维权骑士”()为我的文章进行维权行动。","name":"余博伦","profileUrl":"/people/yubolun","avatar":{"id":"v2-06d97a62e029d46d754eb716bc81b231","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},"column":{"slug":"icode","name":"从零学习前端开发"},"content":"原文链接:作者:在里我们已经讨论过什么是模块,为什么要使用模块以及多种实现模块化的方式。这次,我们会聊一聊什么是模块打包,为什么要打包模块,模块打包的方式工具,还有它当前在Web开发中的运用。什么是模块打包?粗俗一点来讲,模块打包就是把一小坨一小坨的代码粘成一大坨。实际操作起来的时候当然还需要关注一些细节。为什么要打包模块?一般来讲,我们用模块化组织代码的时候,都会把模块划分在不同的文件和文件夹里,也可能会包含一些诸如React和Underscore一类的第三方库。而后,所有的这些模块都需要通过&script&标签引入到你的HTML文件中,然后用户在访问你网页的时候它才能正常显示和工作。每个独立的&script&标签都意味着,它们要被浏览器分别一个个地加载。这就有可能导致页面载入时间过长。为了解决这个问题,我们就需要进行模块打包,把所有的模块合并到一个或几个文件中,以此来减少HTTP请求数。这也可以被称作是从开发到上线前的构建环节。还有一种提升加载速度的做法叫做代码压缩(混淆)。其实就是去除代码中不必要的空格、注释、换行符一类的字符,来保证在不影响代码正常工作的情况下压缩其体积。更小的文件体积也就意味着更短的加载时间。要是你仔细对比过带有 .min后缀的例如 jquery.min.js和jquery.js的话,应该会发现压缩版的文件相较之下要小很多。Gulp和Grunt一类的构建工具可以很方便地解决上述的需求,在开发的时候通过模块来组织代码,上线时再合并压缩提供给浏览器。打包模块的方法有哪些?如果你的代码是通过之前介绍过的模块模式来组织的,合并和压缩它们其实就只是把一些原生的JS代码合在一起而已。但如果你使用的是一些浏览器原生不支持的模块系统(例如CommonJS 或 AMD,以及ES6 模块的支持现在也不完整),你就需要使用一些专门的构建工具来把它们转换成浏览器支持的代码。这类工具就是我们最近经常听说的Browserify, RequireJS, Webpack等等模块化构建、模块化加载工具了。为了实现模块化构建或载入的功能,这类工具提供许多诸如在你改动源代码后自动重新构建(文件监听)等一系列的功能。下面我们就一起来看一些实际的例子吧:打包 CommonJS在上一篇教程中我们了解到, CommonJS是同步载入模块的,这对浏览器来说不是很理想。其实下面介绍的模块化构建工具Browserify在上一篇也提到过。它是一个专门用来打包CommonJS模块以便在浏览器里运行的构建工具。举个例子,假如你在 main.js 文件中引入了一个用来计算平均数的功能模块:var myDependency = require('myDependency');\n\nvar myGrades = [93, 95, 88, 0, 91];\n\nvar myAverageGrade = myDependency.average(myGrades);\n在这个示例中,我们只有一个名为 myDependency 的模块依赖。通过下面的命令,Browserify会依次把main.js里引入的所有模块一同打包到一个名为 bundle.js 的文件里:browserify main.js -o bundle.js\nBrowserify 首先会通过抽象语法树()来解析代码中的每一个 require 语句,在分析完所有模块的依赖和结构之后,就会把所有的代码合并到一个文件中。然后你在HTML文件里引入一个bundle.js就够啦。多个文件和多个依赖也只需要再稍微配置一下就能正常工作了。之后你也可以使用一些例如Minify-JS的工具来压缩代码。打包 AMD假若你使用的是AMD,你会需要一些例如RequireJS 或 Curl的AMD加载器。模块化加载工具可以在你的应用中按需加载模块代码。需要再次提醒一下,AMD 和 CommonJS 的最主要区别是AMD是异步加载模块的。这也就意味着你不是必须把所有的代码打包到一个文件里,模块加载不影响后续语句执行,逐步加载的的模块也不会导致页面阻塞无法响应。不过在实际应用中,为了避免用户过多的请求对服务器造成压力。大多数的开发者还是选择用RequireJS optimizer, 一类的构建工具来合并和压缩AMD的模块。总的来说,AMD 和 CommonJS 在构建中最大的区别是,在开发过程中,采用AMD的应用直到正式上线发布之前都不需要构建。要是你对CommonJS vs. AMD的讨论感兴趣,可以看这一篇WebpackWebpack 是新推出的构建工具里最受欢迎的。它兼容CommonJS, AMD, ES6各类规范。也许你会质疑,我们已经有这么多诸如Browserify 或 RequireJS 的工具了,为什么还需要 Webpack 呢?究其原因之一,Webpack 提供许多例如 code splitting(代码分割) 的有用功能,它可以把你的代码分割成一个个的 chunk 然后按需加载优化性能。举个例子,要是你的Web应用中的一些代码只在很少的情况下才会被用到,把它们全都打包到一个文件里是很低效的做法。所以我们就需要 code splitting 这样的功能来实现按需加载。而不是把那些很少人才会用到的代码一股脑儿全都下载到客户端去。code splitting 只是 Webpack 提供的众多强大功能之一。当然,网上也为这些模块化构建工具吵得不可开交。你要是感兴趣的话也可以在下面这些地方观摩一下:ES6 模块看他们吵够了的话,接下来我就要介绍一下ES6模块了。假如你采用ES6模块,在不远的将来对那些构建工具的需求可能会小一些。首先我们还是看看ES6模块是怎么加载的吧。ES6模块和CommonJS, AMD一类规范最主要的区别是,当你载入一个模块时,载入的操作实际实在编译时执行的——也就是在代码执行之前。所以去掉那些不必要的exports导出语句可以优化我们应用的性能。有一个经常会被问到的问题:去除exports和冗余代码消除(UglifyJS一类工具执行后的效果)之间有什么区别?答案是这个要具体情况具体分析,感兴趣的话可以上Github看这个Repo:让ES6模块与冗余代码消除(Dead code elimination)不同的是一种叫做tree shaking的技术。Tree shaking其实恰好是冗余代码消除的反向操作。它只加载你需要调用的代码,而不是删掉不会被执行的代码。我们还是用一个具体的例子说明吧:假设我们有如下一个使用ES6语法,名为 utils.js 的函数:export function each(collection, iterator) {\n
if (Array.isArray(collection)) {\n
for (var i = 0; i & collection.length; i++) {\n
iterator(collection[i], i, collection);\n
} else {\n
for (var key in collection) {\n
iterator(collection[key], key, collection);\n
}\n }\n\nexport function filter(collection, test) {\n
var filtered = [];\n
each(collection, function(item) {\n
if (test(item)) {\n
filtered.push(item);\n
return filtered;\n}\n\nexport function map(collection, iterator) {\n
var mapped = [];\n
each(collection, function(value, key, collection) {\n
mapped.push(iterator(value));\n
return mapped;\n}\n\nexport function reduce(collection, iterator, accumulator) {\n
var startingValueMissing = accumulator === undefined;\n\n
each(collection, function(item) {\n
if(startingValueMissing) {\n
accumulator = item;\n
startingValueMissing = false;\n
} else {\n
accumulator = iterator(accumulator, item);\n
return accumulator;\n}\n现在我们也不清楚到底需要这个函数的哪些功能,所以先全部引入到 main.js 中://main.js\nimport * as Utils from './utils.js';\n之后我们再调用一下 each 函数://main.js\nimport * as Utils from './utils.js';\n\nUtils.each([1, 2, 3], function(x) { console.log(x) });\n通过 \"tree shaken\" 之后的 main.js 看起来就像下面这样://treeshake.js \nfunction each(collection, iterator) {\n
if (Array.isArray(collection)) {\n
for (var i = 0; i & collection. i++) {\n
iterator(collection[i], i, collection);\n
} else {\n
for (var key in collection) {\n
iterator(collection[key], key, collection);\n
}\n };\n\neach([1, 2, 3], function(x) { console.log(x) });\n注意到这里只导出了我们调用过的 each 方法。再如果我们只调用 filter 方法的话://main.js\nimport * as Utils from './utils.js';\n\nUtils.filter([1, 2, 3], function(x) { return x === 2 });\n\"Tree shaken\" 之后就会变成这样:function each(collection, iterator) {\n
if (Array.isArray(collection)) {\n
for (var i = 0; i & collection.length; i++) {\n
iterator(collection[i], i, collection);\n
} else {\n
for (var key in collection) {\n
iterator(collection[key], key, collection);\n
}\n };\n\nfunction filter(collection, test) {\n
var filtered = [];\n
//注意在filter中调用了each,所以两个方法都会被引入\n
each(collection, function(item) {\n
if (test(item)) {\n
filtered.push(item);\n
return filtered;\n};\n\nfilter([1, 2, 3], function(x) { return x === 2 });\n很神奇不是么?你也可以自己在Rollup.js的实时预览编辑器里做做试验:构建ES6模块现在我们已经了解到ES6模块载入的与众不同了,但我们还没有聊到底该怎么构建ES6模块。因为浏览器对ES6模块的原生支持还不够完善,所以现阶段还需要我们做一些补充工作。让ES6模块在浏览器中顺利运行的常用方法有以下几种:1.使用语法编译器(Babel或Traceur)来把ES6语法的代码编译成ES5或者CommonJS, AMD, UMD等其他形式。然后再通过Browserify 或 Webpack 一类的构建工具来进行构建。2.使用,这其实和上面差不多,只是Rollup还会捎带的利用“tree shaking”技术来优化你的代码。在构建ES6模块时Rollup优于Browserify或Webpack的也正是这一点,它打包出来的文件体积会更小。Rollup也可以把你的代码转换成包括ES6, CommonJS, AMD, UMD, IIFE在内的各种格式。其中IIFE和UMD可以直接在浏览器里运行,AMD, CommonJS, ES6等还需要你通过Browserify, Webpack, RequireJS一类的工具才能在浏览器中使用。小心踩坑这里有一些坑还需要和大家说明一下。转换语法优雅的ES6代码以便在浏览器里运行并不是一件令人舒爽的事情。问题在于,什么时候我们才能免去这些多余的工作。令人感动的答案是:“差不多快了。”ECMAScript目前包含一个名为 的解决方案。简单来讲,这个解决方案允许你动态加载模块并缓存。还是来举例说明:myModule.jsexport class myModule {\n
constructor() {\n
console.log('Hello, I am a module');\n
hello() {\n
console.log('hello!');\n
goodbye() {\n
console.log('goodbye!');\n
}\n}\nmain.jsSystem.import('myModule').then(function(myModule) {\n
new myModule.hello();\n});\n\n// ‘Hello!, I am a module!’\n同样,你可以在script标签上设置type=module的属性来直接定义模块:&script type=\"module\"&\n
// loads the 'myModule' export from 'mymodule.js'\n
import { hello } from 'mymodule';\n
new Hello(); // 'Hello, I am a module!'\n&/script&\n更加详细的介绍也可以在Github上查看:如果你现在就想测试这个解决方案的话,我在这里也安利一下 . SystemJS支持在浏览器端和Node动态加载之前介绍过所有格式的模块(ES6 modules, AMD, CommonJS等),通过把已加载的模块还存在\"module registry\"里来避免重复加载。它也同样支持转换ES6的代码至其他格式。我们已经有了原生ES6模块,还需要那些乱七八糟的玩意儿么?越来越多的人使用ES6模块产生了一些有趣的影响:HTTP/2 出现之后,模块化构建工具是不是都该被淘汰了?在HTTP/1中,一次TCP连接只允许一个请求,所以我们需要通过减少载入的文件数来优化性能。而HTTP/2改变了这一切,请求和响应可以并行,一次连接也允许多个请求。每次请求的消耗也会远远小于HTTP/1,所以载入一堆模块就不再是一个影响性能的问题了。所以许多人认为打包模块完全就是多余的了。这听起来很合理,但我们也需要具体情况具体分析。其中有一条,模块化构建解决了一些HTTP/2解决不了的问题。例如去除冗余的代码以压缩体积。要是你开发的是一个对性能要求很高的网站,模块化构建从长远上考虑会给你带来更多好处。当然,要是你不那么在意性能问题,以后完全就可以省却这些烦人的步骤了。总之,我们离所有的网站都采用HTTP/2传输还有相当一段时间。短期内模块化构建还是很有必要的。要是你对HTTP/2的其他特性也感兴趣,可以查阅这里:CommonJS , AMD, UMD这类标准会过时么?一旦ES6成为了模块化的标准,我们还需要这些非原生的东西么?这点还值得商榷。在JavaScript中采用统一标准,通过import和export来使用模块,省略所有繁杂的多余步骤确实很爽。不过到底要多久ES6才能成为真正的模块化标准呢?反正不会很快。并且开发者也有各自的偏好,“唯一的解决方案”永远也不会存在。总结我希望这两篇文章对于你理解JS模块有所帮助,要是你忘了之前聊过的内容,可以现在点开再看看:有任何问题和建议也欢迎在评论区讨论。","state":"published","sourceUrl":"","pageCommentsCount":0,"canComment":false,"snapshotUrl":"","slug":,"publishedTime":"T11:44:50+08:00","url":"/p/","title":"JavaScript 模块化入门Ⅱ:模块打包构建","summary":"原文链接:作者:在里我们已经讨论过什么是模块,为什么要使用模块以及多种实现模块化的方式。这次,我们会聊一聊什么是模块打包,为什么要打包模块,模块打包的方式工具,还有它当…","reviewingCommentsCount":0,"meta":{"previous":null,"next":null},"commentPermission":"anyone","commentsCount":8,"likesCount":88}},"annotationDetail":null,"commentsCount":32,"likesCount":351,"FULLINFO":true}},"User":{"yubolun":{"isFollowed":false,"name":"余博伦","headline":"我已委托“维权骑士”()为我的文章进行维权行动。","avatarUrl":"/v2-06d97a62e029d46d754eb716bc81b231_s.jpg","isFollowing":false,"type":"people","slug":"yubolun","bio":"少刷知乎多看书","hash":"83a3b10a446f936a77f07f78870b5eec","uid":96,"isOrg":false,"description":"我已委托“维权骑士”()为我的文章进行维权行动。","profileUrl":"/people/yubolun","avatar":{"id":"v2-06d97a62e029d46d754eb716bc81b231","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false,"badge":{"identity":null,"bestAnswerer":null}}},"Comment":{},"favlists":{}},"me":{},"global":{},"columns":{"icode":{"following":false,"canManage":false,"href":"/api/columns/icode","name":"从零学习前端开发","creator":{"slug":"yubolun"},"url":"/icode","slug":"icode","avatar":{"id":"1a8fcada9ebb","template":"/{id}_{size}.jpeg"}}},"columnPosts":{},"columnSettings":{"colomnAuthor":[],"uploadAvatarDetails":"","contributeRequests":[],"contributeRequestsTotalCount":0,"inviteAuthor":""},"postComments":{},"postReviewComments":{"comments":[],"newComments":[],"hasMore":true},"favlistsByUser":{},"favlistRelations":{},"promotions":{},"switches":{"couldAddVideo":false},"draft":{"titleImage":"","titleImageSize":{},"isTitleImageFullScreen":false,"canTitleImageFullScreen":false,"title":"","titleImageUploading":false,"error":"","content":"","draftLoading":false,"globalLoading":false,"pendingVideo":{"resource":null,"error":null}},"drafts":{"draftsList":[],"next":{}},"config":{"userNotBindPhoneTipString":{}},"recommendPosts":{"articleRecommendations":[],"columnRecommendations":[]},"env":{"isAppView":false,"appViewConfig":{"content_padding_top":128,"content_padding_bottom":56,"content_padding_left":16,"content_padding_right":16,"title_font_size":22,"body_font_size":16,"is_dark_theme":false,"can_auto_load_image":true,"app_info":"OS=iOS"},"isApp":false},"sys":{}}

我要回帖

更多关于 风水学最好的入门书籍 的文章

 

随机推荐