ES6基础

2,122 阅读6分钟

一、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图

forlet v of myset)
forlet k of myArr.keys())
forlet v of myArr.values())
forlet [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)