ES6杂记

ES6中对象的简化写法

ES6允许大括号里面直接写入变量和函数,作为对象的属性和方法。
例:

        let nickname = '果粒陈';
        let myNickName = function(){
            console.log("我的昵称是果粒陈");
        }
        const person = {
            nickname,
            myNickName,
        }
        console.log(person.nickname);//果粒陈
        console.log(person.myNickName());//我的昵称是果粒陈

还有方法声明的简化:

        const person = {
            nickname,
            myNickName,
            /*之前:
            improve: function(){
				console.log("提高能力");
			},
            */
			//简化后
			improve(){
				console.log("提高能力");
			},
        }

ES6箭头函数以及声明特点

ES6允许使用=>定义函数

声明和调用

        //声明一个函数
        //()里写参数
        let fn = (a,b) => {
            return a + b;
        }
        //调用函数
        let result = fn(1,2);
        console.log(result);//3

声明特性

this是静态的,this始终指向函数声明时所在作用域下的this值

        function getName(){
            console.log(this.name);
        };
        let getName2 = () => {
            console.log(this.name);
        };
        window.name = '果粒陈';
        const person = {
            name : "guolchen",
        }
        //直接调用
        getName();//果粒陈
        getName2();//果粒陈
        //call方法调用
        getName.call(person);//guolichen
        getName2.call(person);//果粒陈

不能作为构造函数实例化对象

在这里插入图片描述

不能使用arguments变量

在这里插入图片描述

箭头函数的简写

1)省略小括号。【当形参有且只有一个的时候】

        /*let add = (n) => {
            return n+n;
        }  可以省略为如下
        */
        let add = n => {
            return n+n;
        }
        console.log(add(9));//18

2)省略大括号【当代码体只有一条语句的时候】此时return必须省略,而且语句的执行结果就是函数的返回值

		/*let pow = (n) => {
            return n*n;
        }; 可以省略为如下
        */
        let pow = (n) =>  n*n;
        //let pow = n =>  n*n;
        console.log(pow(9));//81

箭头函数的实践与应用场景

需求1:点击div 2s后颜色变成粉色

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>箭头函数实践</title>
    <style>
        div{
            width: 200px;
            height: 200px;
            background-color: #58a;
        }
    </style>
</head>
<body>
    <div id="ad"></div>
    <script>
        let ad = document.getElementById('ad');
        ad.addEventListener("click",function(){
            setTimeout(() => {
                this.style.background = 'pink';
            },2000);
        })
    </script>
</body>
</html>

需求2:从数组中返回偶数的元素

        const arr = [1,6,9,10,100,25];
        //以前:
        // const result = arr.filter(function(item){
        //     if(item % 2 ===0){
        //         return true;
        //     }else{
        //         return false;
        //     }
        // });
        const result = arr.filter(item => {
            if(item % 2 ===0){
                return true;
            }else{
                return false;
            }
        })
        //还可以简写为 const result = arr.filter(item => item % 2 === 0);
        console.log(result);//[6,10,100]

综上,箭头函数适合与this无关的回调,比如定时器、数组的方法回调。
箭头函数不适合与this有关的回调,比如dom元素的事件回调、对象的方法【不适合,不是不能】。

函数参数的默认值设置

ES6允许给函数参数赋初始值
1、形参的初始值。具有默认值的参数,一般位置要靠后

        function add(a, b, c = 10){
            return a+b+c;
        }
        let result = add(1,2,);
        console.log(result);//13

2、与解构赋值结合

        //可以给属性赋初始值
        //function connect({host="127.0.0.1",username,password,port}){
        function connect({host,username,password,port}){
            console.log(host);
            console.log(username);
            console.log(password);
            console.log(port);
        }
        connect({
            host:'localhost',
            username:'root',
            password:'root',
            port:3306
        })

rest参数

