一、ES6简介
ES6是说明新的JavaScript标准
二、变量声明
1、var
(1)var 定义的变量存在变量提升
(2)var定义的变量不存在块级作用域
(3)var可以重复声明变量
2、let
(1)let与var基本一致,用作变量声明
(2)let在一堆大括号{}中形成局部作用域
(3)let声明的变量只在作用域内起作用
(4)let不能在同一个作用域内重复声明
(5)let存在暂时性死区:只要块级作用域内存在let命令,它所声明的变量就“绑定”在这个区域,不再受外部的影响
3、const
(1)与let一致(局部作用域,不存在变量声明提升,不能重复声明)
(2)const声明变量时必须赋值
(3)const定义的变量,不能修改(即值得类型)
(4)建议,在声明变量时,变量名大写
三、数组和对象的解构
1、数组的解构
// 把数组解析为单个的变量
// 可以逗号跳过某个元素
let arr = [1, 2, 3, 4, 5];
let [a, , b, ...c] = arr;
console.log(a);
console.log(b);
console.log(c);
// 可以给默认值
// 通过...接收剩余内容(不定参)
let arr2 = [1, 2, 3, 4];
let [d, e, f, g = 22] = arr2;
console.log(d, e, f, g);
// 可以交换变量
var i = 100;
var j = 50;
[i, j] = [j, i];
console.log(i, j);
2、对象的解构
// 把对象解析为单独的变量
// 不用按顺序解构
let obj = { name: "aaa", age: 12, job: "教师" };
let { age, name, job } = obj;
console.log(age);
console.log(name);
console.log(job);
四、箭头函数
1、箭头函数:
函数的简写
var fun = function () {
alert("love");
}
var fun1 = () => alert("love");
// =>左侧是参数
// =>右侧是执行语句也是返回值
fun();
fun1();
2、如果不是一个则需要添加()
var fun2 = (name, age) => alert("大家好,我是" + name + ",今年" + age + "岁");
fun2("xxx", 23);
3、如果有多行语句用{}
var fun3 = item => {
if (item > 18) {
alert("可以参军");
} else {
alert("小屁孩一个");
}
}
fun3(19);
4、如果需要返回对象用({})
var fun4 = (name, age) => ({
name: name,
age: age,
msg: "大家好我是" + name
})
var obj = fun4("小小怪", 17);
console.log(obj);
5、箭头函数中this的指向问题
箭头函数的this指向的是上一层函数调用者,不能作为构造函数
var age = 50;
var obj = {
age: 18,
grow: () => {//此处不为箭头函数,是function普通函数时需要注意,情况就不一样了
setInterval(() => {//此处同上,会有一些小陷阱,需要注意
this.age++;
console.log(this.age);
}, 3000)
}
}
// obj.grow();
var arr = [2, 4, 6, 7, 8,];
var arr1 = arr.filter(item => item > 5);
console.log(arr1);
var total = arr.reduce((a, b) => a + b);
console.log(total);
var arr2 = arr.map(item => item * 10);
console.log(arr2);
五、ES6新增的字符串方法
1、遍历:forEach
var arr1 = ["小红", "小蓝", "小子", "小黑"];
arr1.forEach(function (item, index, self) {
console.log(item, index, self);
})
2、查找:includes、startsWith、endsWith
var str = "假如把范得起的错,能错的都错过,应该还来得及去悔过";
//includes:查找是否包含
alert(str.includes("错"));
//查找是否已XXX开头
alert(str.startsWith("假如"));
//查找是否已XXX结尾
alert(str.endsWith("过"));
//查找存在返回true,否则返回false
3、补齐:padStart(len,symbol)、padEnd(len,symbol)
len:需要补齐的长度
symbol:用什么补齐
var a = "1";
console.log(a.padStart(3, "0"));//输出结果001
console.log(a.padEnd(4, "0"));//输出结果10000
4、去空白trim、trimLeft、trimRight
var b = " 132 ";
console.log(b);
//去除两侧空白
console.log(b.trim());
//去除左侧空白
console.log(b.trimLeft());
//去除右侧空白
console.log(b.trimRight());
六、数组新增方法
1、排序:sort
arr1 = [1, 12, 15, 33, 7, 9]
arr1.sort((a, b) => a - b);//a-b升序,b-a降序
console.log(arr1);
//运行结果[1,7,9,12,15,33]
2、查找:find、findIndex
find:查找符合条件的元素
findIndex:查找符合条件的元素的下标
var arr = [2, 4, 6, 8];
var el = arr.find(function (item) {
if (item > 5) {
return true;
}
})
var el2 = arr.find(item => item > 5);
console.log(el);
console.log(el2);
var index = arr.findIndex(function (item) {
if (item > 5) {
return true;
}
})
console.log(index);
3、过滤:filter
var arr2 = arr.filter(function (item) {
return item % 2 == 0;
})
console.log(arr2, arr);
## 4、遍历:forEach
var arr1 = ["小红", "小蓝", "小子", "小黑"];
arr1.forEach(function (item, index, self) {
console.log(item, index, self);
})
//item:当前遍历的元素
//index:当前元素得到下标
//self:被遍历的数组
5、映射:map
//通过数组arr得到数据ages
var arr = [
{
name: "小明",
age: 16,
sex: "男"
},
{
name: "小红",
age: 17,
sex: "女"
},
{
name: "小白",
age: 18,
sex: "女"
}
]
var ages = arr.map(item => item.age)
console.log(ages);
6、累计:reduce
reduce(function (a, b) {
return a + b
})
// a:上一次返回的结果
// b:当前遍历的元素
7、some和every
some:都不符合条件返回false,有一个满足返回true,且剩下不再进行检测,返回值为布尔值
every:检测数组所有元素是否满足指定条件,所有元素都满足返回true,一个不满足返回false,且剩下元素不再进行检测,返回值为布尔值
//数组是否有一个大于16岁,是否所有小于60岁
var computers = [
{ name: "Apple", age: 8 },
{ name: "IBM", age: 12 },
{ name: "Acer", age: 32 },
]
var big = computers.map(item => item.age);
var a = big.some(item => item > 16);
if (a) {
alert("有一个大于16岁");
}
var b = big.every(item => item < 60);
if (a) {
alert("所有都小于60岁");
}
七.modul模块
- 解决变量冲突,如果变量都定义在全局作用域中,难免会冲突,模块独立成各自作用域
- 将复杂的业务封装成一个个模块,业务逻辑更清晰
- 模块可以控制暴露什么,不暴露什么(内部调用),可以引入其他模块
导出:
//默认:
function format(date) {return date.toLocaleString();};export default format;
export function reverse(str){}
//导出变量:
export const PRISE = 500;
//先声明再导出
export {name,say}
1
2
3
4
5
6
7
导入:
<script type="module">
import format from ‘相对路径’(format可以和导出的时候不一致)
import {reverse} from ‘相对路径’(reverse要和源文件方法一致)
//导入所有
import * as utils from '相对路径';
utils.say();
utils.reverse("我喜欢你")
utils.default(new Date())
</script>
1
2
3
4
5
6
7
8
9
导入别名
import {reverse as r} from ‘相对路径’
1
默认和普通方法是一个文件
import format, { reverse as c, PRISE ,name ,say } from '相对路径';
1
八.ES6新增数据类型
1.set:集合(不重复的数组)
set对应的方法:
- add:添加
- delete:删除
- clear:清空
- size:大小
2.map:图(键名可以是任何类型的对象)
map对应的方法:
- set(key,value):设置
- get(key):获取
- delete:删除
- clear:清空
- size:大小
- has:检测
- […newSet(arr)]:去重
- symbol:符号(唯一的符号)
- weekSet:值是引用类型
- weekMap:值是引用类型
九.ES6新增类
由于type of class:检测的结果是function,所以类的本质是函数
- 语法:class Block{ }
- 构造函数:constructor(){}
实例化的时候 new 关键字调用的就是构造函数
- super():调用父类的构造函数
- extends:继承父类的方法
- static:类的静态属性和方法
类的this指向的是它的实例(也就是new出来的对象)
十.ES6的迭代类型
可以for of遍历的对象都是可迭代对象 如:String字符串、Array数组、Set集合、Map图
for(let v of myset)
for(let k of myArr.keys())
for(let v of myArr.values())
for(let [k,v] of myArr.entriess())
Promise
// promise承诺 reject拒绝 resolve兑现
var p = new Promise((resolve, reject) => {
var n = Math.random();
setTimeout(() => {
if (n > 0.5) {
resolve('买');
} else {
reject('不买')
}
}, 2000)
})
console.log(p);
// 承诺3个状态 pending准备 rejected拒绝 resolved兑现
// 状态发生变化就不能更改
//.then回调函数拿到的是resolved兑现结果的状态
//.catch回调函数拿到的是rejected拒绝的理由
p.then(res => {
console.log(res);
}, err => console.error(err))
// p.then(res => {
// console.log(res);
// })
// .catch(err => console.error(err))
三个状态:pendding、resolved、rejected,状态的变化不可逆
all(全部)
function downImg(url) {
//返回promise
return new Promise((resolve, reject) => {
//创建img标签
var img = document.createElement("img");
//指定src
img.src = url;
//加载成功返回图片
img.onload = function () {
resolve(img);
}
//加载失败返回错误原因
img.onerror = function (err) {
reject(err);
}
})
}
//同时加载三张
var urls = [
"https://img.alicdn.com/imgextra/i4/6000000006083/O1CN01tdjfJP1uo430zVbdp_!!6000000006083-2-octopus.png",
"https://img.alicdn.com/imgextra/i1/6000000001569/O1CN0108sLbY1NSeCvAJtPL_!!6000000001569-0-octopus.jpg",
"https://img.alicdn.com/imgextra/i3/6000000002368/O1CN01lbQxeC1TMafHbjdvd_!!6000000002368-0-octopus.jpg"
];
//Promise.all 在promise参数列表中所有的promise,resolve才会reslove
Promise.all(urls.map(item => downImg(item)))
.then(res => {
console.log(res);
for (var k of res) {
document.body.appendChild(k);
}
})
.catch(err => {
console.error(err);
})
race(返回最先resolve的结果)
function downImg(url) {
//返回promise
return new Promise((resolve, reject) => {
//创建img标签
var img = document.createElement("img");
//指定src
img.src = url;
//加载成功返回图片
img.onload = function () {
resolve(img);
}
//加载失败返回错误原因
img.onerror = function (err) {
reject(err);
}
})
}
//同时加载三张
var urls = [
"https://img.alicdn.com/imgextra/i4/6000000006083/O1CN01tdjfJP1uo430zVbdp_!!6000000006083-2-octopus.png",
"https://img.alicdn.com/imgextra/i1/6000000001569/O1CN0108sLbY1NSeCvAJtPL_!!6000000001569-0-octopus.jpg",
"https://img.alicdn.com/imgextra/i3/6000000002368/O1CN01lbQxeC1TMafHbjdvd_!!6000000002368-0-octopus.jpg"
];
Promise.race(urls.map(item => downImg(item)))
.then(res => {
document.body.appendChild(res);
})
.catch(err => {
console.error(err);
})
实例P
//实例p
.then(res=>{})
//回调函数获取resolved返回的结果
//返回一个新的promise实例
.catch(err=>{})
//获取rejected的原因
十一.异步和同步
1.异步
异步是先执行主线程的代码,再执行其它线程(非阻塞式)
实现异步的方式
- 回调函数
- 事件响应
- 订阅发布模式
- Promise
- sync和await
2.同步
同步是按顺序从上至下阻塞式执行代码(上一行代码不执行完毕,下行是不会执行)
-
async与await
-
async装饰的函数,返回的是一个promise对象,返回的结果是resolved的结果 -
await用来等待异步中的resolve结果,只能出现在async装饰的函数中
-
async function doit(){
var m1 = await say("你笑起来真好看",2000);
var m2 = await say("像春天的花一样",3000);
return m1 + m2;
}
doit()
.then(res => {})
.catch(err => {})
//例:
function say(msg, delay) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(msg), delay);
})
}
async function doit() {
var m1 = await say("国庆快乐!", 2000);
console.log(m1);
var m2 = await say("祝祖国越来越繁荣昌盛", 3000);
console.log(m2);
return "举国欢庆!";
}
doit()
.then(res => console.log(res))
十二.generator生成器
就是在函数前面加个*
function *range(min,max){
for(var i = min; i < max; i++){
yield;
}
}
//生成器执行的结果是一个迭代器
var iter = range(1,10)
//迭代器通过next方法返回一个对象,对象的value是yield生成的结果,在生成器里面遇到yield就停止等待下一次next调用
//结果
{value:1,done:false}
...
{value:undefined,done:false}
可以通过for来遍历迭代器 可以是String,Array,Set,Map的迭代器
for(var v of fange (1,100){
console.log(v);
})
1
2
3
arr[Symbol.iterator]()
Object.defineProperty
Object.defineProperty(obj,props,{
set(v){
//设置
},
get(){
//获取
},
configurable : true,//是否能删除
enumberable : true,//是否可以枚举
value,//默认值
writable : true,//是否可写
...
})
//例:
// vue2响应式原理 Object.defineProperty 结合订阅发布模式,通过观察者链接视图与数据
// Object.defineProperty 劫持对象的getter与setter
// Object对象 define订阅 Proterty属性 throw抛出
var obj = { _age: 18 };
Object.defineProperty(obj, "age", {
get() {
return this._age;
},
set() {
if (v > 200 || v < 1 || isNaN(v)) {
throw "年龄设置错误"
} else {
this._age = v;
}
}
})
十三.proxy代理对象
//要被劫持的对象
var obj = {
price: 100
}
//处理器
var handle = {
get(target, property) {
//对obj对象进行get或者set的劫持
console.log(new Date().toLocaleString(), "又在看钱包了");
//target目标处理对象
},
set(target, property, value) {
target[property] = value;
console.log(("我的钱包变成了" + value));
}
}
//生成代理对象 proxy
var proxy = new Proxy(obj, handle)