当前位置: 首页 > article >正文

ES6基础内容

ES 全称 EcmaScript ,是脚本语言的规范,而平时经常编写的 JavaScript 是 EcmaScript 的一种实现,所以 ES 新特性其实指的就是 JavaScript 的新特性

一、 let变量声明和声明特性

1.1 变量声明

<!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>
    <script>

        let a;
        let b,c,d;
        let e=521;
        let f=100,g='iloveyou',h=[];

    </script>
</body>
</html>

1.2 声明特性

1.2.1 变量不能重复声明

当用let声明两个变量名一样时,会报错。

1.2.2 块级作用域

es5作用域分为:

  • 全局
  • 函数
  • eval

es6引入新的作用域:块级作用域

<!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>
    <script>

        {
            let name='小羊苏西';
        }
        console.log(name);

    </script>
</body>
</html>

在块之外读取不到该变量,如下:

将let改为var后,可读取到变量:

主要用于:if else for while 后的{}中。

1.2.3 不存在变量提升

<!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>
    <script>

        console.log(age);
        var age=18;

        console.log(addr);
        let addr='山东省'

    </script>
</body>
</html>

var 声明的变量存在变量提升,可在声明变量之前使用该变量而不会报错,而

let 声明的变量不存在变量提升,在声明变量之前使用该变量会报错

var 声明的变量相当于在一开始就声明了该变量,只是没有赋值,故输出undefined。

1.2.4 不影响作用域链

<!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>
    <script>

        {
            let phone=12345;
            function fun(){
                console.log(phone);
            }
            fun();
        }

    </script>
</body>
</html>

在块级作用域中,可正常按照作用域来执行。

1.3 案例

<!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>
    <h3>点击切换颜色</h3>
    <div class="box">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
    <script>

        //获取div元素
        let items=document.getElementsByClassName('item');
        //遍历并绑定事件
        for(var i=0;i<items.length;i++){
            items[i].onclick = function(){
                //修改当前元素的背景颜色
                items[i].style.background='pink';
            }
        }

    </script>
    <style>
        .box{
            width: 350px;
            display: flex;
            justify-self: start;
        }
        .item{
            width: 100px;
            height: 70px;
            margin-left: 5px;
            border: 1px solid blue;
        }
    </style>
</body>
</html>

当使用 var 来定义 i 时,当执行点击函数内部的 items[i] 时,会向外读取 i 的值,而读取到的 i 为3,会报错,可使用 this.style.background='pink' 来实现该效果。

改为 let 来声明,由于具有块级作用域,读取到的 i 可为 0,1,2,不会报错

<!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>
    <h3>点击切换颜色</h3>
    <div class="box">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
    <script>

        //获取div元素
        let items=document.getElementsByClassName('item');
        //遍历并绑定事件
        for(let i=0;i<items.length;i++){
            items[i].onclick = function(){
                //修改当前元素的背景颜色
                items[i].style.background='pink';
            }
        }

    </script>
    <style>
        .box{
            width: 350px;
            display: flex;
            justify-self: start;
        }
        .item{
            width: 100px;
            height: 70px;
            margin-left: 5px;
            border: 1px solid blue;
        }
    </style>
</body>
</html>

效果图如下:

二、const声明常量和特点

2.1 声明格式

<!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>
    <script>

        const NAME='小羊苏西';
        
    </script>
</body>
</html>

2.2 特点

  1.  一定要赋初始值;

  2. 一般常量使用大写;

  3. 常量的值不能修改;

  4. 块级作用域;

  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>
    <script>

        const NAME=['张三','李四'];
        NAME.push('赵五');

    </script>
</body>
</html>

对数组和对象的元素修改,并不影响常量指向的地址,不会报错。

三、变量的解构赋值

ES6 允许按照一定模式从数组和对象中提取值对变量进行赋值

3.1 数组的解构

<!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>
    <script>

        const TF=['王俊凯','王源','易烊千玺'];
        let [no1,no2,no3]=TF;
        console.log(no1);
        console.log(no2);
        console.log(no3);
        
    </script>
</body>
</html>

3.2 对象的解构

<!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>
    <script>

        const WJK={
            name:'王俊凯',
            age:25,
            talent:function(){
                console.log('擅长唱歌跳舞');
            }
        }
        let {name,age,talent}=WJK;
        console.log(name);
        console.log(age);
        talent();

    </script>
</body>
</html>

四、模板字符串

es5声明字符串方式:' '" ";

es6新增:` `

4.1 声明格式

<!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>
    <script>

        let str=`我是一个字符串`;
        console.log(str,typeof(str));

    </script>