ES6中引入rest参数,用于获取函数的实参,用来代替arguments

		//ES5获取实参的方式
        function date(){
            console.log(arguments);
        }
        date('白芷','阿娇','思慧');//对象.....
		//rest参数
        function date(...args){
            console.log(args);
        }
        date('白芷','阿娇','思慧');//数组["白芷","阿娇","思慧"]

rest参数必须要放到参数最后。比如:

        function fn(a,b,...args){
            console.log(a);
            console.log(b);
            console.log(args);
        }
        fn(1,2,3,4,5,6);

在这里插入图片描述

扩展运算符

扩展运算符的介绍

扩展运算符(...)能将数组转换为逗号分隔的参数序列。

        //声明一个数组。。。
        const tfboys = ['易烊千玺','王源','王俊凯'];
        //声明一个函数
        function chunwan(){
            console.log(arguments);
        }
        chunwan(...tfboys);//等同于:chunwan('易烊千玺','王源','王俊凯')

在这里插入图片描述

扩展运算符的应用

1、数组的合并

        const kuaizi = ['王太丽','肖央'];
        const fenghuang = ['曾毅','玲花'];
        //const zuixuan = kuaizi.concat(fenghuang);
        const zuixuan = [...kuaizi,...fenghuang];
        console.log(zuixuan);//['王太丽', '肖央', '曾毅', '玲花']

2、数组的克隆

        const sanzhihua = ['E','G','M'];
        const sanyecao = [...sanzhihua];
        console.log(sanyecao);// ['E', 'G', 'M']

3、将伪数组转为真正的数组

    <div></div>
    <div></div>
    <div></div>
    <script>
        const divs = document.querySelectorAll('div');
        const divArr = [...divs];
        console.log(divArr);//[div, div, div]
    </script>

for…of循环

        //声明一个数组
        const xiyou  =['唐僧','孙悟空','猪八戒','沙僧'];
        // 使用for...of遍历数组
        for(let v of xiyou){
            console.log(v);
        }

在这里插入图片描述

for...offor-in的区别:
for...of保存的是数组的键值
for...in保存的是数组的键名

以上例子用for…in遍历:

        //声明一个数组
        const xiyou  =['唐僧','孙悟空','猪八戒','沙僧'];
        // 使用for...of遍历数组
        for(let v in xiyou){
            console.log(v);
        }

在这里插入图片描述

迭代器应用-自定义遍历对象

遍历对象属性【输出属性里的东西】

        //需求,遍历这个对象,每次返回banji.stus中的一个/
        const banji = {
            name: "火箭班",
            stus: [
                'xiaoming',
                'xiaohua',
                'xiaohuang',
                'xiaolv',
                'xiaolan'
            ],
            [Symbol.iterator]() {
                //索引变量
                let index = 0;
                let _this = this;
                return {
                    next: function () {
                        if (index < _this.stus.length) {
                            const result = {
                                value: _this.stus[index],
                                done: false
                            }
                            index++;
                            return result;
                        }else{
                            return{value:undefined,done:true}
                        }
                    }
                };
            }
        }
        for (let v of banji) {
            console.log(v);
        }

在这里插入图片描述
用箭头函数的方式
【区别在next那里,输出结果同上】

    <script>
        const friend = {
            name:"good",
            stus:[
                'xiaoli',
                'xiaochen',
                'xiaoluo',
                'xiaosu',
                'xiaoshi'
            ],
            [Symbol.iterator] () {
                let index = 0;
                return {
                    next : () => {
                        if(index < this.stus.length){
                            const result = {
                                value:this.stus[index],
                                doce:false
                            }
                            index++;
                            return result;
                        }else{
                            return {value:undefined,done:true};
                        }
                    }
                }
            }
        }
        for(let v of friend){
            console.log(v);
        }
    </script>

