ES6 新特性



1.Let

  • let 不存在变量提升的问题
  • 在代码块内有效,代码块不一定是指的花括号,比如 if 语句后面的内容,while 后面的内容。

比如下边这个,用var就不行,因为他的作用域是属于全局的,只有一个 i,循环到最后成 3 了,显然不对。

  for (var i = 0; i <itmes.lenth:i++){
            itmes[i].render=5
        }


2.const

  • 一般使用大写。
  • 常量不能修改。
  • 是块级作用域
  • 如果 const 指向的数组或者对象,对其中的操作是可以的。这样对数组进行声明是可以的。

出现了 除了单引号,双引号,还可以使用 反引号 ``



3.声明对象

  <script>
      let name="zhao";
      let chang=function(){
          console.log("peng");
      }

      const school={
          name,
          chang
      }
    </script>


4.rest 参数

 <script>
     function datea(...args){
         console.log(args);
     }
     datea("1","2","3");// 做个是打印出来是个数组,而不是对象
    </script>

打碎,用这个方法。

   <script>
   const kuaizhi=["王太利","肖阳"];
   const fenghuagn=["争议","玲花"];
   const hebing=[...kuaizhi,...fenghuagn];

   const shanyan=["E","G","M"];
   const divarr=[...shanyan]; // 数组拷贝
   </script>

5.迭代器

迭代器是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署了 iterator 就可以完成遍历操作。

ES6 中创建了一种遍历命令 for of 循环,能对一下类型进行遍历

  • Array
  • Argument
  • Set
  • Map
  • String
  • TypeArray
  • Nodelist

工作原理,就是创建指针对象,指向当前结构体的起始对象;
第一次调用对象的 next 方法,指针一直往后移动,直到指向了最后一个对象
每次调用 next 方法,都会返回一个 包含 value 和 done 属性的对象。


6.生成器

生成器其实就是一个特殊的函数,一般使用异步编程。

1.声明和使用的特殊之处
   function* gen() { // 声明特殊
            console.log("你好");
        }

        let a = gen();
        a.next(); // 直接调用还不行,需要使用next函数调用

2.yeld 函数

在这里插入图片描述

  • 既然能使用next,就可以使用 for of 方法;



3.yeald 用于异步调用。
    <script>
        function* gen(arg) { // 声明特殊
            console.log(arg);
            let one = yield 111;
            console.log(one);
            let two = yield 222;
            console.log(two);
            yield 333;
        }

        let iter = gen("AAA");
        console.log(iter.next());
        console.log(iter.next("aaa"));
        console.log(iter.next("bbb"));
        // next 可以传参,传过去的参数相当于是上一个函数的返回结果
    </script>


异步操作
  • 异步编程一般适用于 文件操作,网络操作,还有 (axios)数据库操作
  • 1s 后控制台输出 111, 2s 后输出222, 3s 后输出333.

这样的问题就是,如果要进行,如果回调比较多,就会有回调里面用回调,一层套一层。

    <script>
        setTimeout(() => {
            console.log(111);
            setTimeout(() => {
                console.log(222);
                // 如果再继续执行,你会发现这个东西在不断的更新
            }, 2000)
        }, 1000)
    </script>
1.生成器函数的使用,实现异步
  <script>
        function one() {
            setTimeout(() => {
                console.log("aaa");
                iter.next();
            }, 1000)
        }

        function two() {
            setTimeout(() => {
                console.log("bbb");
                iter.next();
            }, 2000)
        }

        function three() {
            setTimeout(() => {
                console.log("ccc");
                iter.next();
            },3000)
        }

        function* gen() {
            yield one();
            yield two();
            yield three();
        }

        let iter = gen();
        iter.next();
    </script>


2.再一个小例子

用户依次取得 订单数据,用户数据,商品数据。

function getone() {
            setTimeout(() => {
                let b = "用户数据";
                A.next(b);
            }, 1000);
        }

        function gettwo() {
            setTimeout(() => {
                let s = "订单数据";
                A.next(s);
            }, 1000);
        }

        function getthree() {
            setTimeout(() => {
                let m = "商品信息,第三个函数";
                console.log(m);
                A.next(m)
            }, 1000)
        }

        function* gin() {
            yield getone();
            let ss = yield gettwo();
            console.log(ss);
            let m = yield getthree();
            console.log(m, "第三个函数");
        }

        let A = gin();
        A.next();



