var---可重复定义,不能限制修改,没有块级作用域
let---不能重复定义,变量+块级作用域
const---不能重复定义,常量+块级作用域(引用类型可以增加属性)
解构赋值
左右两边必须一样,右边必须是个东西(let {a,b}={1,2}这样就不行)
定义和赋值必须一起完成(let a;a=1这样会报错)
箭头函数
有且只有1个参数时,()可以省,有且只有一个函数返回值,{}可以省(let show=a=>a*3)
默认参数(a=xx,b=xxx,c=x)
箭头函数踩坑:简单对象(非函数)是没有执行上下文的!this会指向window
参数展开
function show(a,b,...c){console.log(a,b,c);} show(1,2,3,4,5,6)//1,2,[3,4,5,6]剩余参数必须在末尾
'...'的作用:
接收剩余参数,展开一个数组:
let arr=[1,2,3];let arr2=[4,5,...arr,6];//[4,5,1,2,3,6] console.log(...[2,3]);//2 3 console.log(...[1,2],...[3,4]);//作用同concat,输出1 2 3 4 let xy=[..."es6"]; console.log(xy);//["e", "s", "6"]es6支持
chrome,safari,firefox,ie10+
数组
map
let arr = [1, 2, 3, 54, 634, 235, 324]; let arr3 = arr.map(item=> item >= 60 ) console.log(arr3)//[false, false, false, false, true, true, true]filter
let arr4 = arr.filter(item => item >= 60)//[634, 235, 324]reduce
sum = arr.reduce((prev, cur, index) => {return prev + cur}) console.log(sum)//1253forEach
let sum = 0; arr.forEach(item => sum += item) console.log(sum)//1253from
Array.from();从一个类似数组或可迭代对象中创建一个新的数组实例
JSON
名字和值一样,只写一个
例如:let a=1,b=2; let json={a:a,b:b}可写成 let json={a,b}
function可以简写---function show(){}--->show(){}
字符串
植入变量,保留换行
let json = { name: 'aa', age: 18 } console.log(`name:${json.name} age:${json.age}`)//name:aa // age:18继承
super把属性带到子类去 ,extends把方法带到子类,里面可以定义内部类
class Person { constructor(name, age) { this.name = name; this.age = age; class a {//内部类 constructor() { console.log('ejjyjte'); } } new a();//ejjyjte } showName() { console.log(this.age) } } let p = new Person('aaa', 13); p.showName();//aaa class Child extends Person { constructor(name, age, job) { super(name, age)//等同于Person.constructor(name, age) this.job = job; } showJob() { console.log(this.job) } } var child = new Child('aa', 13, 'ee'); child.showName();//aa child.showJob();//eebind:给函数定死一个this,bind无法改变箭头函数的作用域
var foo={x:3}; var fun=function (){return console.log(this.x)}; fun()//undefined var fun2=fun.bind(foo); fun2()//3 var foo={x:3}; var fun=()=>{return console.log(this.x)}; fun()//undefined var fun2=fun.bind(foo); fun2()//undefined参考链接:用bind方法保持this上下文
箭头函数的this根据环境而定,它在哪它的this就是谁,bind无法改变箭头函数的作用域
arr=[1,2,3] arr.a = function() { console.log(this) } arr.a();//[1,2,3,a:f] arr=[1,2,3] arr.a = ()=>{ console.log(this) } arr.a();//windowPromise
用同步的写法实现异步
let pro = new Promise((resolve, reject) => { $.ajax({ url: '1.txt', dataType: 'json', success(json) { resolve(json); }, error(err) { reject(err); } }) }) pro.then(json => { console.log('成功') }, err => { console.log('失败') }); <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>promise</title> <style></style> <script> window.onload = function() { let checkLogin = () => { return new Promise((resolve, reject) => { let flag = true; if (flag) { resolve({ status: 1, result: true }) } else { reject('error') } }) } let getUserId = () => { return new Promise((resolve, reject) => { resolve({ userId: 'gfdgfg' }) }) }; checkLogin().then((res) => { if (res.status == 1) { console.log("success"); return getUserId(); } }).catch((e) => { console.log("error" + e); }).then((res2) => { console.log(`userId:${res2.userId}`); }); Promise.all([checkLogin(), getUserId()]).then(([res1, res2]) => { console.log(`result1:${res1.result},result2:${res2.userId}`); }) } </script> </head> <body></body> </html>上面的连续两个then中,第一个then方法指定的回调函数,返回的是另一个Promise对象。这时,第二个then方法指定的回调函数,就会等待这个新的Promise对象状态发生变化。如果变为resolve,就输出相应的值
Promise.all用法
let p1 = new Promise((resolve, reject) => { $.ajax({ url: '1.txt', dataType: 'json', success(json) { resolve(json); }, error(err) { reject(err); } }) }); let p2 = new Promise(...); //这里不写了 let p3 = new Promise(...); Promise.all([p1, p2, p3]).then(arr => { let [j1, j2, j3] = arr; console.log(j1, j2, j3) }, (err) => { console.log('失败') });
$.ajax本身就是promise对象,可以这么用:
$.ajax({ url: '1.txt', dataType: 'json' }).then(json => { console.log('成功') }, res => { console.log('失败') });所以多个ajax请求可以写成
Promise.all([ $.ajax({ url: '1.txt', dataType: 'json' }), $.ajax({ url: '2.txt', dataType: 'json' }), $.ajax({ url: '3.txt', dataType: 'json' }) ]).then(arr => { let [j1, j2, j3] = arr; console.log(j1, j2, j3) }, (err) => { console.log('失败') })promise不好处理带逻辑的异步操作
Promise.all()//全部成功
Promise.race()//有一个成功就成功
generator
generator不能写箭头函数
function* myshow() { console.log(1); yield; console.log(2); } let gen = myshow(); gen.next(); //1 gen.next(); //2yield可以传值,可以返回
//传值 function* myshow() { console.log(1); let a = yield; console.log(2, a); } let gen = myshow(); gen.next(); //1 gen.next(16); //2,16 //返回值 function* myshow() { console.log(1); yield 55; console.log(2); return 77; } let gen = myshow(); let r1 = gen.next(); console.log(r1); //{value: 55, done: false} let r2 = gen.next(); console.log(r2) //{value: 77, done: true}async和await
async function(){
...
let 变量=await 异步操作--promise/generator/另一个async函数
...
}
问:async / await会阻塞进程吗?
答:
例如代码:
async function aa(){ await ....; await ....; await ....; console.log("ccc"); }; console.log("aaa"); aa(); console.log("bbb");上例中,function aa里面会产生阻塞,但是不影响外面的代码,所以如果aa()要等很久才能处理完,那执行的顺序的是:
console.log("aaa");---------------》console.log("bbb");--------->console.log("ccc");
参考文档:
async function
理解 JavaScript 的 async/await
深入理解async / await-----重点看阻塞问题
function sleep(sec) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(); }, sec * 1000); }) }; async function show3() { // console.log(1); alert(1) await sleep(1); // console.log(2) alert(2) await sleep(2); // console.log(3) alert(3) } show3(); //先弹出1,等1秒弹出2,再等2秒弹出3
async/await完成ajax带逻辑的操作:
(async function() { let data1 = await $.ajax({ url: '1.txt', dataType: 'json' }); if (data1.a + data1.b > 10) { let data2 = await $.ajax({ url: '2.txt', dataType: 'json' }); console.log(data2[0]) } else { let data3 = await $.ajax({ url: '3.txt', dataType: 'json' }); console.log(data3.name); } })()async/await错误处理:
async function show4() { try { let data1 = await $.ajax({ url: '1.txt', dataType: 'json' }); let data2 = await $.ajax({ url: '2.txt', dataType: 'json' }); let data3 = await $.ajax({ url: '3.txt', dataType: 'json' }); console.log(data1, data2, data3) } catch (e) { console.log('有问题') } }
import export:
//export.js export let sum=(x,y)=>{return x+y;} } export let minus=(x,y)=>{return x-y;} } //方法一:import1.js import {sum,minus} from './export' console.log(`sum:${sum(1,6)}`); console.log(`minus:${minus(1,6)}`); //方法二:import2.js import * as cal from './export' console.log(`sum:${cal.sum(1,6)}`); console.log(`minus:${cal.minus(1,6)}`);
AMD CMD CommonJs ES6的导入导出对比:
AMD是RequireJs在推广过程中对模块定义的规范化产出----依赖前置,我需要用的时候,我先在前面给定义好,然后再在回调里进行加载和引用
define(['package/lib'],function(lib){//需要依赖lib库,就通过['package/lib']加载库,通过回调函数接受lib参数,获取lib的一些方法 function foo(){ lib.log('hello world!'); } return { //通过return输出 foo:foo }; })
CMD是SeaJs在推广过程中对模块定义的规范化产出---依赖就近,哪个地方用,就在哪里引入,同步
define(function (requie, exports, module) { //依赖可以就近书写 var a = require('./a'); a.test(); if (status) { var b = requie('./b'); b.test(); } });
CommonJS规范,通过module.exports(不带名字的输出)和exports(带名字的输出)输出,通过require/import加载,是node.js后端使用的
exports.area=function(r){ return Math.PI*r*r; }:
es6:通过export/import导入导出