es6最新语法(包含promise,generator函数,async函数以及axios异步操作)
1. 企业级开发es6 + 企业级框架vue1) 项目结构取决于脚手架(vue-cli)$ vue create zhaopinnode_modulespublicsrcdist()2) 脚手架中存在静态服务器$ yarn serve3) 打包$ yarn build4) 项目版本控制git/svn5) 部署
2. es6学习环境linux nodejs vi1) vi hello.js2) node hello.js
3. 模块化机制(CommonJS)1) 模块定义任意一个js文件或者目录都可以为一个模块在模块文件中,都有一个module对象表示当前模块idfilename 路径+文件名parent 父模块children 子模块paths 路径exports 【模块向外暴露的接口】2) 模块引用require("")参数:1) 路径require("./module1")按照指定的路径加载所需的模块2) 模块名称require("module1")按照paths中的路径依次寻找所需模块,直到找见为止node_modules用户存放模块(第三方)4. npm (node package manager) $ npm init在当前目录下产生一个package.json,这个文件是当前模块的核心配置文件,记录 模块的基本信息,依赖信息,脚本信息$ npm install xxx --save本地安装xxx模块,默认将xxx安装到当前目录下的node_modules目录中,如果当前目录没有node_modules会自动创建,--save表示这个xxx模块是一个产品依赖,维护在package.json 中的dependecies属性$ npm install xxx -g全局安装xxx模块,默认会将xxx安装到node的安装目录中/opt/node-v10.14.2/lib/node_modules/opt/node-v10.14.2/bin/opt/node-v10.14.2/share效果:全局安装的模块可以在命令行中直接调用,一般用于命令行工具的安装,比如cnpm,babel-cli,vue-cli,create-react-app的安装5. cnpmnpm淘宝镜像1) 安装$ npm install -g cnpm --registry=https://registry.npm.taobao.org报错:EACCES: permission denied, access '/opt/node-v10.14.2/lib/node_modules/cnpm/node_modules/address'原因:当前用户是普通用户,但是全局安装需要将第三方依赖安装到/opt/xxx,没有权限!解决方案:sudo npm 失败将/opt/node-v10.14.2/lib/node_modules/opt/node-v10.14.2/bin/opt/node-v10.14.2/share的拥有者变为当前用户(larry)$ sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share} $ sudo chown -R larry /opt/node-v10.14.2/{lib/node_modules,bin,share} 2) 使用使用方式与cnpm完全一致,只不过原先用npm现在用cnpm6. babel将es6转换es5,仅仅是语法上的转换,对于功能的增强则无法提供,需要添加babel-polyfill,另外不支持模块化的合并,如果需要合并模块还需要webpack支持。1) 全局安装babel-cli$ cnpm install babel-cli -g$ babel --version6.26.0 (babel-core 6.26.3)2) 在项目的根目录中安装bebel预设$ cnpm install babel-preset-es2015 --save-dev 3) 在项目的根目录中添加.babelrc的配置文件{"presets":["es2015"]}7. 变量的声明1) var 可以重复声明 var a = 3; var a = 4;变量的声明会提升没有局部作用域 for(var i=0;i<=100;i++){}console.log(i);2) let 声明一个变量不可以重复声明变量的声明不会被提升,也就是说在变量声明之前不能调用这个变量具有局部作用域3) const 声明一个常量不可以重复声明变量的声明不会被提升,也就是说在变量声明之前不能调用这个变量具有局部作用域常量的值无法改变const a = 3;a++;4) 解构1. 对象解构从一个对象或者数组或字符串中【匹配】出来若干个值分别保存到不同变量中let obj = {name:"terry",age:12,gender:"male"}//let {name:name,age:age,gender:gender} = obj;let name = "charles";let {name:nn,gender,address} = obj;console.log(name,nn,address,gender);let {address:{city}} = {realname:"larry",address:{province:"江西省",city:"南昌市",area:"青山湖区"}}console.log(city);默认值function get({url,method="get",data={},success}){console.log('url',url);console.log('method',method);console.log('data',data);console.log('success',success);}get({url:"http://xxx:6677",data:{id:1},success:function(){},method:"delete"})2. 数组的结构let [a,b,c,[d],e] = [1,2,3,[4,5],6,7,8];console.log(a,b,c,d,e);3. 字符串解构let [a,b,c] = "hello";console.log(a,b,c);let {length} = "hello"console.log(length);console.log("hello".length);8. 对象拓展1) 对象字面量的简写形式var age = 12;var obj = {name:"terry",age:age}=简写=>let name = "terry";let age = 12;let obj = {name, age }2) 对象api拓展var o = new Object();o 实例对象Object o的构造函数Object.prototype o的构造函数的原型,o的原型对象o可以调用Object.prototype中的方法,不能调用Object中的方法Object.prototype.toStringObject.prototype.valueOfObject.prototype.prototypeOfObject.prototype.hasOwnProperty...ES6对Object这个构造函数进行了拓展1. Object.is(o1,o2)对比o1与o2是否相等,如果相等返回true,类似于===2. Object.assign(target,o1,o2,...)3. Object.setPrototypeOf(obj,prototype)=> obj.__proto__ = prototype;4. Object.getPrototypeOf(obj)=> obj.__proto__5. Object.keys()6. Object.values()7. Object.entries()9. 函数拓展1) 函数简写1. 函数在对象中let obj = {sayName(){},sayAge(){},foo:()=>{}, //不推荐写法!bar:function(){}}2. 函数在参数中(回调函数)list.filter(function(item){return item.gender === "male"})等价于list.filter(item=>item.gender === "male")等价于function foo(){list.filter((item)=>{ //这个箭头函数中的this指向foo中的thisreturn item.gender === "male"})}let obj = {data:{name:"charles",list:[{name:"larry",gender:"male"},{name:"tom",gender:"male"},{name:"vicky",gender:"female"}],boys:[]},foo(){// this指向objlet that = this;this.data.list.forEach(function(item){//thisif(item.gender === "male"){that.data.boys.push(item)}})},bar(){this.data.list.forEach((item)=>{//箭头函数中的this指向外部函数的thisif(item.gender === "male"){this.data.boys.push(item);}})}}//obj.foo();obj.bar();console.log(obj.data.boys);12. rest操作符...剥离、拆分let o1 = {a:"1",b:"2"}let o2 = {c:"3",d:"4",e:"5"}Object.assign({},o1,o2){...o1,...o2}将字符串转换数组let str = "hello";let arr = [...str]str.split("")13. 集合的新特性存放多个值的容器1) Array元素有序并且可以重复的即可Array.from(v)v为类数组对象或可迭代的对象(具有迭代器的对象)let al = {"0":"terry","1":"larry","2":"tom",length:3}console.log(al);console.log(Array.from(al));Array.of()let array = Array.of(2) //[2]let array = Array.of(2,3,4) //[2,3,4]Array.prototype.fill()Array.prototype.includes()Array.prototype.find(匿名函数)Array.prototype.findIndex(匿名函数)查找到第一个符合条件的值进行返回,与filter类似Array.prototype.keys() 获取遍历key值的迭代器Array.prototype.values() 获取遍历val的迭代器Array.prototype.entries() 获取遍历键值对的迭代器let arr = [{name:"terry", gender:"male"},{name:"larry", gender:"male"},{name:"vicky", gender:"female"}]let k_iterator = arr.keys();// 如何利用k_iterator获取arr中的每个元素let item ;while(!(item = k_iterator.next()).done){let key =item.value;let val = arr[key];console.log(val);}2) Set元素无序不可以重复的集合1. 实例化let s1 = new Set()let s2 = new Set([1,2,3,4,1,2])参数必须是可以迭代的2. Set.prototype.xxxsizeadd(v)delete(v)has(v)clear()forEach()keys() 获取值的迭代器 values() 获取值的迭代器entries() 获取值-值的迭代器3) Map键值对,键可以为任意数据类型;与对象对比其特点为key可以为任意数据类型1. 实例化let map = new Map();let map = new Map([["name","terry"],["age",12]])2. Map.prototype.xxxsizeset(key,val) key值如果相同,后者覆盖前者get(key)has(key)delete(key)clear()forEach()keys()values()entries()3. 典型应用(购物车)
Map {id:{id,name,price,number}}加入购物车:{id:1,name:"可口可乐",price:2.5number:1}先判断购物车中是否具有id为1的key,如果有,修改number,如果没有setlet shopcar = {car:new Map(),add(line){if(this.car.has(line.id)){this.car.get(line.id).number += line.number;}else {this.car.set(line.id,line)}},remove(id){this.car.delete(id)},jiezhang(){let total = 0;for(let i of this.car.values()){total += (i.price * i.number)}return total;}}// 首次向购物车中添加可口可乐shopcar.add({id:1,name:"可口可乐",price:2.5,number:1})// 再向购物车中添加可口可乐shopcar.add({id:1,name:"可口可乐",price:2.5,number:1})
// 首次向购物车中添加北京方便面
shopcar.add({id:2,name:"北京方便面",price:1,number:1})
//shopcar.remove(1);
console.log(shopcar.car);
let total = shopcar.jiezhang();
console.log("总额为:",total);
14. 迭代器用于遍历的统一机制,这种机制允许我们调用next()方法,每次调用都会返回一个对象 {value,done},当完成迭代后done值为true,value每次获取的元素迭代器的使用1) 手动使用let iterator = array.values();let item ;while(!(item = iterator.next()).done){console.log(item.value);}2) 使用for-of协助let iterator = array.values();for(let v of iterator){console.log(v);}3.使用for-of直接遍历可以迭代对象for(let v of array){console.log(v);}谁具有迭代器?ArraySetMapString类数组对象 Arguments NodeList4. 如何将一个普通对象变成一个可以迭代的对象let obj = {name:"terry",age:12}// 如何获取一个迭代器obj[Symbol.iterator] = [][Symbol.iterator]// 将对象转换为setnew Set(obj)15. entry[[key,val],[key,val],...]16. 迭代器是如何添加到Set、Map、Array...这些数据结构上的?var o = {name:"terry",}o.iterator = iterator;o.iterator = "hello"Symbol()这个函数可以产生一个特殊符号,这个符号可以用于key,通过这个key找见对应的函数。这个key好处在于它是隐式的。17. Promise构造函数,用于创建一个承诺对象,承诺对象主要用于封装异步操作。承诺发起 承诺成功 resolved承诺失败 rejected1) 获取或者创建一个承诺对象let promise = new Promise(function(resolve,reject){})resolve 方法, 将承诺对象 pending -> resolvedreject 方法, 将承诺对象 pending -> rejected2) 使用承诺对象Promise.prototype.then(successHandler[,errorHandler])successHandler 当承诺成功的时候执行errorHandler 当承诺失败的时候执行一般不再then方法中添加errorHandler,而是将errorHandler放到catch中返回值为当前promise实例Promise.prototype.catch(errorHandler)errorHandler 当承诺失败的时候执行Promise.prototype.finally(handler)handler 不管承诺对象的状态变为什么样子,这个handler函数都会执行3) 高级特性1. Promise.all([p1,p2,...])将多个承诺对象合并为一个承诺对象,返回值为promisepromise.then((result)=>{//当所有的承诺都resolved的时候该回调函数才会执行// result 为每个承诺对象返回值组成的一个数组}).catch(()=>{//当有一个承诺对象rejected就会执行这个回调函数})当查询出所有顾客信息以及订单信息后打开模态框2. Promise.race([p1,p2,...])谁先执行完就是谁,返回值为promisepromise.then((result)=>{/先执行完的}).catch(()=>{//只要有一个承诺对象的状态变为rejected,就会执行该回调函数})3. Promise.resolve(v)将v转换为承诺对象4. Promise.rejected(v)返回一个状态为rejected的承诺对象// 基于回调函数的封装
get({url,success,error}){let xhr = new XMLHttpRequest();xhr.open("get",url);xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");xhr.responseType = "json"xhr.send();xhr.onreadystatechange = function(){if(this.readyState === 4){if(this.status === 200){//请求成功success(this.response)} else {//请求失败error(this)}}}}get({url:"",success:function(){},error:function(){}})
18. Generator函数(用于产生一个迭代器对象
)
Promise封装了异步操作
$.get("/customer/findAll")
.then((response)=>{
//通过回调函数来获取异步操作的结果
})
1) 声明
function* foo(){
let a = “hello”
yield a;
yield “world”;
return “end”
}
yield必须在generator函数中
2) 调用
let iterator = foo();
iterator.next() // {value:“hello”,done:false}
iterator.next() // {value:“world”,done:false}
iterator.next() // {value:“end”,done:true}
3) thisGenerator与普通函数中的this的获取是一致的4) yeild表达式的返回值默认是没有返回值的iterator.next(参数) 当前这个参数为上一个yield表达式的返回值5) 作用:1. Generator函数可以用于调用异步函数,将异步操作同步化 let customers = $.get("/customer/findAll");let customerId = customers[0].idlet address = $.get("/address/findByCustomerId?id="+Id)2. 迭代器将obj转换为可迭代器的对象obj[Symbol.iterator] = ""[Symbol.iterator]Generator的返回值就是迭代器对象let arr = [1,2,3];arr.values() 迭代器对象arr[Symbol.iterator] 生成迭代器对象的函数 课堂代码:
let obj = {"0":"terry","1":"larry","2":"tom"}obj[Symbol.iterator] = function* (){//完成迭代obj的工作for(let key in this){let val = this[key];yield [key,val];}}
19. Async函数是Generator函数的语法糖async function foo(){let customers = await $.get(url)let orders = await $.get(url)}let promise = foo()1) awaitawait表达式后一般为promise,await会等待promise状态改变resolved,然后将请求结果返回,最后继续向下运行通过id删除顾客信息
function deleteById(id){$.get(deleteById).then(()=>{alert("");$.get(findAll).then(()=>{重新渲染})})}
async版本
```javascript
async function deleteById(id){let result = await(deleteById,id);alert(result.message);await(findAll)}deleteById(1)
20. axios基于promise机制的纯粹的ajax框架0) 特点基于Promise运行在nodejs、浏览器自动转换request,response data(默认将请求数据转换为json)Content-Type:"application/json"拦截器1) ajax解决方案1) XMLHttpRequest原生的ajax2) jQuery.ajax()不涉及到数据驱动框架的时候使用3) axios涉及到数据驱动框架的时候react/vue/angular + axios在nodejs中可以使用2) 导入依赖1) 浏览器2) nodejsnpm install axios --save3) axios底层接口axios({url,method,data, // post请求的参数params, // get请求的参数baseURL, // 基础路径responseType:'json', //要求服务器端返回值类型为jsontransformRequest:[function(data,headers){return data;}], //在请求发送到服务器前可以改变datatransformResponse:[function(data){return data;}], //在响应数据到达then或者catch之前允许修改headers: {'X-Requested-With': 'XMLHttpRequest','Content-Type':"application/json"}, //异步操作paramsSerializer: function (params) {return Qs.stringify(params, {arrayFormat: 'brackets'})}, // get请求中,序列化params的函数,默认如上get请求中的params一般用查询字符串timeout:0, //超时设置,默认不设置withCredentials:false, // 设置是否携带浏览器cookieproxy:{host: '127.0.0.1',port: 9000,auth: {username: 'mikeymike',password: 'rapunz3l'}}, //代理xsrfXXX, //})axios(config) 返回值为promise对象4) axios快捷接口axios.get(url[,config])axios.get(url+"?id="+id)axios.get(url,{params:{id}})axios.post(url[,data][,config]) axios.post(url,{name:"terry"})5) Response Schemaaxios请求成功或者失败后默认会将服务器端的返回结果封装到一个新的对象,这个对象的数据结构:{data: {},status: 200,statusText: 'OK',headers: {},config: {},request: {}}6) 配置默认信息axios有一个属性defaults,在这个对象中配置的属性所有的axios对象都可以应用到axios.defaults.baseURL = "http://134.175.100.63:6677"axios.defaults.transformRequest = []axios.defaults.transformResponse = []axios.defaults.timeout = 10000;axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";axios.defaults.headers.common["Content-Type"] = "application/x-www-form-urlencoded";axios.get("/customer/findAll").then()axios.get("/order/findAll").then()axiox.post(url,data)默认情况下data对象转换为json7) 拦截器与transformRequest,transformResponse功能类似,可以在请求发送之前或者响应回来之后执行特定代码。但是transformRequest,transformResponse主要用于对参数的格式化或者是对响应结果的格式化,而拦截器主要用于业务上面的拦截,主要可以用于日志的记录,或者异常响应的统一处理...1. 请求拦截器axios.interceptors.request.use(function (config) {// 在请求发送之前可以配置config// ...return config;}, function (error) {// 在请求出现异常的时候,默认返回失败的承诺return Promise.reject(error);});2. 响应拦截器axios.interceptors.response.use(function (response) {// 一般在这里可以对响应结果进行处理// response.data 才是后台返回的结果剃 return response;}, function (error) {// 提示异常信息return Promise.reject(error);});21. 类构造函数 = 类类是构造函数的语法糖1) es5构造函数function Animal(name,age){this.name = name;this.age = age;}Animal.prototype.sayName = function(){console.log("my name is",this.name);}Animal.prototype.sayAge = function(){console.log("my age is",this.age);}//继承function Dog(name,age,gender){Animal.call(this,name,age)this.gender = gender;}Dog.prototype = new Animal();Dog.prototype.constructor = Dog;Dog.protype.sayGender = function(){console.log("my gender is",this.gender);}let d = new Dog("一休",2,"male");d.sayName()d.sayGender();2) 语法1. 类的声明class 类名 {constructor(构造函数形式参数){this.xxx = xxx;}xxx(){}yyy(){}}this表示当前构造函数的实例对象2. 类的继承class 子类名 extends 父类名 {constuctor(子构造函数形式参数){super(x,y)this.z = z;}}任意一个类如果你不提供构造函数,那么系统会为你自动分配一个构造函数,这个构造函数如下constructor(a,b,c){super(a)}super 是借用构造函数的语法糖3) this不管是构造函数还是普通方法,this都指向当前类的实例对象22. ES6的模块化1) CommonJS模块化module.exports = 暴露接口require(模块名称/路径)2) ES6模块化export 暴露的接口import {} from "模块名称/路径"1. 定义模块,通过export暴露接口module1.jsexport let a = 3;export function sayHello(){}index.jsimport {a,sayHello} from './module1'2. 定义模块,通过export default 暴露接口module1.jslet a = 3;function sayHello(){}export default {a,sayHello} index.jsimport module1 from './module1'module1.sayHello3. nodejs如何支持es6的模块化1) es6->es54. 案例:```javascript
module1.jslet name= "module1";// 单独暴露export function sayName(){console.log("my name is",this.name);}export function sayHello(){console.log("hello world");}index.jsimport {sayName} from './module1'
5. 案例
module1.jslet name= "module1";function sayAge(){},function sayGender(){}// 默认集体暴露export default {sayAge,sayGender}index.jsimport m from './module1'm.sayAge()
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