promise语法
 // promise 相当于是一个语法糖
        // promise 成功的话,就调用第一个方法,失败的话,就调用第二个方法
        const p = new Promise(function (resolve, reject) {
            setTimeout(function () {
                console.log("很好");
                let a = "成功";
                resolve(a); // 调用成功这个方法
            }, 1000);
        });
        // 调用promise对象的then 方法
        // 成功的话,掉第一个方法,失败的话,就调第二个方法
        p.then(function (value) {
            console.log(value);
        }, function (err) {
            console.log(err);
        });

Promise三种状态

  • pending:初始状态,完成或失败状态的前一个状态

  • fulfilled:操作成功完成

  • rejected:操作失败



async 和 await

async 和 await 两种语法相结合,就可以让一步代码像同步代码一样。

async 函数
  • 返回值是promise 对象。
  • promise 对象的结果 async 函数执行的返回值决定。
     async function fn() {
            // 返回一个结果,如果这个结果不是一个 promise 对象,
            // 那么返回结果就是正确的
            // 如果一个 promise 对象的输出是成功的,那么就是成功的。
            return "尚硅谷";
        }
        const a = fn();
        console.log(a);

成功的:

在这里插入图片描述



如果是报出的异常呢?

  <script>
        async function fn() {
            // 返回一个结果,如果这个结果不是一个 promise 对象,
            // 那么返回结果就是正确的
            // 如果一个 promise 对象的输出是成功的,那么就是成功的。
            throw new Error("出错了")
        }
        const a = fn();
        console.log(a);
    </script>

在这里插入图片描述

再写两个小例子试一下

   async function fn() {
            // 返回一个结果,如果这个结果不是一个 promise 对象,
            // 那么返回结果就是正确的
            // 如果一个 promise 对象的输出是成功的,那么就是成功的。
            throw new Error("出错了")
        }
        const a = fn();
        a.then(() => {
            console.log("成功了")
        }, () => {
            console.log("失败");
        });

     async function fn() {
            // 返回一个结果,如果这个结果不是一个 promise 对象,
            // 那么返回结果就是正确的
            // 如果一个 promise 对象的输出是成功的,那么就是成功的。
            return "你好"
        }
        const a = fn();
        a.then(() => {
            console.log("成功了")
        }, () => {
            console.log("失败");
        });



await 函数
  • await 必须写在 asycn 的函数中
  • await 返回的是 promise 成功的值
  • 如果失败了,就是用 try***catch 进行捕捉

小例子

  const p = new Promise((resolve, reject) => {
            resolve("成功了");
        });

        async function main() {
            try {
                let m = await p;
                console.log(m);
            } catch (e) {
                console.log(e);
            }
        }
        main();

// 输出
成功了


输出失败了:

  const p = new Promise((resolve, reject) => {
            reject("输出失败");
        });

        async function main() {
            try {
                let m = await p;
                console.log(m);
            } catch (e) {
                console.log("失败了");
                console.log(e);
            }
        }
        main();


再写一个小例子
 const p = new Promise(function (resolve, reject) {
            fs.readFile("t.txt", (err, data));
            if (err) reject(err); // 失败的话报错;
            resolve(data); //如果成功
        });

        p.then(() => {
            console.log("成功");
        }, () => {
            console.log("识别");
        })


自己封装一个 axiso 请求;
    let p = new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            xhr.open("GET", "http//api.ap/get");
            xhr.send(); // 发送请求

            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    if (xhr.status == 200) {
                        resolve("请求成功");
                        console.log("打印成功");
                    } else {
                        resolve("请求失败");
                        console.log("打印失败");
                    }
              }}
        });

        p.then((varlue) => {
            console.log(varlue);
        }, (err) => {
            console.log(err);
        });


七.对象



1.如何声明一个对象

有三种方法

    let obj1 = new Object(); // 直接 new 一个
        let obj2 = {}; // 使用字面变量创建对象

        function Start(name, age) {// 直接使用构造函数
            this.name = name;
            this.age = age;
            this.sing = function () {
                console.log("我会唱歌");
            }
        }

        let liudehua = new Start("刘德华", 18);
        console.log(liudehua);
  • 构造函数一般都是使用 首字母大写

