前端与JavaScript(下)|青训营笔记

79 阅读4分钟

前端与JavaScript(下)|青训营笔记

u=2208590433,1074113762&fm=253&fmt=auto&app=138&f=JPG.webp

这是我参与「第四届青训营 」笔记创作活动的的第十三天

一.ECMAScrpit(ECMAScrpit=语法+API)

let和const是什么?

声明变量或声明常量

var let声明的就是变量,变量一旦初始化之后,还可以从新赋值
        const声明的就是常量,常量一旦初始化,就不能重新赋值
        

let、const、var 的区别

重复声明

已经存在的变量或常量,又声明了一遍 var允许重复声明,let和const不允许

var有变量提升 let和const不存在变量提升

//相当于
        var a;
        console.log(a);
        a=1;
        结果等于
        console.log();
        var a=1; 定义了变量但是undefind
        

暂时性死区

只要作用域内存再let const,他们所声明的变量或者常量就自动'绑定'这个区域,不再受外部作用域的影响

     let a = 2;
        let b = 1;
        function func(){
            console.log(b);//输出1 内层作用域找不到就去外层找
            console.log(a);//报错
            let a = 1;
        }
        func();
        

window对象的属性和方法

全局作用域中 var声明的变量,通过function声明的函数会自动变成window对象的属性或方法 let const就不会

块级作用域

var 没有块级作用域

        for(let i=0;i<3;i++){
            //i=i+1;
            console.log(i);//这里面就是块级作用域 只有里面有效
        }
        console.log(i);//在外面就会无效报错
        

二.模板字符串和箭头函数

  • 模板字符串 ``
  • 模板字符串中 所有的空格换行和缩进都会保留再输出中
  • 模板字符串的注入 ${}

箭头函数 ()=>{};

因为箭头函数不能命名只能赋值 const/let 函数名=(参数)=>{函数体};

箭头函数的注意事项

  • 单个参数可以省略圆括号

  • 无参数和多个参数是不能省圆括号

      单行函数体可以省略{}和return
                  const add=(x,y)>={
                      return x+y;
                  };
                  化简
                  const add=(x,y)=>x+y;
                  console.log(add(1,1));//2
    

    单行对象

     const add=(x,y)>={
                  return{
                      value:x+y
                  };
              };
              化简
              const add=(x,y)=({
                  value:x+y
                  });
    
              console.log(add(1,1));//2
              
    

    this指向

    非箭头函数this指向

       this指向和函数在哪调用没有关系只和谁在调用有关
       构造函数的this指向实例化生成的对象
       
    

    箭头函数this指向(箭头函数没有自己的this 根据作用域链寻找)

    箭头函数不适用的场景

              作为构造函数的时候
              需要this指向调用对象的时候
              箭头函数中没有arguments
    

三.解构赋值

数组结构赋值

什么是解构赋值?

解析某一数据的结构,将我们想要的东西提取出来,赋值给变量或常量
        const [a,b,c]=[1,2,3];]
        console.log(a,b,c);//123

模式(结构)匹配

    const[a,[,,b],c]=[1,[2,4,5],3];
        console.log(a,b,c);//1 5 3
        

默认值的生效条件

      只有数组成员严格===undefined时,默认值才会生效
        const [a = 1, b = 2] = []; //默认值 1 2
        console.log(a, b); //1 2

对象结构赋值

    属性名相同的完成赋值
    const{age:age,username:username}={username:'stone',age:18}
    
    const{age:age,username:user}={username:'stone',age:18}
    console.log(age,user);//18 stone
    
    如果将一个已经声明的变量用于对象的结构赋值,整个赋值须在原括号中进行

    可以取到继承的属性
    
    
    

四.对象字面量的增强与函数参数的默认值

对象字面量是什么?

    实例化构造函数生成对象
    const person=new Object();
    person.age=18;
    person.speak=function(){};

属性简介表示法

    键名和变量名一样的时候可以只写一个
    const age =18;
    const person={
        //age:age
        age
    };
    console.log(person);//age:18

方法的简洁表示法

    方法可以省略冒号和function关键字
    const person{
        //speak:func(){}
        speak(){}
    };
    console.log(person);