遍历对象【输出对象中的属性】

        const friend = {
            name:"good",
            stus:[
                'xiaoli',
                'xiaochen',
                'xiaoluo',
                'xiaosu',
                'xiaoshi'
            ],
            
            [Symbol.iterator] () {
                let index = 0;
                                const keys = Object.getOwnPropertyNames(this);
                return {
                    next () {
                        const _this = Object.assign(friend);
                        return index < _this.stus.length?{value:_this[keys[index++]],
                        done:false}:{value:undefined,done:true};
                    }
                }
            }
        }
        for(const v of friend){
            console.log(v);
        }

在这里插入图片描述

生成器

生成器函数声明与调用

生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。
异步编程以前用的是纯回调函数

<script>
        //声明
        function * gen(){
            console.log("hello generator");
        }
        let iterator = gen();
        //console.log(iterator);
        //调用。需要用next来调用
        iterator.next();
    </script>

在生成器函数可以出现yield语句,yield算是函数代码的分隔符,把函数代码切分成几块。比如这里三个分隔符,产生四块代码

function *gen(){
            console.log(111);
            yield '吧啦啦啦啦~';
            console.log(222);
            yield '小魔仙~';
            console.log(333);
            yield '呜啦啦啦啦';
            console.log(444);
        }
        let iterator = gen();
        iterator.next();//111
        iterator.next();//222
        iterator.next();//333
        iterator.next();//444
        function *gen(){
            yield '吧啦啦啦啦~';
            yield '小魔仙~';
            yield '呜啦啦啦啦';
        }
        //遍历
        for(let v of gen()){
            console.log(v);
        }

以上遍历输出如下:
在这里插入图片描述

生成器函数参数

生成器函数可以传入参数

        function * gen(arg){
            console.log(arg);
            yield 111;
            yield 222;
            yield 333;
        }
        let iterator = gen('AAA');
        console.log(iterator.next());

在这里插入图片描述
next方法可以传入实参,这个实参就是yield语句整个的返回结果
生成器函数可以传入参数

        function * gen(arg){
            console.log(arg);
            let one = yield 111;
            console.log(one);
            let two = yield 222;
            console.log(two);
            let three = yield 333;
            console.log(three);
        }
        let iterator = gen('AAA');
        console.log(iterator.next());
        console.log(iterator.next('bbb'));//第一次调用next将作为第一个yield语句整体的返回结果
        console.log(iterator.next('ccc'));
        console.log(iterator.next('ddd'));

在这里插入图片描述

生成器函数实例

生成器函数是专门针对于异步编程的新的解决方案
JS本身是单线程的,异步是单线程的。
异步编程:文件操作、网络操作(Ajax、request)、数据库操作

案例1:
【以定时器的案例演示生成器函数在异步编程中的表现】
1s后控制台输出111 2s后输出222 3s后输出333
定时器嵌套实现【回调地狱】

		 setTimeout(() => {
            console.log(111);
            setTimeout(() => {
                console.log(222);
                setTimeout(()=>{
                    console.log(333);
                })
            }, 2000);
        }, 1000);

用生成器

        function one(){
            setTimeout(()=>{
                console.log(111);
                iterator.next();
            },1000)
        }
        function two(){
            setTimeout(()=>{
                console.log(222);
                iterator.next();
            },2000)
        }
        function three(){
            setTimeout(()=>{
                console.log(333);
                iterator.next();
            },3000)
        }
        function * gen(){
            yield one();
            yield two();
            yield three();
        }
        //调用生成器函数
        let iterator = gen();
        iterator.next();

在这里插入图片描述
案例二
【模拟获取】
获取用户数据、订单数据、商品数据(有先后顺序)

        function getUsers(){
            setTimeout(() => {
                let data = '用户数据';
                //调用next方法并且将数据传入
                iterator.next(data)
            }, 1000);
        }
        function getOrders(){
            setTimeout(() => {
                let data  ='订单数据';
                iterator.next(data);
            }, 1000);
        }
        function getGoods(){
            setTimeout(() => {
                let data  ='商品数据';
                iterator.next(data);
            }, 1000);
        }
        function * gen(){
            let users = yield getUsers();
            console.log(users);
            let orders = yield getOrders();
            console.log(orders);
            let goods = yield getGoods();
            console.log(goods);
        }
        let iterator = gen ();
        iterator.next();

