es6
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)//1253
forEach
let sum = 0; arr.forEach(item => sum += item) console.log(sum)//1253
from
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();//ee
bind:给函数定死一个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();//window
Promise
用同步的写法实现异步
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(); //2
yield可以传值,可以返回
//传值
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");
参考文档:
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导入导出