ImageVerifierCode 换一换
格式:DOCX , 页数:30 ,大小:28.55KB ,
资源ID:28324991      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/28324991.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(给 JavaScript 初心者的 ES实战.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

给 JavaScript 初心者的 ES实战.docx

1、给 JavaScript 初心者的 ES实战给 JavaScript 初心者的 ES2015 实战 作者:小问感谢以下厂商联合为作者提供的 4000 元写作赞助:成为赞助方 /开始写作给 JavaScript 初心者的 ES2015 实战前言历时将近6年的时间来制定的新 ECMAScript 标准 ECMAScript 6(亦称 ECMAScript Harmony,简称 ES6)终于在 2015 年 6 月正式发布。自从上一个标准版本 ES5 在 2009 年发布以后,ES6 就一直以新语法、新特性的优越性吸引著众多 JavaScript 开发者,驱使他们积极尝鲜。虽然至今各大浏览器厂商所开

2、发的 JavaScript 引擎都还没有完成对 ES2015 中所有特性的完美支持,但这并不能阻挡工程师们对 ES6 的热情,于是乎如 babel、Traceur 等编译器便出现了。它们能将尚未得到支持的 ES2015 特性转换为 ES5 标准的代码,使其得到浏览器的支持。其中,babel 因其模块化转换器(Transformer)的设计特点赢得了绝大部份 JavaScript 开发者的青睐,本文也将以 babel 为基础工具,向大家展示 ES2015 的神奇魅力。笔者目前所负责的项目中,已经在前端和后端全方位的使用了 ES2015 标准进行 JavaScript 开发,已有将近两年的 ES2

3、015 开发经验。如今 ES2015 以成为 ECMA 国际委员会的首要语言标准,使用 ES2015 标准所进行的工程开发已打好了坚实的基础,而 ES7(ES2016) 的定制也走上了正轨,所以在这个如此恰当的时机,我觉得应该写一篇通俗易懂的 ES2015 教程来引导广大 JavaScript 爱好者和工程师向新时代前进。若您能从本文中有所收获,便是对我最大的鼓励。我希望你在阅读本文前,已经掌握了 JavaScript 的基本知识,并具有一定的 Web App 开发基础和 Node.js 基本使用经验。目录一言蔽之 ES2015ES2015 能为 JavaScript 的开发带来什么语法糖工程

4、优势ES2015 新语法详解let 、 const 和块级作用域块级作用域箭头函数(Arrow Function)使用方法箭头函数与上下文绑定注意事项模板字符串支持变量注入支持换行对象字面量扩展语法方法属性省略 function支持注入 _proto_同名方法属性省略语法可以动态计算的属性名称表达式解构函数参数表达、传参默认参数值后续参数注意事项解构传参注意事项新的数据结构Set 和 WeakSetMap 和 WeakMap类(Classes)语法定义继承静态方法遗憾与期望生成器(Generator)来龙基本概念Generator FunctionGenerator基本使用方法Promise概

5、念基本用法弊端原生的模块化历史小回顾基本用法全局引入局部引入接口暴露降级兼容Symbol黑科技Proxy(代理)ES2015 的前端开发实战构建界面结构定义架构设计模块化数据支持界面渲染构建应用入口文件数据层:文章路由:首页准备页面渲染加载数据设计组件路由:文章页面路由:发布新文章路由绑定合并代码ES2015 的 Node.js 开发实战架构设计构建应用入口文件数据抽象层Posts 控制器API:获取所有文章API:获取指定文章API:发布新文章Comments 控制器API:获取指定文章的评论API:发表新评论配置路由配置任务文件部署到 DaoCloudDockerfile创建 DaoClo

6、ud 上的 MongoDB 服务代码构建一窥 ES7async/awaitDecorators简单实例黑科技后记本文的实战部份将以开发一个动态博客系统为背景,向大家展示如何使用 ES2015 进行项目开发。成品代码将在 GitHub 上展示。一言蔽之 ES2015说到 ES2015,有了解过的同学一定会马上想到各种新语法,如箭头函数(=)、class、模板字符串等。是的,ECMA 委员会吸取了许多来自全球众多 JavaScript 开发者的意见和来自其他优秀编程语言的经验,致力于制定出一个更适合现代 JavaScript 开发的标准,以达到“和谐”(Harmony)。一言蔽之:ES2015 标

7、准提供了许多新的语法和编程特性以提高 JavaScript 的开发效率和体验从 ES6 的别名被定为 Harmony 开始,就注定了这个新的语言标准将以一种更优雅的姿态展现出来,以适应日趋复杂的应用开发需求。ES2015 能为 JavaScript 的开发带来什么语法糖如果您有其他语言(如 Ruby、Scala)或是某些 JavaScript 的衍生语言(如 CoffeeScript、TypeScript)的开发经验,就一定会了解一些很有意思的语法糖,如 Ruby 中的 Range - 1.10,Scala 和 CoffeeScript 中的箭头函数 (a, b) = a + b。ECMA 委

8、员会借鉴了许多其他编程语言的标准,给 ECMAScript 家族带来了许多可用性非常高的语法糖,下文将会一一讲解。这些语法糖能让 JavaScript 开发者更舒心地开发 JavaScript 应用,提高我们的工作效率,多一些时间出去浪。工程优势ES2015 除了提供了许多语法糖以外,还由官方解决了多年来困扰众多 JavaScript 开发者的问题:JavaScript 的模块化构建。从许多年前开始,各大公司、团队、大牛都相继给出了他们对于这个问题的不同解决方案,以至于定下了如 CommonJS、AMD、CMD 或是 UMD 等 JavaScript 模块化标准,RequireJS、SeaJS

9、、FIS、Browserify、webpack 等模块加载库都以各自不同的优势占领著一方土地。然而正正是因为这春秋战国般的现状,广大的前端搬砖工们表示很纳闷。这?究竟哪种好?哪种适合我?求大神带我飞!对此,ECMA 委员会终于是坐不住了,站了起来表示不服,并制订了 ES2015 的原生模块加载器标准。import fs from fsimport readline from readlineimport path from pathlet Module = readLineInFile(filename, callback = noop, complete = noop) let rl = r

10、eadline.createInterface( input: fs.createReadStream(path.resolve(_dirname, ./big_file.txt) ) rl.on(line, line = /. do something with the current line callback(line) ) rl.on(close, complete) return rl function noop() return false export default Module老实说,这套模块化语法不禁让我们又得要对那个很 silly 的问题进行重新思考了:JavaScrip

11、t 和 Java 有什么关系?可惜的是,目前暂时还没有任何浏览器厂商或是 JavaScript 引擎支持这种模块化语法。所以我们需要用 babel 进行转换为 CommonJS、AMD 或是 UMD 等模块化标准的语法。ES2015 新语法详解经过以上的介(xun)绍(tao),相信你对 ES2015 也有了一定的了解和期待。接下来我将带大家慢慢看看 ECMA 委员会含辛茹苦制定的新语言特性吧。let、const 和块级作用域在 ES2015 的新语法中,影响速度最为直接,范围最大的,恐怕得数 let 和 const 了,它们是继 var 之后,新的变量定义方法。与 let 相比,const

12、更容易被理解:const 也就是 constant 的缩写,跟 C/C+ 等经典语言一样,用于定义常量,即不可变量。但由于在 ES6 之前的 ECMAScript 标准中,并没有原生的实现,所以在降级编译中,会马上进行引用检查,然后使用 var 代替。/ foo.jsconst foo = barfoo = newvalue$ babel foo.js.SyntaxError: test.js: Line 3: foo is read-only 1 | const foo = bar 2 | 3 | foo = newvalue.块级作用域在 ES6 诞生之前,我们在给 JavaScript

13、新手解答困惑时,经常会提到一个观点:JavaScript 没有块级作用域在 ES6 诞生之前的时代中,JavaScript 确实是没有块级作用域的。这个问题之所以为人所熟知,是因为它引发了诸如历遍监听事件需要使用闭包解决等问题。一二三四 var buttons = document.querySelectorAll(button) var output = document.querySelector(#output) for (var i = 0; i buttons.length; i+) buttonsi.addEventListener(click, function() output

14、.innerText = buttonsi.innerText ) 前端新手非常容易写出类似的代码,因为从直观的角度看这段代码并没有语义上的错误,但是当我们点击任意一个按钮时,就会报出这样的错误信息:Uncaught TypeError: Cannot read property innerText of undefined出现这个错误的原因是因为 buttonsi 不存在,即为 undefined。为什么会出现按钮不存在结果呢?通过排查,我们可以发现,每次我们点击按钮时,事件监听回调函数中得到的变量 i 都会等于 buttons.length,也就是这里的 4。而 buttons4 恰恰不存

15、在,所以导致了错误的发生。再而导致 i 得到的值都是 buttons.length 的原因就是因为 JavaScript 中没有块级作用域,而使对 i 的变量引用(Reference)一直保持在上一层作用域(循环语句所在层)上,而当循环结束时 i 则正好是 buttons.length。而在 ES6 中,我们只需做出一个小小的改动,便可以解决该问题(假设所使用的浏览器已经支持所需要的特性):/ .for (/* var */ let i = 0; i buttons.length; i+) / ./ .通过把 for 语句中对计数器 i 的定义语句从 var 换成 let,即可。因为 let

16、语句会使该变量处于一个块级作用域中,从而让事件监听回调函数中的变量引用得到保持。我们不妨看看改进后的代码经过 babel 的编译会变成什么样子:/ .var _loop = function (i) buttonsi.addEventListener(click, function () output.innerText = buttonsi.innerText )for (var i = 0; i )进行定义的函数,属于匿名函数(Lambda)一类。当然了,也可以作为定义式函数使用,但我们并不推荐这样做,随后会详细解释。使用箭头函数有好几种使用语法:1. foo = foo + world

17、/ means return foo + world2. (foo, bar) = foo + bar3. foo = return foo + world4.(foo, bar) = return foo + bar以上都是被支持的箭头函数表达方式,其最大的好处便是简洁明了,省略了 function 关键字,而使用 = 代替。箭头函数语言简洁的特点使其特别适合用於单行回调函数的定义:let names = Will, Jack, Peter, Steve, John, Hugo, Mike let newSet = names .map(name, index) = return id: i

18、ndex, name: name ) .filter(man = man.id % 2 = 0) .map(man = man.name) .reduce(a, b) = a.concat(b)console.log(newSet) /= Will, Peter, John, Mike 如果你有 Scala + Spark 的开发经验,就一定会觉得这非常亲切,因为这跟其中的 RDD 操作几乎如出一辙:将原本的由名字组成的数组转换为一个格式为 id, name 的对象,id 则为每个名字在原数组中的位置剔除其中 id 为奇数的元素,只保留 id 为偶数的元素将剩下的元素转换为一个包含当前元素中原

19、名字的单元数组,以方便下一步的处理通过不断合并相邻的两个数组,最后能得到的一个数组,便是我们需要得到的目标值箭头函数与上下文绑定事实上,箭头函数在 ES2015 标准中,并不只是作为一种新的语法出现。就如同它在 CoffeeScript 中的定义一般,是用于对函数内部的上下文 (this)绑定为定义函数所在的作用域的上下文。let obj = hello: world, foo() let bar = () = return this.hello return bar window.hello = ES6window.bar = obj.foo()window.bar() /= world上面

20、代码中的 obj.foo 等价于:/ .foo() let bar = (function() return this.hello ).bind(this) return bar/ .为什么要为箭头函数给予这样的特性呢?我们可以假设出这样的一个应用场景,我们需要创建一个实例,用于对一些数据进行查询和筛选。let DataCenter = baseUrl: search(query) fetch($this.baseUrl/search?query=$query) .then(res = res.json() .then(rows = / TODO ) 此时,从服务器获得数据是一个 JSON 编

21、码的数组,其中包含的元素是若干元素的 ID,我们需要另外请求服务器的其他 API 以获得元素本身(当然了,实际上的 API 设计大部份不会这么使用这么蛋疼的设计)。我们就需要在回调函数中再次使用 this.baseUrl 这个属性,如果要同时兼顾代码的可阅读性和美观性,ES2015 允许我们这样做。let DataCenter = baseUrl: search(query) return fetch($this.baseUrl/search?query=$query) .then(res = res.json() .then(rows = return fetch($this.baseUrl

22、/fetch?ids=$rows.join(,) / 此处的 this 是 DataCenter,而不是 fetch 中的某个实例 ) .then(res = res.json() DataCenter.search(iwillwen) .then(rows = console.log(rows)因为在单行匿名函数中,如果 this 指向的是该函数的上下文,就会不符合直观的语义表达。注意事项另外,要注意的是,箭头函数对上下文的绑定是强制性的,无法通过 apply 或 call 方法改变其上下文。let a = init() this.bar = () = this.dam , dam: hei

23、, foo() return this.dam let b = dam: haa.init()console.log(a.foo() /= heiconsole.log(a.foo.bind(b).call(a) /= haconsole.log(a.bar.call(b) /= hei另外,因为箭头函数会绑定上下文的特性,故不能随意在顶层作用域使用箭头函数,以防出错:/ 假设当前运行环境为浏览器,故顶层作上下文为 windowlet obj = msg: pong, ping: () = return this.msg / Warning! obj.ping() /= undefinedle

24、t msg = bang!obj.ping() /= bang!为什么上面这段代码会如此让人费解呢?我们来看看它的等价代码吧。let obj = / . ping: (function() return this.msg / Warning! ).bind(this)/ 同样等价于let obj = /* . */ obj.ping = (function() return this.msg).bind(this /* this - window */)模板字符串模板字符串模板出现简直对 Node.js 应用的开发和 Node.js 自身的发展起到了相当大的推动作用!我的意思并不是说这个原生的

25、模板字符串能代替现有的模板引擎,而是说它的出现可以让非常多的字符串使用变得尤为轻松。模板字符串要求使用 代替原本的单/双引号来包裹字符串内容。它有两大特点:支持变量注入支持换行支持变量注入模板字符串之所以称之为“模板”,就是因为它允许我们在字符串中引用外部变量,而不需要像以往需要不断地相加、相加、相加let name = Will Wen Gunnlet title = Founderlet company = LikMoon Creationlet greet = Hi, Im $name, I am the $title at $companyconsole.log(greet) /= H

26、i, Im Will Wen Gunn, I am the Founder at LikMoon Creation支持换行在 Node.js 中,如果我们没有支持换行的模板字符串,若需要拼接一条SQL,则很有可能是这样的:var sql = SELECT * FROM Users + WHERE FirstName=Mike + LIMIT 5;或者是这样的:var sql = SELECT * FROM Users, WHERE FirstName=Mike, LIMIT 5;.join( )无论是上面的哪一种,都会让我们感到很不爽。但若使用模板字符串,仿佛打开了新世界的大门let sql

27、= SELECT * FROM UsersWHERE FirstName=MikeLIMIT 5;Sweet! 在 Node.js 应用的实际开发中,除了 SQL 的编写,还有如 Lua 等嵌入语言的出现(如 Redis 中的 SCRIPT 命令),或是手工的 XML 拼接。模板字符串的出现使这些需求的解决变得不再纠结了对象字面量扩展语法看到这个标题的时候,相信有很多同学会感到奇怪,对象字面量还有什么可以扩展的?确实,对象字面量的语法在 ES2015 之前早已挺完善的了。不过,对于聪明的工程师们来说,细微的改变,也能带来不少的价值。方法属性省略 function这个新特性可以算是比较有用但并不

28、是很显眼的一个。let obj = / before foo: function() return foo , / after bar() return bar 支持 _proto_ 注入在 ES2015 中,我们可以给一个对象硬生生的赋予其 _proto_,这样它就可以成为这个值所属类的一个实例了。class Foo constructor() this.pingMsg = pong ping() console.log(this.pingMsg) let o = _proto_: new Foo()o.ping() /= pong什么?有什么卵用?有一个比较特殊的场景会需要用到:我想扩展或者覆盖一个类的方法,并生成一个实例,但觉得另外定义一个类就感觉浪费了。那我可以这样做:let o = _proto_: new Foo(), constructor() this.pingMsg = alive

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1