浅学 ES6

 一、ES6介绍

ECMAScript 6.0 (以下简称ES6) 是JavaScript语言的下一代标准.使得JavaScript语言可以用来编写复杂

  • ES5语言的先天性不足。比如变量提升、内置对象的方法 不灵活、模块化实现不完善等等
  • 为了后面vue、尤其是react框架做好了准备

二、let和const命令

1.let 声明变量, 没有变量提升

代码如下:

 console.log(a); // 报错
 let a =10;

2.是个块作用

代码如下:

 if(1===1){
   let b = 10;
 }
 console.log(b);

3. 不能重复声明

 let a =2;
 let a =4;
 console.log(a);

4. const 声明常量 一旦被声明 无法修改

 console.log(max);
   if(1==1){
    const max = 40;
  }

  const max = 30;
  const max = 40;
  console.log(max);

  const person = {
     name:"三和"
  }
   person.name = "sanhe"  // √
   person = {             // X
      age:20
   }
  console.log(person); // {name: 'sanhe'}

4. 作用: 1 for循环是个经典例子

 var arr =[];   // 10
 const arr =[];    // 4
 for(let i=0;i<10;i++){
    arr[i] = function(){
     return i;
    }
  }
 console.log(arr[4]());

5. 作用: 2 不会污染全局变量

let RegExp = 10;
    console.log(RegExp);  // 10
    console.log( window.RegExp); // ƒ RegExp() { [native code] }

    // 建议: 在默认情况下使用const, 而只有在你知道变量值需要被修改的情况下使用let

三、模板字符串

模板字符串: 使用tab键上面的反引号`` ,插入变量时使用${变量名}

  const oBox = document.querySelector(".box")
  let id = 1;
  let name = "sanhe";
  let htmlStr = `  
  • ${name}

`; oBox.innerHTML = htmlStr; // oBox.innerHTML = "
  • " + name + "

"

四、函数之默认值、剩余参数

1.带参数默认值的函数

 function add(a,b=20){
    return a+b;
   }
 console.log(add(30));

2. 默认的表达式也可以是一个函数

function add(a,b = getVal(5)){
   return a+b;
 }

function getVal(val){
     return val+5;
 }

console.log(add(30));

3.剩余参数: 由三个... 和一个紧跟着的具名参数指定 ...keys

