深入解读ES6系列(全18讲)

505 阅读6分钟

视频地址:b站:深入解读ES6系列

1 . ES6怎么来的

  • ECMAScript 和 JavaScript
    • ECMAScript是标准,JavaScript 是实现
    • ES是ECMAScript的简称
  • 历史版本
    • 2015年ES6正式发布

2 . ES6兼容性

  • 支持 IE10+ ,Chrome ,FireFox ,移动端 ,NodeJS
  • 解决不兼容办法:Babel
    • 主要用于将 ES6 版本的代码转换为向后兼容的 JavaScript 语法,以便能够在当前和旧版本的浏览器或其他环境中运行

3 . let 和 const

  • var 最大的问题就是可以重复声明,并且没有报错和警告
var num = 111
var num = 222
console.log(num); // 打印结果222
  • var 第二个问题是没有办法可以控制一个值让它不发生改变,比如PI是固定的,这种不变的值我们称为常量
  • var 第三个问题没有块级作用域,什么叫块级作用域?用{}包起来的就叫语法块,在块{}内声明的变量在块{}外无效
if () {}
for () {}

  • let 变量-可以修改,不能重复声明,拥有块级作用域
    const 常量-不能修改,不能重复声明,拥有块级作用域
  • 小案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input type="button" value="button_1"></input>
    <input type="button" value="button_2"></input>
    <input type="button" value="button_3"></input>
</body>
<script>
    window.onload = function () {
        var btnArr = document.getElementsByTagName('input')
        console.log(btnArr);

        //问题:使用var,点击button_1弹出3,点击button_2弹出3,点击button_3弹出3
        for (var i = 0; i < btnArr.length; i++) {
            btnArr[i].onclick = function () { alert(i) }
        }

        //解决1:利用函数作为一级作用域可以解决上面问题
        // for (var i = 0; i < btnArr.length; i++) {
        //     (function (i) {
        //         btnArr[i].onclick = function () { alert(i) }
        //     })(i)
        // }

        //解决2:使用带有快级作用域的let
        // for (let i = 0; i < btnArr.length; i++) {
        //     btnArr[i].onclick = function () { alert(i) }
        // }
    }
</script>
</html>

4 . 箭头函数

function demo (){} //普通函数
let demo=()=>{} //等同于普通函数

function (){}
()=>{} //去掉function,在()后面加上=>
  • 箭头函数,是函数的简写
    • 如果只有一个参数,()可省略,多了不行,少了也不行
    • 如果只有一条return语句,{}可省略,return可省略,没有不行,有其他代码也不行,
let double = function (num) {
    return num*2
}
let double = num => num*2

5 . 函数的参数

  • 收集参数,展开数组
    • 用... 来收集剩余的参数,用...的行参必须是参数中最后一个位置
    • 还可以将数组合并
  • 默认参数
    • 可以给形参设默认值,无实参时显示默认,有实参会覆盖默认值
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body></body>
<script>
    window.onload = ()=> {
        let show = (a,b, ...c) => {
            alert(a)
            alert(b)
            alert(c)
        }
        show(1,2,3,4,5)
  		//一共会有三次弹出,第一次打印1,第二次打印2,第三次打印3,4,5
  
  		let arr1 = [1, 2, 3]
		let arr2 = [4, 5, 6]
		let arr3 = [...arr1, ...arr2]
  		let arr4 = [7, 8, 9, ...arr3]
		console.log(arr3)
  		console.log(arr4)
  
  		function default (parameter1, parameter2 = 0, parameter3 = 1){
  			console.log(parameter1,parameter2,parameter3)
  		}
  		default(a)
  		//打印出的结果:a 0 1
  		default(a,b,c)
  		//打印出的结果:a b c
    }
</script>
</html>

6 . 解构赋值

  • 拆解数据结构并重新赋值

  • 注意以下几点:
    1.等号两边的结构要一致(右边是数组 左边也给是数组,右边是对象 左边也给是对象)
    2.等号右边的数据必须是合法数据,否则会报错
    3.声明和赋值需在一条语句里完成,否则会报错

let [a, b, c] = [1, 2, 3]
let {x, y, z} = {x: 4, y: 5, z: 6}
console.log(a, b, c)
console.log(x, y, z)

let [json, arr, num, str] = [{ a: 1, b: 2 }, [1, 2, 3], 8, 'str']
console.log(json, arr, num, str)

7 . 数组

  • 数组增加了4个方法
    • map
    • reduce
    • filter
    • forEach

map

理解为映射,特点是 一个对一个,
它有一个参数 是一个function,理解为 数组中的每一项都会走这个方法,
方法也有一个参数 是数组的每一项