函数参数的默认值

    const multiply=(x,y=1)=>{
        return x*y;
    };
    console.log(multiply(2,2));
    注意事项:
        函数参数的默认值,最好从参数列表的右边开始设置

五.ES6语法扩展

认识剩余参数

        const add = (x, y, ...args) => {};

剩余参数的本质

        const add = (x, y, ...args) => {
            console.log(x, y, args);
        };

        add(1);
        add(1, 2);
        add(1, 3, 4);

        //剩余参数永远是数组 即使没有值也是空数组
    

...展开运算符

        区分剩余参数和展开运算符
            根本区别:
                展开运算符  [3,1,2]->3,1,2
                剩余运算符  3,1,2->[3,1,2]

复制数组

        const a = [1, 2];
        const b = a;
        a[0] = 3;
        console.log(b);



        const c = [...a];
        const c = [1, 2];

合并数组

        const a = [1, 2];
        const b = [3];
        const c = [4, 5];

        console.log([...a, ...b, ...c]);

字符串转为数组

        console.log(...
            'stone'); //s t o n e
        等于console.log('s','t','o','n','e');

        // console.log([...
        //     'alex'
        // ]);
    
    不能展开对象中的对象属性 相同对象属性后面的覆盖前面的

set是什么?

Set是一系列无序,没有重复值的数据集合

Set不能有重复成员

Set没有下标去标示每一个值所以是无序的也不能像数组那样通过下标去访问Set成员

        方法add 实例化构造函数创建Set
            const s = new Set();
            s.add(1).add(2);

        方法has
        const s = new Set();
            s.add(1).add(2);
            console.log(s.has(1))//true
            console.log(s.has(3))//false

        方法delete
            s.delete();

        方法clear
            s.clear();

        方法forEach
            遍历set 访问set里的成员
            ; s.forEach(function(回调函数){回调函数this指向}修改this指向)
            ; console.log(s);
            s.forEach(function(value,key,set){
                //Set中value=key
                console.log(this);
            },document)
            console.log(s);

            forEach按照成员添加进集合的顺序遍历

    属性size
            s.size();获取成员长度

注意事项:

  • et对重复值得判断进本遵循严格相等===
  • 但是对于NaN得判断与===不同,Set中的NaN等于NaN

什么时候使用Set

  • 1.数组或字符串去重时

  • 2.不需要通过下标访问,只需要遍历时

Map 映射

Map和对象都是键值对的集合

            const person={
                键->值,key->value
                name:'stone',
                age:18
            };

set方法

            const m = new Map();
            m.set('name','stone');
            m.set('age',18);
            console.log(m);
   

Map和对象的区别

            对象一般用字符串当作键
            基本数据类型:数字、字符串、布尔值、undefine、null
            引用数据类型:对象([]、{}、函数、SETMAP等)
            以上都可以作为Map的键

         方法set

            const m = new Map();
            使用set添加的新成员,如果已经存在,后添加的键值对覆盖已经有的
            m.set('age',18).set(ture,'true').set('age',20);
            console.log(m);

        方法get
            console.log(m);
            console.log(m.get('age'));
            console.log(m.get('true')); //undefined
            console.log(m.get(true)); //布尔值

        方法has
            console.log(m.has('age'));

        方法delete  
            m.delete('age');

        方法clear
            m.clear();

        方法forEach
            m.forEach(function(value,key,map){

            }document);

        属性size    
            获取成员个数
            console.log(m.size);
        
        什么时候使用Map
            如果只是需要key->value的结构,或者需要字符串以外的值做键,使用Map更合适
            

lterator是什么?

lterator:遍历器(迭代器)

Symbol.iterator(可遍历对象的生成方法)->it(可遍历对象)->it.next()->it.next()->...(直到done为true)

认识for of

    for(cosnt item of arr)
    for...of循环只会遍历出那些donefalse时,对应的value值

取数组索引

        console.log(arr.keys());
        for(const key of arr.keys()){
            console.log(key);//0 1 2
        }

        for(const entries of arr.entries()){
            得到索引+值
        }

    使用lterator的场合
        数组的展开运算符
        set和map的构造函数

