ES6
题目
ES6模块化如何使用,开发环境如何打包。
- 语法:import export
-
Class和普通的构造函数有何区别
Class在语法上更加贴合面向对象的写法
- Class实现集成更加一度,易理解
- 更抑郁java等后端语言的使用
-
Promise的基本使用和原理
new Promsie() 要return
- new Promsie()时要传入函数,函数有resolve,reject两个参数
- 成功时执行resolve() 失败时执行reject()
-
ES6常用功能
let/const
- 多行字符串/模板变量
- 快儿级作用域
- 函数默认参数
- 尖头函数
ES6模块化
模块化基本语法
- export语法
-
开发环境配置babel
node npm init
- npm i -D babel-core babel-core babel-preset-es2015 babel-preset-latest
-
webpack
rollup
vue、react都死使用rollup进行打包的
- 特点
- 尽量简化输出的内容大小
使用:
- npm init
- npm i rollup rollup-plugin-node-resolve rollup-plgin-babel babel-plugin-external-helpers babel-preset-latest -D
- 配置.babellrc
- 配置rollup.config.js
区别:
- rollup功能单一,webpack功能强大。
- 工具要尽量功能单一,可集成,可扩展。
- 比如可以用gulp+rollup构建工具库
关于JS众多模块化标准
- 没有模块化
- AMD成为标准,require.js (也有cmd)
- 前端打包工具,使得nodejs模块化可以被使用
- Es6出现,想统一现在所有模块化标准
- nodejs积极支持,浏览器尚未统一
- 可以自造lib,但不要自造标注
class和普通构造函数区别
JS构造函数
Class基本语法
语法糖
class MathHandle{// ...}typeof MathHandle // "function"MathHandle === MathHandle.prototype.constructor // truemathhandle.__proto__ === Mathhandle.propertype //true
集成
Promise的基本使用
目的:干掉callback Hell
原型
重点:原型的实际应用,比如zepto是怎么使用原型的
题目
说一个原型的实际应用
(function(window){var zepto={}function Z(dom,selector){var i ,len=dom?dom.length:0for (i=0;i<len;i++){this[i]=dom[i]}this.length=lenthis.slector=selctor||''}zepto.Z=function(dom,selector){}zepto.init=function(selector){var slice=Array.prototype.slicevar dom = slice.call(document.querySelectorAll(selector))return zepto.Z(dom,selector)}var $=function(selector){return zepto.init(selector)}window.$=$$.fn={css:function(key,value){},html:function(){}}Z.prototype=$.fn})(window)
(funciton (window){var jQuery=function(selector){return new jQuery.fn.init(selector)}jQuery.fn={css:function(){},html:functin(){}}var init=jQuery.fn.init=funciton(selector){var slice=Array.prototype.slicevar dom=slice.call(document.queryselctorAll(selector))var i,len=dom?dom.length:0for(i=0;i<len;i++){this[i]=dom[i]}this.length=len;this.slector=selector||''}init.prototype=jQuery.fn})(window)
原型如何体现他的扩展性
异步
题目
什么是单线程,和异步有什么关系
- 单线程:同时只能做一件事情,两端JS不可以同时执行
- 原因为了避免DOM渲染冲突
-
什么是eventloop
事件轮询,JS异步的解决方案
- 是么是异步队列,何时被放入异步队列
-
jQuery的Deferred
jQuery1.5对ajax的改变举例
- 简单封装,使用Deferred
promise和Deferred的区别
基本语法
- 如何捕获异常
- 多个串联-链式执行的好处
- Promise.all和Promise.race
-
介绍一下async/await(和Promise的区别、联系)
基本语法
- 使用了Promise,并没有和Promise冲突。
- 完美的同步写法,再也没有回调函数。
-
总结当前JS异步解决方案
jQuery Deferred
- Promise
- Async/Await
- Generator
- 原理比较复杂,学习成本高,调试成本,线上风险
- 不是异步的直接替代方式
- 有更好的解决方案async/await
单线程
单线程:只有一个线程,同一时间只能做一个事情
- 循环运行期间,JS执行和DOM渲染时卡顿,(1e9 次可能会卡死)
-
原因:避免DOM渲染的冲突
浏览器需要渲染DOM
- JS可以修改DOM结构
- JS执行的时候,浏览器渲染DOM会暂停
- 两段JS不能同时执行(都修改DOM就冲突了)
- webworker支持多线程,但是不呢个访问DOM
解决方案:异步
console.log(100)setTimeout(funciton(){console.log(200) // 1000ms之后执行,先不管它,先执行其他JS代码运行},1000)console.log(300)console.log(400)// 比如ajax加载完才执行,先不管他,先运行其他JS代码
JS异步和谐高效的解决方案
问题
- 未按照书写顺序执行,可读性差。
- callback中不容易模块化
什么是event-loop
- 单线程:同一时间制作一件事
- 原因:避免DOM渲染冲突
- 解决方案:异步
- 实现方式event-loop(时间轮询),JS实现异步的具体解决方案。
event-loop
- 同步代码,直接执行。
- 异步函数放在异步队列中
- 待同步函数执行完毕,轮询执行异步队列的函数。
```javascript
$.ajax({
url:’xx’,
success:funciton(){
} }) setTimeout(function() {// ajax加载完成才被放入异步队列
console.log(1) },100) setTimeout(function() { console.log(2) }) console.log(3)
// 立刻放入
function() {
console.log(2)
}
// 100ms后放入
function() {
console.log(1)
}
// js会一致轮询异步队列,如果有就执行
setTimeout是多少时间之后再放入<a name="HvMxr"></a>##### 回顾- 事件轮询,JS实现异步的具体解决方案。- 同步代码,直接在主进程中直接执行。- 异步函数,放在异步队列中,有延迟的,等待延迟结束才放入,有ajax的是等待ajaxa加载完成之后才放到异步队列中。- 待同步函数执行完成,轮询执行异步队列的函数。<a name="wTjOg"></a>### jQuery Deferred<a name="YKSQW"></a>#### jQuery1.5的变化- 1.5之前,是传递回调函数- 1.5之后```javascriptvar ajax=$.ajax('xxx.json');ajax.done(function(){console.log('success1')}).fail(function(){console.log('error')}).done(function(){console.log('success2')})console.log(ajax) // 是一个Deferred对象
- 无法改变JS异步和单线程的本质
- 只能从写法上杜绝callback这种代码形式
- 它是一种语法糖,但是解耦了代码
- 很好的体验:开放封闭原则。
使用jQuery Deferred
```javascript // 给出一段非常简单的异步操作代码,使用setTimeout var wait= function (){ var task=function(){ajax.then(funciton(){console.log('success1')},function(){console.log('fail1')}).then(funciton(){console.log('success2')},function(){console.log('fail2')})
} setTimeout(task,2000) }console.log('执行完成')
wait()
// 新增,在执行完之后进行某些特别复杂的操作,代码可能会有很多,而且要分好几个步骤,
```javascriptfunciton waitHandler(){var dtd=$.Deferred()var wait= function (dtd){ // 要求传入一个deferred对象var task=function(){console.log('执行完成')dtd.resolve() // 异步任务已经完成// dtd.reject() // 异步任务失败或出错}setTimeout(task,2000)return dtd // 要求返回一个deferred对象}return wait(dtd)}var w= waitHandler()w.then(function(){},function(){}).then(function(){},function(){})会err1,ok2//还有w.done w.fail。
总结
- dtd的API分成两类
Promise基本使用和原理
Bluebird 是一个第三方 Promise 规范实现库,它不仅完全兼容原生 Promise 对象,且比原生对象功能更强大
基本语法
result.then(function(img){console.log(1,img)return img},function(){console.log('error)}).then(function(img){console.log(2,img)}
异常捕获(Error和reject都要考虑)
异常捕获时,
每个then只接受一个参数,最后统一用catch捕获异常
result.catch(function(ex){// 最后统一catchconsole.log(ex)})
多个串联
链式操作 ```javascript var result1=loadImg(src1); var result2=loadImg(src2);
result1.then(function(img){ console.log(‘第一个图片加载万层’) return result2 }).then(function(img){ console.log(“第二个图片加载完成”) }).catch(()=>{
})
<a name="ZaTyu"></a>#### Promise.all和Promise.race<a name="XVb72"></a>#### Promise标准- 状态变化- 三种状态:pending fulfilled rejected- 初始状态时pending- pending变为fulfilled或者pending变成rejected- 状态变化不可逆- promise实例必须实现then方法- then()方法必须接受两个函数作为参数- then()方法返回的必须是一个Promsie实例。如果then里没有return```javascriptvar result=loadImg(src)result.then(function(img){console.log(img.width) // 没有return,返回的就是本身}).then(function(img){console.log(img.height)})
介绍async/await
用了Promise的特性做了改进
then只是将callback拆分了
本质上还是callback的写法
var w = waitHandler()w.then(function(){console.log('ok1');},function(){console.log('err1')}).then(function(){console.log('ok2');},function(){console.log('err2')})
const load=async function(){const result1=await loadImg(src1)console.log(result1)const result2=await loadImg(src2)console.log(result2)}
asyn/await是最直接的同步写法
- 使用await,函数必须用async标识
- await后面跟的是一个Promise实例
- 需要babel-polyfill