</body>
</html>

4.2 特点

4.2.1 内容中可以直接出现换行符

<!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>
    <script>

        let str=`<ul>
            <li>王俊凯</li>
            <li>王源</li>
            <li>易烊千玺</li>
            </ul>`;
        
    </script>
</body>
</html>

 ` `使用换行符时并不会出现错误

' '" "会报错。 

4.2.2 字符拼接

<!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>
    <script>

        let name='王俊凯';
        let res=`${name}擅长唱歌跳舞`;
        console.log(res);
        
    </script>
</body>
</html>

五、对象简化写法

<!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>
    <script>
        let name=`小田`;
        let change=function(){
            console.log('我们可以改变');
        }
        const res={

            //name:name
            name,
            //change:change
            change,
            // fun:function(){
            //     console.log("我们在学校");
            // }
            fun(){
                console.log("我们在学校");
            }
        }
        console.log(res);
    </script>
</body>
</html>

六、箭头函数

6.1 声明格式

<!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>
    <script>

        let fun=(a,b)=>{
            return a+b;
        }
        let res=fun(1,2);
        console.log(res);

    </script>
</body>
</html>

 6.2 特点

6.2.1 this是静态

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

<!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>
    <script>

        function getName(){
            console.log(this.name);
        }
        let getName1=()=>{
            console.log(this.name);
        }
        //设置 window 对象的 name 属性
        window.name='小田';
        const temp={
            name:'xiaotian'
        }

        //直接调用
        getName();
        getName1();

        console.log("————————")

        //call方法调用
        getName.call(temp);
        getName1.call(temp);

    </script>
</body>
</html>

call方法可以改变函数内部this值 

6.2.2 不能作为构造实例化对象

6.2.3 不能使用 arguments 变量

 6.2.4 箭头函数简写

<!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>
    <script>

        //省略小括号,当形参有且只有一个的时候
        let add= n =>{
            return n+n;
        }
        console.log(add(9));

        //省略花括号,当代码体只有一条语句的时候,此时return必须省略
        //语句执行结果就是函数返回值
        let pow=(n)=>n*n;
        console.log(pow(9));
        
    </script>
</body>
</html>

七、函数参数默认值

 ES6允许给参数参数赋值初始值

7.1  形参初始值

具有默认的参数,一般位置要靠后

<!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>
    <script>

        function add(a,b,c){
            return a+b+c;
        }

        let res=add(1,2,3);
        console.log(res);
        //当c没有传值时,为undefined,相加为NaN
        let res1=add(1,2);
        console.log(res1);

        function add1(a,b,c=10){
            return a+b+c;
        }
        //当c有传值时,用所传的值覆盖初始值
        let res2=add1(1,2,3);
        console.log(res2);
        //当c没有传值时,用初始值
        let res3=add1(1,2);
        console.log(res3);

    </script>
</body>
</html>

7.2 与解构赋值结合

<!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>
    <script>

        function connect({host="127.0.0.1",username,password,port}){
            console.log(host);
            console.log(username);
            console.log(password);
            console.log(port);
        }

        connect({
            host:'localhost',
            username:'root',
            password:'root',
            port:3306
        })
        //无host值,使用默认值·
        connect({
            username:'tian',
            password:123456,
            port:8080
        })

    </script>
</body>
</html>

八、rest参数

ES5获取实参方式:

<!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>
    <script>

        function data(){
            console.log(arguments);
        }
        data('王俊凯','王源','易烊千玺');
        
    </script>
</body>
</html>

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

<!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>
    <script>

        function data(...args){
            console.log(args);
        }
        data('王俊凯','王源','易烊千玺');
        //rest参数必须要放到参数最后
        function fn(a,b,...args){
            console.log(a);
            console.log(b);
            console.log(args);
        }
        fn(1,2,3,4,5,6);

    </script>
</body>
</html>

arguments 获取的是对象,而 rest 参数类型获取的是数组形式。 

九、扩展运算符

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

<!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>
    <script>

        const tfboys=['王俊凯','王源','易烊千玺'];
        // =>'王俊凯','王源','易烊千玺'
        function fn(){
            console.log(arguments);
        }

        fn(tfboys);
        console.log('----------')
        fn(...tfboys);
        // => fn('王俊凯','王源','易烊千玺')

    </script>
</body>
</html>

9.1 应用

9.1.1 数组的合并

<!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>
    <script>

        const heze=['曹县','定陶'];
        const taian=['岱岳区','泰山区'];

        const shandong=heze.concat(taian);
        console.log(shandong);

        const shandong1=[...heze,...taian];
        console.log(shandong1);

    </script>