ES6新增方法

        padStart() padEnd()
        //补全字符串长度 console.log('x',padStart(5,'ab'))//ababx

        trimStart() trimEnd()
        //清除字符串的首或尾空格,中间的空格不会清楚

        includes()判断数组中是否含有某个成员 第二个参数表示搜索的其实位置默认值时0
        去重:
        const arr=[];
        for(const item of [1,2,1]){
            if(!arr.includes(item)){
                arr.push(item);
            }
        }
        console.log(arr);//[1,2]

        Array.from();
            可以转换成数组
    
    find();找到满足条件的一个立即返回
    findIndex();找到满足条件的一个,立即返回其索引

    Object.assign(目标对象,源对象)
    //用来合并对象   

六.Promise类和class类

  • promise是异步操作的一种解决方案

  • promise一般用来解决层层嵌套的回调函数的问题

  • promise有3种状态,一开始是pending(未完成),执行resolve,变成fulfilled(resolve),已成功

  • promise的状态一旦变化,就不会再改变了

      什么时候执行
          pending->fulfilled时,执行then的第一个回调函数
          pending->rejected时,执行then的第二个回调函数
    
          const p = new Promise((回调函数,回调函数)=>{})
    

catch()

        专门处理then里面的失败(rejected)状态
        new Promise((resolve,reject)=>{
            reject('失败');
        }).then(data=>{
            console.log(data);
        }).catch(err=>{
            console.log(err);//直接捕获前面的错误
            })

了解finally()

Promise状态发生变化时,不论如何变化都会执行,不变化不执行

Promise.resolve()

        是成功状态Promise的一种简写形式
        new Promise(resolve=>resolve('foo'));
        简写:Promise.resolve('foo');

        //参数
        //一般参数
        const p1 = new Promise(resolve=>{
            setTimeout(resolve,1000,'我执行了');
        });
        Promise.resolve(p1).then(data=>{
            console.log(data);
        })
        
        //当resolve函数接收的是Promise对象时,后面的then会根据传递的Promise对象的状态变化决定执行哪一个回调

Promise.reject()

        是失败状态Promise的一种简写形式
        new Promise((resolve,reject)=>{
            reject('reason');
        })
        等价于:Promise.reject('reason');

        参数:不管什么参数,都会原封不动的向后传递,作为后续方法的参数
        

Promise.all

        关注多个Promise对象得状态变化
        传入多个Promise实例,包装成一个新的Promise实例返回
        所有状态都变成resolved最终得状态才会变成resolved
        只要有一个变成rejected,最终的状态就变成rejected

了解promise.race()

        promise.race()的状态取决于第一个完成的Promise实例对象,如果第一个完成的成功了,那最终的就成功,如果第一个完成的失败了,那最终的就失败

Class类

认识class:

具体的人:实例、对象

类可以看作是对象的模板,用一个类可以创造出许多不同的对象

        //声明形式
        class Person{
            //实例化时执行构造方法,所以必须有构造方法,但可以不写出来
            constructor(name,age){
                console.log('实例化时执行构造方法');
                this.name=name;
                this.age=age;
            }
        }
       const zs = new Person(); //this 指向实例化对象

       //构造函数
        function Person(name.age){
            this.name=name;
                this.age=age;
        }
        Person.prototype.speak=func(){

        };

        //表达式形式
        const Person = class{
            constructor(){
                console.log('constructor');
            }
            speak(){}
        };

        //匿名函数
        (function(){
            console.log('object')
        })();

        new (class{
            constructor(){
                console.log('constructor');
            }
        })();

    
        super虽然代表了父类的构造方法,但是内部的this指向子类的实例
        super代表父类的原型对象 Person.prototype
        在静态方法中使用,指向父类,而不是父类的原型对象
        通过super调用父类的方法时,方法内部的this指向当前的子类,而不是子类的实例

七.Module模块与babel编译

module是什么

        type='module'
    模块:一个一个的局部作用域的代码块

模块系统:

  • 模块系统需要解决的主要问题

  • 模块化问题

  • 消除全局变量

  • 管理加载顺序

          export default导出和对应的import导入
          export 导出和对应的import导入
    