在这里插入图片描述

Promise实践

【Promise解决回调地狱的演示】
需求:读取三个文件,先读取为学再读取插秧诗再读取观书有感最后把三个内容合在一起进行输出
在这里插入图片描述

const fs = require("fs");
const { resolve } = require("path");
const p = new Promise((resolve, reject) => {
    fs.readFile("./resources/为学.md", (err, data) => {
        resolve(data);
    });
});
p.then(value => {
    return new Promise((resolve, reject) => {
        fs.readFile("./resources/插秧诗.md", (err, data) => {
            resolve([value, data]);
        });
    });
}).then(value => {
    return new Promise((resolve, reject) => {
        fs.readFile("./resources/观书有感.md", (err, data) => {
            //压入
            value.push(data);
            resolve(value);
        });
    })
}).then(value=>{
    console.log(value.join('\r\n'));
});

在这里插入图片描述

class类

ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法。

class声明类

ES5

        class Phone{
            //构造方法【名字不能修改,自动执行】
            constructor(brand,price){
                this.brand = brand;
                this.price = price;
            }
            //方法必须使用该语法,不能使用ES5的对象完整形式
            call(){
                console.log("我可以打电话!!");
            }
            say(){
                console.log("我可以说话!");
            }
        } ```

类的静态成员

        function Phone(){

        }
        Phone.name = '手机';//属于函数对象,并不属于实例对象,这种称为静态成员
        //属于函数对象,并不属于实例对象.这种称为静态成员
        Phone.change = function(){
            console.log("我可以改变世界");
        }
        let nokia = new Phone();
        console.log(nokia.name);//undefined
        //nokia.change();//Uncaught TypeError: nokia.change is not a function
        //实例对象是实例对象,函数对象是函数对象,他们的属性是不同的。实例对象和构造函数原型对象相同。如下
        Phone.prototype.size = '5.5inch';
        console.log(nokia.size); ```
 以上是ES5中,以下是ES6
        //在面向对象中,静态成员属于类,不属于实例对象
        class Phone{
            static name = '手机';
            static change(){
                console.log("我可以改变世界");
            }
        }
        let nokia = new Phone();
        console.log(nokia.name);//undefined
        console.log(Phone.name);//手机 ```

类继承

构造函数继承

        //手机
        function Phone(brand,price){
            this.brand = brand;
            this.price = price;
        }
        Phone.prototype.call =function(){
            console.log("我可以打电话!");
        }
        //智能手机
        function SmartPhone(brand,price,color,size){
            //this指向SmartPhone
            Phone.call(this,brand,price);
            this.color = color;
            this.size = size;
        }
        //设置子级构造函数的原型
        SmartPhone.prototype = new Phone;
        SmartPhone.prototype.constructor = SmartPhone;

        //声明子类的方法
        SmartPhone.prototype.photo = function(){
            console.log("我可以拍照");
        }
        SmartPhone.prototype.playGame  =function(){
            console.log("我可以玩游戏");
        }
        const chuizi = new SmartPhone('锤子',2499,'黑色','5.5inch');
        console.log(chuizi);

在这里插入图片描述

类继承

        class Phone {
            //构造方法
            constructor(brand, price) {
                this.brand = brand;
                this.price = price;
            }
            //父类的成员属性
            call() {
                console.log("我可以打电话!!");
            }
            photo() {
                console.log("我可以拍照");
            }
        }
        class SmartPhone extends Phone {
            //构造方法
            constructor(brand, price, color, size) {
                super(brand, price);//Phone.call(this,brand,price)
                this.color = color;
                this.size = size;
            }
            playGame() {
                console.log("玩游戏");
            }
            wechat() {
                console.log("玩微信");
            }
        }
        const huawei = new SmartPhone('huawei', 2499, '黑色', '5inch');
        console.log(huawei);//SmartPhone {brand: 'huawei', price: 2499, color: '黑色', size: '5inch'}
        huawei.call();
        huawei.photo();
        huawei.playGame();
        huawei.wechat();