</body>
</html>

 9.1.2 数组的克隆

<!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>
    <script>

        const arr=['a','b','c'];
        const arr1=[...arr];
        console.log(arr1);
        
    </script>
</body>
</html>

9.1.3 伪数组转换成真正数组

<!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>
    <div></div>
    <div></div>
    <div></div>
    <script>

        const divs=document.querySelectorAll('div');
        const divArr=[...divs];
        console.log(divs);
        console.log(divArr);

    </script>
</body>
</html>

十、Symbol

ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
Symbol 特点

  •  Symbol 的值是唯一的,用来解决命名冲突的问题
  • Symbol值不能与其他数据进行运算
  • Symbol定义的对象属性不能使用 for..in 循环遍历,但是可以使用Reflect.ownKeys 来获取对象的所有键名

JS七种数据类型:

undefined 

string 、symbol

object

null 、number·

boolean

10.1 symbol创建

<!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>
    <script>

        let s=Symbol();
        console.log(s,typeof s);
        //tian相当于一个名称或注释,描述字符串
        let s1=Symbol('tian');
        let s2=Symbol('tian');
        console.log(s1===s2);

        let s3=Symbol.for('tian');
        let s4=Symbol.for('tian');
        console.log(s3===s4);
        //不能与其他数据进行运算
        let res=s+100;
        let res1=s>100;
        let res2=s+s;

    </script>
</body>
</html>

10.2 symbol使用

给对象添加属性和方法,表示独一无二的 

<!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>
    <script>
        
        let game={
            name:'王者荣耀',
            up:'我上升到王者了',
            down:'我下降到砖石了',
        };
        //当想向game对象添加方法 up down
        // game.up=function(){},当game对象内部未知,使用可能有冲突
        let methods={
            up:Symbol(),
            down:Symbol()
        };
        game[methods.up]=function(){
            console.log("我上星了");
        }
        game[methods.down]=function(){
            console.log("我掉星了");
        }
        console.log(game);

        let youxi={
            name:'狼人杀',
            [Symbol('say')]:function(){
                console.log("我可以发言");
            },
            [Symbol('zibao')]:function(){
                console.log("我要自爆");
            }
        };
        console.log(youxi);
        
    </script>
</body>
</html>

10.3 symbol内置属性 

Symbol.hasInstance当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法
Symbol.isConcatSpreadable对象的 Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于 Array:prototype.concat()时,是否可以展开。
Symbol.unscopables该对象指定了使用 with 关键字时,哪些属性会被 with环境排除。
Symbol.match当执行 str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值。
Symbol.replace当该对象被 str.replace(myObject)方法调用时,会返回该方法的返回值。
Symbol.search当该对象被 str. search(myObject)方法调用时,会返回该方法的返回值。
Symbol.split当该对象被 str. split (myObject)方法调用时,会返回该方法的返回值。
Symbol.iterator对象进行 for..of循环时,会调用Symbol.iterator 方法,返回该对象的默认遍历器。
Symbol.toPrimitive该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。
Symbol. toStringTag在该对象上面调用 toString 方法时,返回该方法的返回值。
Symbol.species创建衍生对象时,会使用该属性。
<!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>
    <script>

        class Person{
            static [Symbol.hasInstance](param){
                console.log(param);
                console.log(1111111);
            }
        }
        let o={};
        console.log(o instanceof Person);

        console.log('------------');

        const arr=[1,2,3];
        const arr1=[4,5,6];
        console.log(arr.concat(arr1));
        arr1[Symbol.isConcatSpreadable]=false;
        console.log(arr.concat(arr1));
        
    </script>
</body>
</html>

十一、迭代器

迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口,就可以完成遍历操作。
ES6 创造了一种新的遍历命令 for..of 循环,lterator 接口主要供 for..of 消费

原生具备iterator 接口的数据(可用for of遍历):
Array、Arguments、Set、Map、String、TypedArray、NodeList 

<!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>
    <script>

        const tfboys=['王俊凯','王源','易烊千玺'];
        //for...of 中表 键值
        for(let v of tfboys){
            console.log(v);
        }
        //for...in 中表 下标
        for(let v in tfboys){
            console.log(v);
        }
        
    </script>
</body>
</html>

工作原理

  1. 创建一个指针对象,指向当前数据结构的起始位置
  2. 第一次调用对象的next 方法,指针自动指向数据结构的第一个成员
  3. 接下来不断调用 next 方法,指针一直往后移动,直到向最后一个成员
  4. 每调用 next方法返回一个包含 value 和 done 属性的对象