export和对应的 import:

        export 声明或语句
        export const age=18;导出
        export{age};//导出

        {}里面可以写多个 后面接as可以取别名 
        import {age} from './module.js';导入

babel 编译器 编译ES6

package.json文件中添加执行babel命令
        "scripts": {
            "build": "babel src -d dist"
            },
        
        npm run build 执行后发现没有配置文件

        Babel的配置文件
        .babelrc

        npm install @babel/preset-env@7.11.0 --save-dev

        创建配置文件 .babelrc 并配置
        {
            "presets":[@babel/preset-env]
        }

Webpack

Webpack是静态模块打包器,打包成一个或多个文件

        entry和output  输入单个或多个和输出单个或多个
        module.exports = {
            mode: 'development',
            // entry: './src/index.js',
            // entry: './src/serach.js',
            entry: {
                main: './src/index.js',
                search: './src/serach.js'
            },
            output: {
                path: path.resolve(__dirname, 'dist'),
                // filename: 'bundle.js'
                filename: '[name].js'
            }
        };

loader(加载器)

Loader让webpack能够去处理那些非js文件的模块 babel-loader: babel和webpack的接口

   安装示例:
            包:npm install --save-dev babel-loader@8.1.0 @babel/core@7.11.0 @babel/preset-env@7.11.0
                npm install --save-dev babel-loader@8.1.0 @babel/core@7.11.0 @babel/preset-env@7.11.0

            引入core-js (补充缺少): npm install --save-dev core-js@3.6.5
                然后再源码的最上面导入 import "core-js/stable"

            处理CSS导包:npm install --save-dev css-loader@4.1.1 帮助webpack识别CSS
                        npm install  --save-dev style-loader@1.2.1
            
            处理CSS导包(图片) npm install --save-dev file-loader@6.0.0
            
            使用html-withimg-loader处理html中的图片:npm install --save-dev html-withimg-loader@0.1.16
                

wekpack里面添加:

                module: {
                        rules: [{
                            test: /\.js$/,
                            exclude: /node_modules/,
                            loader: 'babel-loader'
                        }]
                    }

        

plugins

插件:www.webpackjs.com/plugins/

npm install --save-dev html-webpack-plugin@4.3.0

            引用CSS插件导入 require('mini-css-extract-plugin')
            导包:npm install -save-dev mini-css-extract-plugin@0.9.0

            处理图片 如果是外部的资源,是不需要考虑webpack的,只有本地的图片才需要被webpack处理

        使用webpack-dev-sever搭建开发环境
            npm install --save-dev webpack-dev-sever@3.11.0 

        

总结:

        Balel官网:http://babeljs.io/setup
            使用Babel的流程
                安装Node.jshttp://nodejs.org/en/)
                初始化项目,生成package.json文件
                    npm init

                安装Babel需要的包(@babel.core、@babel/cli、@babel/preset-env)
                
                在package.json文件添加执行编译的命令
                "scripts":{
                    "build":"babel src -d dist"
                }

                创建配置文件.bablrc,并配置
                {
                    "presets":["@babel/preset-env"]
                }

                编译并测试
                    npm run build

            
            使用Webpack的流程
            初始化项目,生成package.json文件
            安装webpack需要的包(webpack-cli和webpack)
                npm install --save-dev webpack-cli webpackpackage.json文件添加执行编译的命令
                {
                    "name":"webpack",
                    "scripts":{
                        "webpack":"webpack"
                        //"webpack":"webpack --config webpack.config.js"
                        //"webpack":"webpack --config webpack.js"
                    }
                }
            
            创建配置文件(默认webpack.config.js),并配置
            打包并测试
                npm run webpack

八.HTTP协议、存储、Ajax

前后端通信(前端和后端相互通信)

HTTP是什么:

  • 超文本传输协议
  • HTML:超文本标记语言
  • 超文本:原先一个一个单一的文本,通过超链接将其联系起来,由原先的单一的文本变成了可无限延申扩展的超级文本、立体文本

HTTP报文

        浏览器向服务器发送请求时,请求本身就是信息,叫请求报文
        服务器向浏览器发送响应时传输的信息,叫响应报文

常用HTTP方法

        浏览器发送请求时采用的方法,和响应无关

        //GET POST PUT delete

        语义:get获取数据       获取资源(文件)
            post创建数据      注册
            PUT更新数据