在这里插入图片描述

子类对父类方法的重写

例如以上例子中重写父类的call方法:

               class Phone {
            //构造方法
            constructor(brand, price) {
                this.brand = brand;
                this.price = price;
            }
            //父类的成员属性
            call() {
                console.log("我可以打电话!!");
            }
            photo() {
                console.log("我可以拍照");
            }
        }
        class SmartPhone extends Phone {
            //构造方法
            constructor(brand, price, color, size) {
                super(brand, price);//Phone.call(this,brand,price)
                this.color = color;
                this.size = size;
            }
            playGame() {
                console.log("玩游戏");
            }
            wechat() {
                console.log("玩微信");
            }
            //重写父类的call方法
            call(){
                console.log("我可以视频通话");
            }
        }
        const huawei = new SmartPhone('huawei', 2499, '黑色', '5inch');
        huawei.call();//我可以视频通话

class中的set、get

setgetES5中也用过,可以对对象的属性进行方法的绑定。比如:添加一个get方法,当对某一个属性进行获取时,执行get对应的函数;当对某一属性进行设置时,执行set对应的函数。在class中也有这样的特性。

class中set、get使用场景:
get通常来对对象的动态的属性进行一个封装;
set可以添加更多的控制、判断

 class Phone{
            set price(newVal){
                console.log("价格属性被修改了");
                
            }
            get price(){
                console.log("价格属性被读取");
                return 'aaa';
            }
        }
        //实例化对象
        let s = new Phone();
        console.log(s.price);
        s.price = 'free';//价格属性被修改了

在这里插入图片描述

ES6中的数值扩展

Number.EPSILON

Number.EPSILON 是 JavaScript 表示的最小精度
EPSILON 属性的值接近于2.2204460492503130808472633361816E-16
该数常用来浮点数的运算上,对精度做一个设置

console.log(0.1+0.2);//0.30000000000000004
			//解决
        function equal(a, b) {
            if (Math.abs(a - b) < Number.EPSILON) {
                return true;
            } else {
                return false;
            }
        }
        console.log(0.1+0.2 === 0.3);//false
        console.log(equal(0.1 + 0.2, 0.3));//true

二进制和八进制

 //二进制
 let b = 0b1010;
 //八进制
 let o = 0o777;
 //十进制
 let d = 100;
 //十六进制
 let x = 0xff;

Number.isFinite

Number.isFinite 检测一个数值是否为有限数

 console.log(Number.isFinite(100));//true
 console.log(Number.isFinite(100/0));//false
 console.log(Number.isFinite(Infinity));//false

Number.isNaN

Number.isNaN 检测一个数值是否为 NaN
【ES5中isNaN是一个单独的函数,在ES6中把它作为了Number的方法。】

 console.log(Number.isNaN(123)); //false

Number.parseInt Number.parseFloat字符串转整数

 console.log(Number.parseInt('5211314love'));//5211314
 console.log(Number.parseFloat('3.1415926神奇'));//3.1415926

Number.isInteger 判断一个数是否为整数

 console.log(Number.isInteger(5));//true
 console.log(Number.isInteger(2.5));//false

Math.trunc 将数字的小数部分抹掉

 console.log(Math.trunc(3.5));//3

Math.sign 判断一个数到底为正数 负数 还是零

			console.log(Math.sign(100));//1【代表为正数】
        console.log(Math.sign(0));//0【代表为0】
        console.log(Math.sign(-1000));//-1【代表为负数】

对象方法的扩展

Object.is