需要自定义遍历数据的时候,要想到迭代器。 

 11.1 自定义遍历数据

<!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>
    <script>
        
        const clazz={
            name:'1班',
            stus:[
                '张三',
                '李四',
                '王五'
            ],
            [Symbol.iterator](){
                //索引变量
                let index=0;
                let _this=this;
                return{
                    next:function(){
                        if(index<_this.stus.length){
                            const res={
                                value:_this.stus[index],
                                done:false
                            };
                            //下标自增
                            index++;
                            //返回结果
                            return res;
                        }else{
                            return {value:undefined,done:true};
                        }
                    }
                };
            }
        }

        for(let v of clazz){
            console.log(v);
        }
        
    </script>
</body>
</html>

十二、生成器

生成器函数其实是一种特殊的函数,用于异步编程 

12.1 声明与调用

<!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>
    <script>

        //声明
        function * gen(){
            console.log("hello tian")
        }
        //调用
        let iterator=gen();
        iterator.next();

    </script>
</body>
</html>

生成器函数可用 yield 函数代码的分隔符

<!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>
    <script>

        function * gen(){
            console.log(111);
            yield '一只没有耳朵';
            console.log(222);
            yield '一只没有尾巴';
            console.log(333);
            yield '真奇怪';
            console.log(444);
        }
        function * gen1(){
            yield '一只没有耳朵';
            yield '一只没有尾巴';
            yield '真奇怪';
        }
        //调用
        let iterator=gen();
        //只输出每个模块中的输出内容
        iterator.next();
        iterator.next();
        iterator.next();
        iterator.next();

        console.log("---------------");

        let iterator1=gen1();
        //会输出返回的value值
        console.log(iterator1.next());
        console.log(iterator1.next());
        console.log(iterator1.next());
        console.log(iterator1.next());

        console.log("---------------");

        for(let v of gen1()){
            console.log(v);
        }

    </script>
</body>
</html>

12.2 参数传递

<!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>
    <script>

        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);
        }
        //arg接受AAA
        let iterator=gen('AAA');
        //输出第一模块间语句,并且输出第一条yield
        console.log(iterator.next());
        //next方法可以传入实参,作为上一条yield语句的返回值
        console.log(iterator.next('BBB'));
        console.log(iterator.next('CCC'));
        console.log(iterator.next('DDD'));

    </script>
</body>
</html>

12.3 案例

1s后控制台输出111,2s后输出222,3s后输出333。

<!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>
    <script>

        //回调地狱,此方法不建议
        setTimeout(()=>{
            console.log(111);
            setTimeout(()=>{
                console.log(222);
                setTimeout(()=>{
                    console.log(333);
                },3000)
            },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();

    </script>
</body>
</html>

模拟获取 用户数据 订单数据 商品数据

<!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>
    <script>

        function getUsers(){
            setTimeout(()=>{
                let data='用户数据';
                iterator.next(data);
            },1000);
        }
        function getOders(){
            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 oders=yield getOders();
            console.log(oders);
            let goods=yield getGoods();
            console.log(goods);

        }
        let iterator=gen();
        iterator.next();

    </script>
</body>
</html>

十三、Promise

13.1 基本使用

<!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>
    <script>

        //实例化Promise对象,参数为函数,函数的参数resolve表示成功,reject表示失败
        const p=new Promise(function(resolve,reject){
            setTimeout(function(){
                let data='用户数据';
                resolve(data);
            },1000);
        })
        //参数为两个函数,第一个函数对应resolve成功执行,第二个函数对应reject失败执行
        p.then(function(value){
            console.log(value);
        },function(reason){
            console.error(reason);
        })

    </script>
</body>
</html>

<!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>
    <script>

        //实例化Promise对象,参数为函数,函数的参数resolve表示成功,reject表示失败
        const p=new Promise(function(resolve,reject){
            setTimeout(function(){
                let err='数据读取失败';
                reject(err);
            },1000);
        })
        //参数为两个函数,第一个函数对应resolve成功执行,第二个函数对应reject失败执行
        p.then(function(value){
            console.log(value);
        },function(reason){
            console.error(reason);
        })

    </script>
</body>
</html>

 

调用 resolve 后,p 的状态变为成功,并调用 p.then() 参数中第一个函数

调用 reject 后,p 的状态变为失败, 并调用 p.then() 参数中第二个函数

13.2 读取文件

const fs=require('fs');
const { resourceLimits } = require('worker_threads');
//1.调用方法读取文件
fs.readFile('./静夜思.md',(err,data)=>{
    //如果失败,则抛出异常
    if(err) throw err;
    //如果成功,则输出内容
    console.log(data.toString());
});
//2.使用Promise封装
const p=new Promise(function(resolve,reject){
    fs.readFile("./静夜思.md",(err,data)=>{
        if(err) reject(err);
        resolve(data);
    });
});
p.then(function(value){
    console.log(value.toString());
},function(reason){
    console.log("读取失败!!");
})

13.3 封装AJAX请求

<!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>
    <script>

        const p=new Promise((reslove,reject)=>{
            //1.创建对象
            const xhr=new XMLHttpRequest();
            //2.初始化
            xhr.open("GET","https://api.apiopen.top/getJoke");
            //3.发送
            xhr.send();
            //4.绑定事件,处理响应结果
            xhr.onreadystatechange=function(){
                if(xhr.readyState===4){
                    if(xhr.status>=200 && xhr.status<300){
                        //表示成功
                        reslove(xhr.response);
                    }else{
                        //如果失败
                        reject(xhr.status);
                    }
                }
            }
        });
        //指定回调
        p.then(function(value){
            console.log(value);
        },function(reason){
            console.error(reason);
        })
        
    </script>
</body>
</html>

13.4 then方法

调用 then 方法, then 方法的返回结果是 Promise 对象,对象状态由回调函数的执行结果决定。

如果回调函数中返回的结果是 非Promise 类型的属性,状态为已完成,返回值为对象的成功的值;

是 Promise 对象,状态为已完成,返回值为 调用 resolve 或 reject 传的值;

抛出异常,状态为失败,返回值为 抛出的异常值;

<!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>
    <script>

        const p=new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve("用户数据");
            },1000)
        });
        //返回结果为非promise对象,不写return默认为undefined
        const res=p.then(value=>{
            console.log(value);
            return 123;
        },reason=>{
            console.warn(reason);
        })

        console.log(res);

    </script>