发送数据

        GET通过地址在请求头中携带数据
        能携带的数据量和地址的长度有关系,一般最多几K

        POST既可以通过地址在请求头中携带数据,也可以通过请求体携带数据

        get可以被缓存 get不可以被缓存

本地存储

    Cookie全称HTTP Cookie,简称Cookie
        是浏览器存储数据的一种方式
        因为存储在用户本地,而不是存储在服务器上,时本地存储
        一般会自动随着浏览器每次请求发送到服务器端

    Cookie属性
        Cookie的名称(name)和值(value)
        最重要的两个属性,创建Cookie时必须填写,其他属性可以使用默认值

        Cookie的名称或值如果包含非英文字母,则写入时需要使用encodeURIComponet()编码,读取时使用dedodeURICompoent()解码
        document.Cookie=`${encodeURIComponet('用户名')=encodeURIComponet('张三')}`

        失效(到期)事件
            失效会被清除
            document.Cookie='username=alex;max-age=5';
            document.Cookie=`username=alex;max-age=${24*3600*30}`;//30天后删除

        Domain域(不同域名)
            限定了Cookie的范围
            使用JS只能读写当前域或父域的Cookie,无法读写其他域的Cookie
            document.cookie='username=alex;domain=www.imooc.com';

        path路径(同一个域名)
            path限定了访问Cookie的范围(同一个域名下)
            使用JS只能读写当前路径和上级路径的Cookie,无法读写下级路径的Cookie
            document.cookie='usrname=alex;path=/course/list';
            当Name、Domain、path这3个字段都相同的时候,才是同一个Cookie

        HttpOnly
            设置了HttpOnly属性Cookie不能通过JS去访问

        Secure安全标志 
            Secure限定了只有在使用了HTTP而不是HTTP的情况下才可以发送给服务端

        Domain、Path、Secure都要满足条件,还不能时过期的Cookie才能随着请求发送到服务器端 

    Cookie的封装

        //写入Cookie
            const set = (name, value, { maxAge, domain, path, secure } = {}) => {
                let cookieText = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
                if (typeof maxAge === 'number') {
                    cookieText += `;max-age=${maxAge}`;
                }
                if (domain) {
                    cookieText += `;domian=${domain}`;
                }
                if (path) {
                    cookieText += `;path=${path}`;
                }
                if (secure) {
                    cookieText += `;securen`;
                }

                document.cookie = cookieText;
            };


            //通过name 获取cookie的值 
            const get = name => {
                name = `${encodeURIComponent(name)}`;
                const cookies = document.cookie.split('; ');

                for (const item of cookies) {
                    const [cookieName, cookieValue] = item.split('=');

                    if (cookieName === name) {
                        return decodeURIComponent(cookieValue);
                    }
                }
                return;
            };

            get('用户名');
            export { set };

localStorage:

localStorage也是一种浏览器存储数据的方式(本地存储),它只存储在本地,不会发送到服务器端

单个域名下的localStorage总大小有限制

        localStorage的基本用法
        setltem()
        localStorage.setltem('username','alex');

        length
        console.log(localStorage.length);

        getltem()
        console.log(localStorage.getltem('username'));
        console.log(localStorage.getltem('age'));

        获取不存在的放回null
        console.log(localStorage/getltem('name'));

        removeltem()
        localStorage.removeltem('username');

        删除不存在的key,不报错
        localStorage.removeltem('name');

        clear()
        localStorage.clear();

        localStorage的存储期限除非手动删除否则永远不会过期

        sessionStorage:当会话结束(比如关闭浏览器)的时候,seesionStorage中的数据会被清除
                        sessionStorage存储的键和值只能时字符串,不是字符串也会转化成字符串在存进去
                        不同域名下是不能共用localStorage

Ajax

Ajax是什么?

Ajax是Asynchronous javaScript and XML(异步javaScript和XML)的简写

Ajax中的异步:可以异步的向服务器发送请求,在等待响应的过程中,不会阻塞当前页面,浏览器可以做自己的事情,直到成功获取响应后,浏览器才开始处理响应数据