[12, 58, 99, 86, 45, 91] //分数
[不及格, 不及格, 及格, 及格, 不及格, 及格]

[001, 002, 003, 004] //用户编号
[	{name: '张三', level: '99'},    {name: '李四', level: '98'},    {name: '王五', level: '97'}]
1:
let numArr = [12, 5, 8]
numArr.map(function (item) {
    console.log(item);
})
let result = numArr.map(function (item) {
    return item * 2
})
console.log(result);
2:
let score = [19, 85, 99, 25, 90]
let result = score.map(item => item > 60 ? '及格' : '不及格')
console.log(result);


reduce

理解为汇总,特点是 一堆出来一个
1:求和(比如购物车算总价)
let arr = [12, 69, 180, 8763]
let result = arr.reduce(function (tmp, item, index) {
    // tmp:return值,item:数组每项,index:下标。每一次的return值 会成为下一次的tmp
    return tmp+item
})
console.log(result);
1:求平均数
let arr = [12, 69, 180, 8763]
let result = arr.reduce(function (tmp, item, index) {
    if (index != arr.length-1) { //如果不是最后一次 求和
        return tmp+item
    } else { //最后一次求平均数
        return (tmp+item)/arr.length
    }
})
console.log(result);


filter

理解为过滤器,特点是 留一部分消失一部分 true留下 false不留
1
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let result = arr.filter(item => {
    if (item%3===0) { //如果能被3整除的留下
        return true
    } else { //其他的不留
        return false
    }
})
console.log(result);

简写
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let result = arr.filter(item => item%3===0)
console.log(result);
2
var arr = [
    { varieties: '苹果', price: 10 },
    { varieties: '西瓜', price: 20 },
    { varieties: '榴莲', price: 100 },
    { varieties: '荔枝', price: 21 },
    { varieties: '甘蔗', price: 15 }
]
var result = arr.filter(item => item.price > 20)
console.log(result)


forEach

循环(迭代)和for一样
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
arr.forEach((item,index) => console.log(index+","+item))

8 . 字符串

  • 多了两个新方法
    • startsWith() 是否已什么开头,返回的是布尔值
    • endsWith() 是否已什么结尾,返回的是布尔值
  • 字符串模版
    • 反单引号``就是字符串模版,作用就是把变量直接塞到字符串里去,${变量}
    • 普通字符串拼接html标签时不能折行需要+号拼接,字符串模版在``中可以随意折行
1
let str = "https://www.baidu.com"
if (str.startsWith("http://")) {
    console.log("普通网址")
} else if (str.startsWith("https://")) {
    console.log("加密网址")
} else {
    console.log("其他")
}
2
let str = "my.jpg"
if (str.endsWith(".jpg")) {
    console.log("JPG格式图片")
} else if (str.endsWith(".png")) {
    console.log("PNG格式图片")
} else {
    console.log("其他格式")
}
3
let num = 2
let num2 = `1${num}3`
console.log(num2)
4
function html(obj) {
	return '<div class="demo">'+
    '<h1>'+obj.title+'</h1>'+
    '<p>'+obj.content+'</p>'+
    '<div>'
}
function html(obj) {
	return `<div class="demo">
    <h1>${obj.title}</h1>
    <p>${obj.content}</p>
    <div>`
}

9 . 面向对象基础

  • 老版面向对象
<script>
    // 定义类:(是类又是构造函数)
    function User(username, password){
        this.username = username;
        this.password = password;
    }
    // 给类添加方法:(是用原型加)
    User.prototype.showUserName=function (){
        alert(this.username)
    }
    User.prototype.showPassWord=function (){
        alert(this.password)
    }
  
    // 构造实例对象
    let u1 = new User("高正正", "123456")
    // 实例对象调用方法
    u1.showUserName()
    u1.showPassWord()
</script>
<script>
    // 定义类:(是类又是构造函数)
    function User(username, password){
        this.username = username;
        this.password = password;
    }
    // 给类添加方法:(是用原型加)
    User.prototype.getUserName=function (){
        alert(this.username)
    }
    User.prototype.getPassWord=function (){
        alert(this.password)
    }
  
    // 继承
    function VipUser(username, password, level) {
        User.call(this, username, password)
        this.level = level
    }
    VipUser.prototype = new User();
    VipUser.prototype.consturctor = VipUser;
    
    VipUser.prototype.getLevel = function (){
        alert(this.level)
    }

    // 调用
    let v1 = new VipUser('高高', '654321', '3级');
    v1.getUserName()
    v1.getPassWord()
    v1.getLevel()