function pick(obj, ...keys) {
     // ...keys 解决了arguments 的问题
     // console.log(keys);
     let result = Object.create(null);
     for(let i=0;i

五、扩展的对象的功能

   //es6直接写变量和函数,作为对象的属性方法
        const name = "sanhe",
            age = 20;
        const person = {
            name, // 等价于name:name,
            age,
            sayName() {
                 console.log(this.name);
            }
        }
        person.sayName();
        // 用法
        let cart = {
            wheel: 4,
            set(newVal) {
                if (newVal < this.wheel) {
                    throw new Error('轮子数太少了')
                }
                this.wheel = newVal;
            },
            get() {
                return this.wheel;
            }
        }
        // console.log(cart.get()); // 4
        cart.set(6)
        console.log(cart.get()); // 6

        // 对象的方法
        // is()===
        // 比较两个值是否严格相等
         console.log(NaN === NaN); // false
         console.log(Object.is(NaN === NaN)); // false

        // assign() 对象的合并
        // Object.assign(target,obj1,obj2)
        // 返回合并之后的新对象
        let newObj = Object.assign({}, { a: 1 }, { b: 2 });
         console.log(newObj); // {a: 1, b: 2}

六、Symbol类型

  //原始数据类型Symbol, 它表示是独一无二的值
        // 最大的用途: 用来定义对象的私有变量

        const name = Symbol("name");
        const name2 = Symbol("name");
        console.log(name === name2); //false

        let s1 = Symbol("s1");
        console.log(s1); // Symbol(s1)

        // let obj = {};
        // obj[s1] = 'sanha';
        // 上面等价于
        let obj = {
            [s1] : 'sanhe'
        }
        // 如果用Symbol定义的对象中的变量,取值时一定要用 [ 变量名 ]
        console.log(obj[s1]); // sanhe

        // 获取Symbol声明的属性名(作为对象的key)
        let s = Object.getOwnPropertySymbols(obj)
        console.log(s[0]); //Symbol(s1)
        let m = Reflect.ownKeys(obj);
        console.log(m); //[Symbol(s1)]

七、Set集合数据类型

   // 集合: 表示无重复值的有序列表
        let set = new Set();
        console.log(set); //Set(0)

        // 添加元素
        set.add(2);
        set.add([1,34,56]);
        // 删除元素
        set.delete(2);
        // 校验某个值是否在set中
        console.log(set.has('4'));// false    true/false
        console.log(set.size);
        console.log(set);
        
        // set.forEach((val,key) => {
        //     console.log(val); //[1, 34, 56]
        //     console.log(key); //[1, 34, 56]
        // });

        // 将set转化成数组
        let set2 = new Set([1,2,3,4,5,5,5,6]);
        console.log(set2);  // Set(6) {1, 2, 3, 4, 5, …}
        // 扩展运算符
        let arr = [...set2]
        console.log(arr); // (6) [1, 2, 3, 4, 5, 6]

        // 1.set中对象的引用无法被释放
        let set3 = new Set(),obj={};
        set3.add(obj);
        // 释放当前的资源
        obj = null;
        console.log(set3);
        

        //  WeakSet
        // 1. 不能传入费=非对象类型的参数
        // 2. 不可迭代
        // 3. 没有forEach()
        // 4. 没有size属性
        let set4 = new WeakSet(),obj1={};
        set4.add(obj1);
        // 释放当前的资源
        obj1 = null;
        console.log(set4);

八、Map数据类型

  // Map类型是键值对的有序列表, 键和值是任意类型
        // set设置 get获取
        let map = new Map();
        map.set('name', "张三");
        map.set('age', 20);
        console.log(map.get('name')); // 张三
        console.log(map); // Map(2) {'name' => '张三', 'age' => 20}
        map.has('name') // true
        map.delete();   // 清除
        map.set(['a', [1, 2, 3]], 'hello') // Map(3) {'name' => '张三', 'age' => 20, Array(2) => 'hello'}
        console.log(map);

        let m = new Map([
            ['a', 1],
            ['b', 2]
        ])
        console.log(m); //Map(2) {'a' => 1, 'b' => 2}

九、数组的扩展方法1

 // 数组的方法  from()  of()
        // 1. from() 将伪数组转换成真正的数组
        function add(){
            console.log(arguments); // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
            // es5 转换
            let arr = [].slice.call(arguments);
            console.log(arr);//(3) [1, 2, 3]

            // es6 写法
            let arr1 = Array.from(arguments);
            console.log(arr1); //(3) [1, 2, 3]
        }
        add(1,2,3)

        let lis = document.querySelectorAll('li');
        console.log(Array.from(lis));  // (4) [li, li, li, li]
        // 扩展运算符 将伪数组转换成真正的数组
        console.log([...lis]);

        // from() 还可以接受第二个参数, 用来对每个元素进行处理
        let licontent = Array.from(lis,ele=>ele.textContent);
        console.log(licontent); //(4) ['1', '2', '3', '4']


        // 2. of() 将任意的数据类型,转换成数组
        console.log(Array.of(3,4,43,[34,5,"67"],{id:"1"})); //(5) [3, 4, 43, Array(3), {…}]


        // 3. copywithin(下标0开始,下标结束但不包括) 复制
        // 比如下面的 (0,5)从下标0开始 一直到下标4(不包括5) 只剩9替换1所以为[ 9, 2, 3, 7, 8, 9]
        console.log([1,2,3,7,8,9].copyWithin(0,5)); //  [ 9, 2, 3, 7, 8, 9]

        // 4. find() findIndex()
        // find() 找出第一个符合条件的数组成员
       console.log( [1,2,-10,-20,3].find(n => n<0));  // -10
        // findIndex() 找出第一个符合条件的数组成员的索引
        console.log( [1,2,-10,-20,3].findIndex(n => n<0));//2

十、数组的扩展方法2

// entries() keys() values() 返回一个遍历器 可以使用for..of循环进行遍历
    // keys()       对键名遍历
    // values()     对值遍历
    // entries()    对键值对遍历


        console.log(["a","b"].keys()); //Array Iterator {}

        for(let index of ["a","b"].keys()){
            console.log(index); // 0 1
        }
        for(let index of ["a","b"].values()){
            console.log(index); // a b
        }
        for(let index of ["a","b"].entries()){
            console.log(index); // [0, 'a'] [1, 'b']
        }

        // includes() 返回一个布尔值, 表示某个数组是否包含给定的值
        console.log([1,2,3].includes(2)); // true
        console.log([1,2,3].includes("4")); //false
        console.log([1,2,3].indexOf("4")); //-1

十一、迭代器iterator的用法

  // Interator
        // 是一种新的遍历机制
        // 1. 迭代器是一个接口,能快捷的访问数据, 通过Symbol.iterator来创建迭代器 通过迭代器的next()获取迭代之后的结果
        // 2. 迭代器是用于遍历数据结构的指针(数据库的游标)

        // 使用迭代
        const items = ['one', 'two', 'three'];
        // 1. 创建新的迭代器
        const ite = items[Symbol.iterator]();
        console.log(ite.next()); //{value: 'one', done: false} done 如果为false,表示遍历继续  如果为true,表示遍历完成
        console.log(ite.next()); //{value: 'two', done: false}
        console.log(ite.next());//{value: 'two', done: false}
        console.log(ite.next());//{value: 'two', done: true}

十二、生成器Generator的用法

  // generator函数 可以通过yield关键字,将函数挂起, 为了改变执行流提供了可能,同时为了异步编程提供了方案
        // 它普通函数的区别
        // 1. function后面 函数名之前有个*
        // 2. 只能在函数内部使用yield表达式, 让函数挂起

        function* func(){
            return 2;
        }
        // 返回一个遍历器对象 可以调用next()
        // console.log(func().next());

        // 总结: generator函数是分段执行的,yield语句是暂停执行  而next()是恢复

        function* add(){
            console.log('start');   // start
            // x 不是yield '2' 的返回值,他是next()调用, 恢复当前yield() 执行传入的实参
            let x = yield '2';      // {value: '2', done: false}
            console.log('one:'+x);  // one:10
            let y = yield '3';      // {value: '3', done: false}
            console.log('two:'+y);  // two:20
            return x+y;             // {value: 30, done: true}
        }
        let fn = add();
        console.log(fn.next());
        console.log(fn.next(10));
        console.log(fn.next(20));

        // 使用场景: 为具备interator接口的对象提供了遍历操作
        function* objectEntries(obj){
            const propKeys = Object.keys(obj);
            for(const propkey of propKeys){
                yield [propkey,obj[propkey]]
            }
        }

        const obj = {
            name:"es6",
            age:20
        }
        obj[Symbol.iterator] = objectEntries;
        console.log(obj);
        for(let [key,value] of objectEntries(obj)){
            console.log(`${key}:${value}`);
        }

十三、Generator的应用

  // Generator 部署ajax操作,让异步代码同步化

        // 加载loading...页面
        // 数据加载完成... (异步操作)
        // loading关闭掉
        function* load() {
            loadui();
            yield loadData();
            loadend();
        }
        let cc = load();
        cc.next();

        function loadui() {
            console.log('loading显示');
        }
        function loadData() {
            setTimeout(() => {
                console.log('内容加载完成');
                   cc.next();
            },1000)
         
        }
        function loadend() {
            console.log('loading隐藏');
        }

十四、Promise的基本使用

Promise 承诺

        相当于一个容器,保存着未来才会结束的事件(异步操作)的一个结果

        各种异步操作都可以用同样的方法进行处理 axios

特点:

       1. 对象的状态不受外界影响,处理异步操作 三个状态 pending(进行) Resolved(成功) Rejected(失败)

        2. 一旦状态改变,就不会再变, 任何时候都可以得到这个结果

 // 第一种
        let pro = new Promise((resolved,rejected)=>{
            let res = {
                code:201,
                data:{
                    name:"张三"
                },
                error:'失败'
            }
            setTimeout(()=>{
                if(res.code === 200){
                    resolved(res.data);
                }else{
                    rejected(res.error)
                }
            },1000)
        })
        // console.log(pro);
        pro.then((val)=>{
            console.log(val);
        },(err)=>{
            console.log(err);
        })
        
        // 第二种
        function timeOut(ms){
            return new Promise((resolved,rejected)=>{
                setTimeout(()=>{
                    resolved('成功')
                },ms)
            })
        }
        timeOut(2000).then((val)=>{
            console.log(val);
        })

十五、使用Promise封装ajax

   // then() 方法
       // then() 第一个参数是relove回调函数, 第二个参数是可选的,是reject状态回调的函数
       // then() 返回一个闲的Promise实例, 可以采用链式编程
       getJSON('url')
       .then(data=>{
        console.log(data);
       }).catch(err=>{
        console.log(err);
       })

十六、Promise对象的其他方法

 // resolve()  reject()  all()   race()  done()  finally()

        // resolve() 能将现有的任何对象转换成promise对象
        //    let p = Promise.resolve('foo'); 等价于下面的
        let p = new Promise(resolve=>resolve('foo'));
            console.log(p);
            p.then(data=>{
                console.log(data);
            })

        // all() 应用: 一些游戏类的素材比较多, 等待图片、flash、静态资源文件 都加载完成, 才进行页面的初始化
        let promise1 = new Promise((resolve,reject)=>{});
        let promise2 = new Promise((resolve,reject)=>{});
        let promise3 = new Promise((resolve,reject)=>{});
        let p4 = Promise.all([promise1,promise2,promise3]);
        p4.then(()=>{
            // 三个都成功 才成功执行then里面的代码
        }).catch(()=>{
            // 如果有一个失败,则失败
        })

        // race() 某个异步请求设置超时时间, 并且在超时后执行相应的操作
        // 1. 请求图片资源
        function requestImg(imgSrc){
            return new Promise((resolve,reject)=>{
                const img = new Image();
                img.onload = function(){
                    resolve(img)
                }
                img.src = imgSrc;
            })
        }
        function timeout(){
            return new Promise((resolve,reject)=>{
                setTimeout(()=>{
                    reject(new Error('图片请求超时'))
                },3000)

            })
        }
        Promise.race([requestImg('https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F1115%2F0ZR1095111%2F210ZP95111-7-1200.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1660806408&t=79a35f949ff42aafecb6d8aa56bd01ca'),timeout()])
        .then((data)=>{
            console.log(data);
            document.body.appendChild(data);
        }).catch((err)=>{
            console.log(err);
        })

十七、async的用法

 // Genarator Promise async 1.解决回调地域 2.使得异步操作更加方便

      // 作用:      使得异步操作更加方便
      // 基本操作:  async 它会返回一个Promise对象 then catch
      // async是Generator的一个语法糖
      // 注意点: 用await命令一定在async函数中,不能单独使用
        async function f(){
            // return await 'hello async';
            let s = await 'hello,word';
            let t = await s.split('');
            return t
        }
        // 如果asynv函数中有多个await 那么then函数会等待所有的await指令 运行完的结果 才去执行 
        f().then(v=>{console.log(v)}).catch(e=>{console.log(e)})

        async function f2(){
            // throw new Error('出错了')
            // await Promise.reject('错误');
            try {
                await Promise.reject('错误');
            } catch (error) {
                
            }
            return await Promise.resolve('成功');
        }
        f2().then(v=>{console.log(v)}).catch(e=>{console.log(e)})

18、class类的用法

// es5 造类
    //  function Person1(name,age){
    //     this.name = name;
    //     this.age = age;
    //  }
    //  Person1.prototype.sayName1 = function(){
    //     return this.name;
    //  }
    //  let p1 = new Person1('es6',30)
    //  console.log(p1);  // Person {name: 'es6', age: 30}

    class Person{
        // 实例化的时候会立即被调用
        constructor(name,age){
            this.name = name;
            this.age = age;
        }
        // sayName(){
        //     return this.name;
        // }
        // sayAge(){
        //     return this.age;
        // }
    }
    // 通过Object.assgin()方法一次性向类中添加多个方法
    Object.assign(Person.prototype,{
        sayName(){
            return this.name;
        },
        sayAge(){
            return this.age;
        }
    })
    let p1 = new Person('es6',21);
    console.log(p1);

19、类的继承

  // 使用关键字 extends
        class Anmal{
            constructor(name,age){
                this.name = name;
                this.age = age;
            }
            sayName(){
                return this.name;
            }
            sayAge(){
                return this.age;
            }
        }
        class Dog extends Anmal{
            constructor(name,age,color){
                super(name,age);
                // Anmal.call(this,name,age);
                this.color = color;
            }
            // 子类自己的方法
            sayColor(){
                return this.color;
            }
            // 重写父类的方法
            sayName(){
                return this.name + super.sayAge() + this.color;
            }
        }
        let d1 = new Dog("大黄",4,'red');
        // console.log(d1);
        console.log(d1.sayName());

20、ES6的模块化实现

html:

     // CommonJs 和 AMD
    //    import {name} from './modules/index.js';
       import Person,{name,age,sayName} from './modules/index.js';
    //    console.log(name);
    //    import * as f from './modules/index.js';
    //    console.log(f);
    //    console.log(f.default);
       console.log(Person);
       let p  = new Person();
       p.sayAge();

index.js:

// es6模块功能主要有两个命令构成: export 和 import 
// exxport 用于规定模块的对外接口 import用于输入其他模块提供的功能
// 一个模块就是独立的文件
// default 只能在一个js文件中使用一次
export const name = "张三";
export const age = 18;
export function sayName(){
    return 'my name is es6'
}
const obj = {
    foo:"foo"
}
// export default obj;
class Person{
    constructor(){

    }
    sayAge(){
        console.log(15);
    }
}
export default Person;

你可能感兴趣的:(js,es6,javascript)