XML可扩展标记语言是前后端数据通信时传输数据的一种格式

Ajax其实就是浏览器与服务器之间的一种异步通信方法

使用Ajax可以在不重新加载整个页面的情况下,对页面的某些地方进行更新

Ajax想要实现浏览器与服务器之间的异步通信,需要依靠XMLHttpRequest,它是一个构造函数

    Ajax使用步骤
        1.创建XHR对象
        const xhr = new XMLHttpRequest();

        2.'准备'发送请求
        xhr.open('HTTP方法 get post put delete','地址 URL https://www.imooc.com/api/http/search/suggest?words=js',true)
        
        3.发送请求
        调用send()正式发送请求
        xhr.send(null);

        4.监听事件,处理响应
        当获取到响应后,会触发xhr对象的readystatechange事件,可以在该事件中对响应进行处理
        
        xhr.onreadystatechange = ()=>{
            if(xhr.readyState !==4)return;
            //HTTP CODE
            //获取响应后,响应内容会自动填充xhr对象的属性
            //xhr.status:HTTP 200 404
            //xhr.statusText:HTTP状态说明OK NOT Found
            if((xhr.status>=200)&&(xhr.status<300)||xhr.status===304){
                console.log('正常使用');
                //数据存放 console.log(xhr.responseText);
            }
        };
        
        readystatechange事件监听readyState这个状态的变化
        它的值从0~4,一共5个状态
        0:未初始化.尚未调用open()
        1:启动。已经调用open(),但尚未调用send()
        2:发送.已经调配用send(),但尚未接收到响应
        3:接收.已经接收到部分响应数据
        4:完成.已经接收到全部响应数据,而且已经可以在浏览器中使用了

GET请求:

  • 携带数据 GET请求不能通过请求体携带数据,但可以通过请求头携带
  • 数据编码 如果携带的数据是非英文字母,则写入时需要使用encodeURIComponet()编码

POST请求 :

OST请求主要通过请求体携带数据,同时也可以通过请求头携带

如果向发送数据,直接写在send()参数位置,一般是字符串

        xhr.send('username=stone&age=18');
        不能直接传递对象,需要先将对象转换成字符串的形式
        xhr.send({
            username:'stone',
            age:18
        });

JSON是什么?

Ajax发送和接收数据的一种格式

JSON全称javaScript Object Notation

JSON有三种形式,每种形式的写法都和JS中的数据类型很像,可以很轻松的和JS中的数据类型相互转换

    JSON中没有undefinedJSON中的字符串必须使用双引号
    注意JSON中的字符串是什么样子的
    JSON中不能注释

    对象形式
    JSON对象形式对应着JS中的对象
    JSON中只要涉及到字符串,就必须使用双引号
    不支持undefined

    数组形式
    JSON的数组形式就对应着JS中的数组

    JSON.parse()可以将JSON格式的字符串解析成JS中的对应值
    JSON.stringify()可以将JS的基本数据类型、对象或者数组转换成JSON格式的字符串
        
        使用JSON.parse()和JSON.stringify()封装

什么是不同域,什么是同域:

协议、域名、端口号任何一个不一样就是不同域

与路径无关,路径一不一样无所谓

CORS跨域共享

Access-Control-Allow-Origin:*
    表明允许所有的域名来跨域请求它 *是通配符,没有限制

JONSP的原理

    script标签跨域不会被浏览器阻止
    JONSP主要就是利用script标签,加载跨域文件

使用JSONP实现跨域

    服务器端准备好JSONP接口
    动态加载JSONP接口或动态加载JSONP接口
    const script = document.creatElement('script');
    script.src='接口';
    document.boby.appendChild(script);

使用JSONP利用script标签加载跨域文件

    function handleResponse(data){
        console.log(data);
        //data就是跨域获取到的数据
    }

XHR属性

    responseType和response属性
    可以用来替代responseText

XHR方法

    abort()
        终止当前请求
        一般配合abort事件一起使用

setRequestHeader()

        可以设置请求头信息
        xhr.setRequestHeader(头部字段的名称,头部字段的值)
        请求头中的Content-Type字段用来告诉服务器,浏览器发送的数据是什么格式的
        xhr.setRequesHeader('Content-Type','application/x-www-form-urlencoded');
        xhr.setRequestHeader('Content-Type','application/json');