Object.js比较两个值是否严格相等,与===行为基本一致。Object.js===的不同之处:NaN

        console.log(Object.is(120,120));//true
        console.log(Object.is(120,110));//false
        
        console.log(Object.is(NaN,NaN));//true
        console.log(NaN === NaN);//fasle

Object.assign

Object.assign对象的合并,将源对象的所有可枚举属性,复制到目标对象
它用来做配置的合并,非常合适

        const config1 = {
            host:'localhost',
            port:3306,
            name:'root',
            pass:'root',
            test:'test'
        };
        const config2 = {
            host:'http://www.cxj.com',
            port:33060,
            name:'cxj.com',
            pass:'abc',
            test2:'test2'
        }
        //config2会覆盖config1重名的属性
        console.log(Object.assign(config1,config2));

在这里插入图片描述

proto、setPrototypeOf、getPrototypeof

_proto_、setPrototypeOf、getPrototypeof可以直接设置对象的原型

        const school = {
            name: '果粒陈'
        }
        const cities = {
            xiaoqu: ['北京', '上海', '广州', '深圳']
        }
        Object.setPrototypeOf(school, cities);
        console.log(school);
        console.log(Object.getPrototypeOf(school));

在这里插入图片描述

模块化

模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。

模块化的好处

模块化的优势有几下几点:

  • 防止命名冲突
  • 代码复用
  • 高维护性

模块化规范产品

ES6之前的模块化规范有:

  • CommonJS => NodeJS、Browserify
  • AMD => requireJS
  • CMD => seaJS

ES6模块化语法

模块功能主要由两个命令构成:export和import

  • export命令用于规定模块的外接口
  • import命令用于输入其他模块提供的功能

浏览器使用ES6模块化引入模块方式一

1、以下就是一个模块
在这里插入图片描述2、想对外暴露一些数据,让外部模块可以使用这个模块的一些变量或者函数。【可以使用export命令来暴露】
【分别暴露】
在这里插入图片描述
3、引入模块

【通用方式引入】

    <script type = "module">
        //引入 39-m1.js 模块内容
        import * as m1 from "./39-m1.js";
        console.log(m1);
    </script>

在这里插入图片描述

ES6模块暴露数据语法汇总

【统一暴露】

//统一暴露
let school = '果粒陈';
function good(){
    console.log("我们可以让你变得优秀");
}
export{school,good}

在这里插入图片描述

【默认暴露】

//默认暴露
export default{
    school:'CXJCXJ',
    change:function(){
        console.log("我们可以改变你");
    }
}

在这里插入图片描述

ES6引入模块数据语法汇总

【解构赋值形式】

//导入分别暴露
import {school,teach} from "./39-m1.js";//这时候可以直接使用school、teach
//导入统一暴露
import {school as cxj,good} from "./39-m2.js";//这里school重名了,可以起别名
//导入默认暴露
import {default as m3} from "./39-m3.js";
console.log(school);
console.log(teach);
console.log(cxj);
console.log(good);
console.log(m3);

在这里插入图片描述【简便形式】只能针对默认暴露

import m3 from "./39-m3.js";
console.log(m3);//输出结果同上输出m3的结果

浏览器使用ES6模块化方式二

前面都是使用script标签写import语句。这样会使文件的体积变大。所以可以把import单独写入到一个文件中。这个文件可以当做整个JS代码的入口

step1:在html文件中引入入口文件

<script src="./39-app.js" type="module"></script>

step2:在入口文件中引入模块
在这里插入图片描述

babel对ES6模块化代码转换【项目中的应用】

Babel中文网
step1:
1、安装工具:

  • babel-cli【babel命令行工具】
  • babel-preset-env【预设包:能够把最新的ECMAScript的特性做一个转换,转化为ES5的语法】
  • broeserify【打包工具】打包工具还有webpack,项目中其实用webpack

2、对文件进行转换
在这里插入图片描述3、打包
在这里插入图片描述4、引入打包好的js,就完成了
在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值