</script>
  • ES6的面向对象
    • 添加了class关键字来定义一个类,并且构造器与类分开了
    • 不用通过原型的方式添加方法,可以直接在类中给类添加方法
<script>
    // 定义类
    class User{
        // 构造函数
        constructor(name, pass){
            // 定义属性
            this.name = name;
            this.pass = pass;
        }
        // 定义方法
        showName(){
            console.log(this.name);
        }
        showPass(){
            console.log(this.pass);
        }
    }
    
    // 构造实例对象
    let u1 = new User("高正正", "123456")
    // 实例对象调用方法
    u1.showName()
    u1.showPass()
</script>
<script>
    // 定义类
    class User{
        // 构造函数
        constructor(name, pass){
            // 定义属性
            this.name = name;
            this.pass = pass;
        }
        // 定义方法
        getName(){
            console.log(this.name);
        }
        getPass(){
            console.log(this.pass);
        }
    }

    //继承
    class VipUser extends User{
        // VipUser类是User类的扩展 || VipUser类 继承 User类
        constructor(name, pass, level){
            // 代表执行(超类)父类的构造函数,与call()作用是一样的
            super(name, pass)
            // 添加新的属性
            this.level = level;
        }
        // 添加新的方法
        getLevel(){
            console.log(this.level);
        }
    }

    // 调用
    let v1 = new VipUser("正正", "112233", "5级")
    v1.getName()
    v1.getPass()
    v1.getLevel()
</script>

10. 面向对象应用

  • React
    • 强依赖于ES6面向对象的
    • 有两点特点
      • 1 强调模块化(组件化),React里一个组件 就是一个class
      • 2 强依赖于JSX(js扩展版),其实JSX就是babel也就是browser.js

代码:gitee.com/zheng_feng/…

11. json

  • JSON对象,有两个方法
    • JSON.stringify() 字符串化
    • JSON.parse() 字符串解析成json
  • JSON的标准写法:两条
    • 1.只能用双引号,不能用单引号
    • 2.所有键名必须引号包起来
    • let json = {a:1, b:2} (falsh)
    • let json = {"a":1, "b":2} (true)
    • let json = {"a":'123', "b":2} (falsh)
    • let json = {"a":"123", "b":2} (true)
<script>
        let json = {title:"百度",content:"前端"}
        // let str = "https://www.baidu.com/s?ie=UTF-8&wd="+JSON.stringify(json)
        // let str = "https://www.baidu.com/s?ie=UTF-8&wd="+JSON.stringify(json.content)
        let str = "https://www.baidu.com/s?ie=UTF-8&wd="+encodeURIComponent(JSON.stringify(json.content)) //encodeURIComponent() 把字符串作为URI组件进行编码
        console.log(str);
</script>
  • JSON的简写
    • 1.键名和值一样的时候可以简写,只写一个
    • 2.方法可以简写
<script>
    let title = "百度"
    let content = "前端"
    let json = {title, content, "date":"20200913"}
    console.log(json);
</script>
<script>
    let title = "百度"
    let content = "前端"
    let json = {
        title, 
        content,
        // show: function(params) {
        //     alert(this.title+this.content);
        // },
        show(){
            alert(this.title+this.content);
        }
    }
    json.show()
</script>

12 . Promise

  • 异步:操作之间没啥关系,可同时进行多个操作

  • 同步:同时只能做一件事,必须等前一个人过去后一个人才能走,像地铁检票口

  • Promise:可以消除异步操作

    • 用同步一样的方式,来书写异步代码
  • Promise 到底怎么用

13 . generator

  • generator-生成器的意思(zai ne rui ter)
    • 普通函数:一路执行到底,就好像坐飞机,中途不能停
    • generator生成器函数:不一样就在于中间能停,就好像出租车可以中途停去接个朋友,再继续前行
    • generator函数有一特点,他与普通函数最大的不同是有一个星号*,这个星号可以和函数名贴一块、可以和function,就是不能和他俩都贴一块,可以谁都不贴
    • 执行generator函数不会直接运行函数里面的代码,他是创建了一个generator对象,对象里有一个很重要的方法 next() 执行下一步
    • generator本质上是生成多个小函数
  • yield-放弃的意思
    • 控制generator函数走到哪停
    • 函数执行的时候碰到yield会放弃执行
    • 什么时候回来用,就再调用一次next()方法
<script>//普通函数
  function show() {
    alert(1)
    alert(2)
  }
  show()
</script>
<script>//generator函数
  function * show() {
      alert(1)
      yield
      alert(2)
  }
  let generatorObj = show()
  console.log(generatorObj);
  generatorObj.next()//第一个打印
  generatorObj.next()//第二个打印
</script>