XHR的事件:

    load事件:响应数据可用时触发 
    IE6~IE8不支持load事件
    xhr.onload = ()=>{
            //HTTP CODE
            //获取响应后,响应内容会自动填充xhr对象的属性
            //xhr.status:HTTP 200 404
            //xhr.statusText:HTTP状态说明OK NOT Found
            if((xhr.status>=200)&&(xhr.status<300)||xhr.status===304){
                console.log('正常使用');
                //数据存放 console.log(xhr.responseText);
            }
        };
        或者
        xhr.addEventListener('load',()=>{
             if((xhr.status>=200)&&(xhr.status<300)||xhr.status===304){
                console.log('正常使用');
                //数据存放 console.log(xhr.responseText);
            }
        },false) ;


        error事件:请求发生错误时触发
            xhr.addEventListener('error',()=>{
                console.log('error');
            },false);

        abort事件:调用abort()终止请求时触发
            xhr.addEventListener('abort',()=>{
                console.log('abort');
            },false);
            xhr.abort();

FormData:

    使用Ajax提交表单

    const data = new FormData(login);

axios是什么

    axios是基于promise的HTTP库,可以在浏览器和node.js中(第三方Ajax库)
    引入axios
    <script scr='https://unpkg.com/axios@0.19.2/dist/axios.min.js'></script>
    axios(url,{method:'post',
        //通过请求头携带数据
        header:{
            'Content-Type':'application/x-www-form-urlencoded'
        },
        //通过请求头携带数据
        param:{
            username:'stone'
        },
        //通过请求体携带数据
        data{
            age:18,
            sex:'男'
        }
    })

Fetch是什么?

前后端通信的一种方式

用于替代Ajax的一种选择

    Fetch的基本用法
        fetch(url)
        .then(response=>{
            if(response.ok){
                return response.json();
            }else{
                throw new Error(`HTTP CODE异常${response.status}`);
            }
        }).then(data=>{
            console.log(data);
        }).catch(err=>{
            console.log(err);
        })

    Fetch的相关配置
        fetch(url,{
            method:'POST',
            请求头信息
            headers:{
                'Content-Type':'applicaton/x-www-form-urlencoded'
            },
            //请求体携带数据
            body:'name=alex&age=18',
            //跨域时设置
            mode:'cors',
            //跨域时携带Cookie
            credentials:'incluede'
        });

总结: Ajax的使用步骤

    1.创建xhr对象
    const xhr = new XMLHttpRequest();

    2.监听事件,处理响应
    xhr.onreadystatechange = ()=>{
            if(xhr.readyState !==4)return;
            //HTTP CODE
            //获取响应后,响应内容会自动填充xhr对象的属性
            //xhr.status:HTTP 200 404
            //xhr.statusText:HTTP状态说明OK NOT Found
            if((xhr.status>=200)&&(xhr.status<300)||xhr.status===304){
                console.log(xhr.responseText);
                console.log(typeof xhr.responseText);
            }
        };

    xhr.addEventListener('load',()=>{
        if((xhr.status>=200)&&(xhr.status<300)||xhr.status===304){
            console.log(xhr.responseText);
                console.log(typeof xhr.responseText);
        }
    },false);    

    3.准备发送请求
        xhr.open('GET','http://www.imooc.com/api/http/search/suggest?words=js',true);

    4.发送请求
        xhr.send(null);
        xhr.send('username=alex&age=18');
        xhr.send(
            JSON.stringify({
                username:'alex',
                age:18
            })
        );

九.模板引擎

模板引擎:art-tempalte

引入art-tempalte

引入在线版本

    准备好模板
        <script id="tpl-students" type="text/html">
            //循环
            {{each students}}
            <li>{{$value.name}}</li>
            {{/each}}

            //条件
            {{if}}
            内容
            {{/if}}
        </script>

        //tempalte('tpl-students',{
       //     'students':students
       // })
       list.innerHTML=template('tpl-students',{
           students
       });

常用语法: 官方文档:aui.github.io/art-templat…

        <script id='tpl-1' type='text/html'></script>