执行 new 的时候,会执行的四件事

  1. 在内存中创建一个新的对象。
  2. this 指向这个新对象。
  3. 使用构造函数的属性,给新对象添加属性和方法
  4. 返回这个新对象(所以构造函数不包含 return)



2.实例成员和静态成员
  • 实例成员就是构造函数内部,通过 this 来添加的成员;
  • 实例成员只能通过实例化的对象来访问;
  • 静态对象能直接添加属性。
  • 静态对象,只能使用对象引用。
    let obj1 = new Object(); // 直接 new 一个
        let obj2 = {}; // 使用字面变量创建对象

        function Start(name, age) { // 直接使用构造函数
            this.name = name;
            this.age = age;
            this.sing = function () {
                console.log("我会唱歌");
            }
        }

        let liudehua = new Start("刘德华", 18);
        console.log(liudehua.name); // 这个就是实例成员

        Start.sex = "男"; // 静态成员直接加就行
        console.log(Start.sex);  // 不能通过实例访问


构造函数存在的问题

构造函数的方法很好用,但是存在浪费内存的问题。
在这里插入图片描述



使用构造函数原型

通过原型分配的函数,都是所有对象所共享的。

js规定,每个构造函数都有一个 prototyep 属性,指向另一个对象,注意这个 prototype 是个对象,我们可以把那些个不变的方法,直接定义在 prototype 对象上,这样所有的实例就都可以共享这些个对象了。

    let obj1 = new Object(); // 直接 new 一个
        let obj2 = {}; // 使用字面变量创建对象

        function Start(name, age) { // 直接使用构造函数
            this.name = name;
            this.age = age;
        }
        
        Start.prototype.single = function () {
            console.log("我会唱歌");
        }

        let liudehua = new Start("刘德华", 18);
        console.dir(Start);
        console.dir(liudehua);
        liudehua.single();

此方法可以直接使用,原始数组中,比如 Array 这个关键字。可以执行一些对原有的数组求和等等的操作

Array.prototype.sum = function () {
            let sum = 0;
            for (let i = 0; i < this.length; i++) {
                sum += this[i]
            }
            return sum;
        }

        let arr = [1, 2, 3];
        console.log(arr.sum());


2.1 函数的内部 this 的指向
调用方法this 指向
普通函数调用window
对象调用该方法所指的对象
构造函数调用实例对象,原型对象里的方法都指向实例对象
立即执行函数window

通过 call 改变原来函数的指向

 function fn(a,b) {
            console.log(a+b);
            console.log("函数的this" + this);
        }

        let o={
            name:"wang",
            age:"li"
        }

        fn.call(o,1,2)
 // 输出
 3
 Object



2.js 中的闭包问题

  • 函数的内部可以使用全局变量
  • 函数的外部不可以使用全局变量
  • 当函数执行完毕以后,本作用域内的局部变量就会被销毁

闭包是有权访问另一个作用域中变量的函数

一个作用域可以访问另外一个函数内部的局部变量。

  function f1() {  // f1就是个闭包。
            var num = 10; 
            function f2() {
                console.log(num);
            }
            f2();
        }
        f1();


闭包的强大作用就是在包的外面访问包的内部

  • 闭包的作用就是延伸了变量的作用范围
  • 原本 num 在调用就要销毁的,现在不能销毁了,因为还有一个函数 f2 要等着用。
      function f1() {
            var num = 10;

            function f2() {
                console.log(num);
            }
            // f2(); 把执行做个函数变成返回
            return f2
        }
        let m = f1(); // 实际上此时的m就是f2
        m();

打印斐波那契列数

 function fb(n) {
            if (n == 1 || n == 2) {
                return 1;
            } else {
                return fb(n - 1) + fb(n - 2);
            }
        }
        let a = fb(5);



八. 其他的小知识点

Proxy

  • proxy 相当于在目标自己按架了一层拦截,对对象的访问,都必须要通过这个拦截。
var obj = new Proxy({}, {
  get: function (target, propKey, receiver) {
    console.log(`getting ${propKey}!`);
    return Reflect.get(target, propKey, receiver);
  },
  set: function (target, propKey, value, receiver) {
    console.log(`setting ${propKey}!`);
    return Reflect.set(target, propKey, value, receiver);
  }
});
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值