</body>
</html>

<!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>
    <script>

        const p=new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve("用户数据");
            },1000)
        });
        //返回结果为非promise对象,不写return默认为undefined
        const res=p.then(value=>{
            console.log(value);
            return new Promise((resolve,reject)=>{
                resolve("ok");
            })
        },reason=>{
            console.warn(reason);
        })

        console.log(res);

    </script>
</body>
</html>

 

<!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>
    <script>

        const p=new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve("用户数据");
            },1000)
        });
        //返回结果为非promise对象,不写return默认为undefined
        const res=p.then(value=>{
            console.log(value);
            throw "出错啦!!!";
        },reason=>{
            console.warn(reason);
        })

        console.log(res);

    </script>
</body>
</html>

 可进行链式调用!!!

<!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>
    <script>

        const p=new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve("用户数据");
            },1000)
        });

        p.then(value=>{

        },reason=>{

        }).then(value=>{

        },reason=>{

        });

    </script>
</body>
</html>


http://www.kler.cn/a/532183.html

相关文章:

  • 华为云kubernetes部署deepseek r1、ollama和open-webui(已踩过坑)
  • 【从零开始的LeetCode-算法】922. 按奇偶排序数组 II
  • 2 [GitHub遭遇严重供应链投毒攻击]
  • Docker入门篇(Docker基础概念与Linux安装教程)
  • K8S集群架构及主机准备
  • 信息学奥赛一本通 2113:【24CSPJ普及组】小木棍(sticks) | 洛谷 P11229 [CSP-J 2024] 小木棍
  • [特殊字符] ChatGPT-4与4o大比拼
  • 基于SpringBoot体育商品推荐设计与实现
  • Spring Boot常用注解深度解析:从入门到精通
  • 排序算法与查找算法
  • Blender的材质节点中 透射(Transmission) 和 Alpha的区别
  • Leetcode 3439. Reschedule Meetings for Maximum Free Time I
  • 深度学习 Pytorch 建模可视化工具TensorBoard的安装与使用
  • 关于图像锐化的一份介绍
  • Spring 实现注入的方式
  • 深入解析FastParquet库:高效处理Parquet文件的Python利器
  • 【华为OD-E卷 - 任务最优调度 100分(python、java、c++、js、c)】
  • 【STM32系列】在串口上绘制正弦波
  • 目前市场主流的AI PC对于大模型本地部署的支持情况分析-Deepseek
  • 线程的概念
  • Linux远程登陆
  • PAT甲级1032、sharing
  • 华水967数据结构2024真题(回忆版)
  • chatGPT写的网页版贪吃蛇小游戏
  • 【Linux】线程池封装与介绍
  • 【Java】位图 布隆过滤器