1 ES6

1 ES6介绍

为什么要学习ES6

  • ES5语言的先天性不足。比如变量提升、内置对象的方法不灵活、模块化实
    现不完善等等
  • 为了后面vue、尤其是react框架做好了准备
  • 目前大部分公司的项目都在使用es6

ES6简介:

ECMAScript 6.0 (以下简称ES6)是JavaScript语言的下一代标准,已经在
2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言

ES6既是一个历史名词,也是一个泛指,含义是5.1版以后的JavaScript的下一
代标准,涵盖了ES2015、ES2016、ES2017 等等,而ES2015则是正式名称,特
指该年发布的正式版本的语言标准

ES6新特性:

  • let和const命令
  • es6的模板字符串
  • 增强的函数
  • 扩展的字符串、对象、数组功能
  • 解构赋值
  • Symbol
  • Map和Set
  • 迭代器和生成器
  • Promise对象
  • Proxy对象
  • async的用法
  • 类class
  • 模块化实现

浏览器的支持:

各大浏览器的最新版本,对ES6的支持可以查看kangax.github.io/compat-table/es6/ 随着时间的推移,支持度已经越来越高了,超过90%的ES6语法特性都实现了。

前端工具:强大的babel

  • 被称为下一代的JavaScript编译器。可以将es6的代码转换成es5的代码,从而让浏览器获得支持
  • 这个课程我们只需要知道前端工具babel这个工具的作用,在这里不做过多的赘述

参考文献:

ES6阮-峰教程: http://es6.ruanyifeng.com
MDN教程: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript


2 let和const

let声明的变量特性:

  • 声明变量,没有变量提升

    console.log(a);
    let a = 10;
    # 报错
    
  • 是一个局部作用域

    if(1===1){
    	let b = 10;
    }
    console.log(b)
    # 报错
    
  • 不能重复声明,也就是不能覆盖

    let a = 1;
    let a = 2;
    console.log(a);
    # 报错
    

const声明的变量:

  • const声明的是常量,一旦声明 不可修改

    const max = 30;
    max = 40;
    console.log(max)
    # 报错
    
  • const声明的常量属于局部作用域,也不能覆盖

    console.log(max)
    if(1===1){
        const max = 30;
    }
    # 报错
    
  • 可以修改对象

    可修改对象的常量中的属性,但不能修改常量

    const person = {
        name:'小马哥'
    }
    person.name = "alex";
    console.log(person)
    

简单的应用:

  • 使用var声明的变量,会有覆盖现象:

    const arr = [];
    for (let i = 0; i<10; i++){
        arr[i] = function(){
            return i;
        }
    }
    console.log(arr[5]());
    # 10
    
  • 使用let和const声明的变量,不会有覆盖现象:

    const arr = [];
    for (let i = 0; i<10; i++){
        arr[i] = function(){
            return i;
        }
    }
    console.log(arr[5]());
    # 5
    
  • 使用let和const声明的变量,不会污染全局变量:

    let RegExp = 10;
    console.log(RegExp);
    console.log(window.RegExp);
    

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


3 模板字符串

模板字符串的好处:

tab键上面的反引号
如果说你要拼接一串字符串,那么不需要咱们直接的+去拼接,使用反引号来拼接,拼接的变量使用${变量名}
函数的书写

<div class="box"></div>
<script>
    const oBox = document.querySelector('.box');
    let id = '1p', name = '刘大帅'
    oBox.innerHTML = `
    <ul>
        <li>
            <p id="${id}">${name}</p>
        </li>
    </ul>
    `
</script>


4 函数

4-1 箭头函数

es6箭头函数的使用:

function(){} ==== ()=>{}

箭头函数的使用带来的问题:
    1.使用箭头函数 this的指向发生了改变
    2.使用箭头函数 arguments不能使用
  • es5函数

    let add = function(a,b){
        return a+b;
    }
    
  • es6函数

    es6的箭头函数
    使用=> 来定义 function(){}等于与()=>{}

// 两个参数
let add = (a,b)=>{
     return a+b;
 }
 console.log(add(10,20))

// 一个参数
let add = val =>{
    return val + 5;
 }

// 简易写法
let add = val => (val+5);
console.log(add(10))

let add = val => val;
console.log(add())

let add = (val1,val2) => val1+val2;
console.log(add(10,20))

let fn = ()=> "hello world"+"lxx";
console.log(fu());
let getObj = id => {
    return {
        id: id,
        name: "刘大帅",
    }
}
let obj = getObj(1);
console.log(obj);

// 简易写法
let getObj = id => ({id: id,name: "刘大帅"})

let obj = getObj(1);
console.log(obj);
let fn = (function(){
    return function(){
    	console.log('hello es6');
	}
})();
fn();

// 简易写法
let fn = (()=>{
    return ()=>{
        console.log('hello es6');
    }
})();
fn();

4-2 带参数默认值的函数

<script>
    // 1.带参数默认值的函数
    // es5的写法
    function add(a,b) {
        a = a || 10;
        b = b || 20;
        return a + b
    };
    console.log(add());

    // es6的写法
    function add(a=10,b=20){
        return a+b
    };
    console.log(add())
</script>

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

function add(a,b=getVal(5)){
	return a+b
};
function getVal(val){
	return val+5
};
console.log(add(10));

4-3 剩余运算符

<script>
    function pick(obj) {
        let result = Object.create(null);
        for (let i = 0; i < arguments.length; i++) {
            result[arguments[i]] = obj[arguments[i]]

        }
        return result
    }

    let book = {
        title: 'es6的教程',
        author: '小马哥',
        year: 2019,
    }

    let bookData = pick(book, 'title', 'year');
    console.log(bookData);
</script>
// es6写法
function pick(obj,...keys){
    let result = Object.create(null);
    for(let i=0; i<keys.length; i++){
        result[keys[i]] = obj[keys[i]];
    }
    return result
}

let book = {
    title:'es6的教程',
    author:'小马哥',
    year:2019,
}

let bookData = pick(book, 'title', 'year');
console.log(bookData);

简易写法:

function checkArgs(...args){
    console.log(args);
    console.log(arguments);
}
checkArgs('a', 'b', 'c')

4-4 扩展运算符

将一个数组分割,并将各个项作为分离的参数传给函数

//es5 
const arr = [10,20,40,30,90,100];
console.log(Math.max.apply(null,arr));

// es6 扩展运算法更方便
console.log(Math.max(...arr))

4-5 this指向

// es5中的this指向:取决于调用该函数的上下文对象
let PageHandle = {
    id: 123,
    init: function(){
        document.addEventListener('click', function(event){
            this.doSomeThings(event.type);
        }.bind(this), false)
    },
    doSomeThings: function(type){
        console.log(`事件类型:${type},当前id:${this.id}`);
    }
}
PageHandle.init();


// es6中的this没有this绑定
let PageHandle = {
    id: 123,
    init: function(){
        // 箭头函数没有this指向,箭头 函数内部this值只能通过查找作用域链来确定,一旦使用箭头函数,当前就不存在作用域链
        document.addEventListener('click', (event)=>{
            this.doSomeThings(event.type);
        },false)
    },
    doSomeThings: function(type){
        console.log(`事件类型:${type},当前id:${this.id}`);
    }
}
PageHandle.init();

4-6 箭头函数的注意事项

  • 使用箭头函数后,内部就不会在有arguments

    let getVal = (a,b) =>{
        console.log(arguments);
        return a+b;
    }
    console.log(getVal(1,3));
    // 报错
    
  • 使用箭头函数后,this指向的是父级

  • 箭头函数不能使用new关键字来实例化对象

    let Person = () =>{};
    //function函数也是一个对象,但是箭头函数不是个对象,它其实就是一个函数的语法糖
    let p = new Person();
    

5 解构赋值

  • 解构赋值是对赋值运算符的一种扩展
  • 它针对数组和对象来进行操作
  • 优点:代码书写上简洁易读
let node = {
    type: 'iden',
    name: 'foo'
}
// let type = node.type;
// let name = node.name;

let {type, name} = node;
console.log(type, name);
// iden foo
let obj = {
    a: {name: '张三'},
    b: [],
    c: 'hello world'
}

let {a} = obj;
console.log(a)
// {name: '张三'}

// 剩余运算符
let {a,...res} = obj
console.log(a)
console.log(res)

默认值:

let {a, b=30} = {a:20}
console.log(a,b)

对数组解构:

let arr = [1,2,3];
let [a,b] = arr;
console.log(a,b);
// 1 2

可嵌套:

let [a,[b],c] = [1,[2],3];
console.log(a,b,c)

6 对象扩展功能

  • es6直接写入变量和函数,作为对象的属性和方法

    const name = '小马哥', age=20;
    const person = {
        name,  // 等价于name:name(注:属性值和属性名要相同)
        age,
        sayName(){
            console.log(this.name);
        }  // 方法的简写
    }
    person.sayName();
    
    function fn(x, y) {
        return {x, y};
    }
    console.log(fn(10, 20));
    
    const obj = {};
    obj.isShow = true;
    
    const name = 'a';
    obj[name+'bc'] = 123;
    console.log(obj);
    
    -----------------------------------
       
    // 方法的表达式:
    const name = 'a';
    const obj = {
        isShow: true,
        [name+'bc']: 123,
        ['f'+name](){console.log(this);}
    }
    console.log(obj);
    
  • 对象的方法

    // is() ===
    // 比较两个值是否严格相等
    console.log(NaN === NaN);  // false
    console.log(Object.is(NaN,NaN));  // true
    
    
    // assign()
    // 对象的属性合并
    // Object.assign(target, obj1, obj2, ...)
    // 返回合并之后的新对象
    let newObj = Object.assign({},{a:1},{b:2})
    console.log(newObj)
    

7 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 = {[s1]: '大帅比'};
console.log(obj);
// 获取值:如果用Symbol定义的对象中的变量,取值时定要用[变量名]
console.log(obj[s1]);
// console.log(obj.s1); undefined

// 私有属性,循环没有值
for (let key in obj){
    console.log(key);
}  // 空

// 私有属性,对象取值为空数组
console.log(Object.keys(obj));


// 获取Symbol声明的属性名(作为对象的key)
// 方法1:
let s = Object.getOwnPropertySymbols(obj);
console.log(s[0]);

// 方法2:反射
let m = Reflect.ownKeys(obj);
console.log(m[0]);

8 Set数据类型

集合:表示无重复值的有序列表

let set = new Set();
console.log(set);

// 添加元素
set.add(2);
set.add('4');
set.add(['hello',1,2,3]);
console.log(set);

// 删除元素
set.delete(2);
console.log(set);

// 校验某个值是否在set中
console.log(set.has('4')); // 有true,无false

// 查看集合的长度
console.log(set.size);

// 遍历(只针对set中的数组)
set.forEach((val,key)=>{
    console.log(val);
    console.log(key);
})

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

WeakSet

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

// WeakSet
// 1.不能传入非对象类型的参数
// 2.不可迭代
// 3.没有forEach()方法
// 4.没有size属性

9 Map数据类型

// Map类型是健值对的有序列表,键和值是任意类型
let map = new Map();

// 添加值
map.set('name', '张三');
map.set('age', 20);
console.log(map);

// 获取值
console.log(map.get('name'));

// 查询某个值是否存在
console.log(map.has('name')); // true,false

// 删除名
map.delete('name');
console.log(map);

// 清空值
map.clear();
console.log(map);

// 创建map方式2:
let m = new Map([['a',1],['c',2]]);
console.log(m);
// 同样map也有WeakMap,这就不在赘述

10 数组类型

  • 方法1:from()

    from() 将伪数组转换成真正的数组

    function add() {
        // console.log(arguments);
        // es5转换
        // let arr = [].slice.call(arguments);
        // console.log(arr);
    
        // es6写法
        let arr = Array.from(arguments);
        console.log(arr);
    }
    
    add(1, 2, 3);
    

    应用:

    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    
    // 应用:
    let lis = document.querySelectorAll('li');
    // from转换
    console.log(Array.from(lis)); // [li, li, li]
    // 扩展运算符转换
    console.log([...lis]); // [li, li, li]
    
    // from() 还可以有第二个参数,用来对每个元素进行处理
    let liContents = Array.from(lis, ele => ele.textContent);
    console.log(liContents);  // ['1', '2', '3']
    
  • 方法2:of()

    将任意的数据类型,转换成数组

    console.log(Array.of(3, 11, 20, '30'));
    
  • 方法3:copyWithin()

    数组内部将指定位置的元素复制到其它的位置,返回当前数组

    // 从3位置往后的所有数值,替换从0位置往后的三个数值
    console.log([1,2,3,8,9,10].copyWithin(0,3));
    
  • 方法4:find()findIndex()

    find() 找出第一个符合条件的数组成员

    let num = [1,2,-10,-20,9,2].find(n => n<0);
    console.log(num);
    

    findIndex() 找出第一个符合条件的数组成员的索引

    let numIndex = [1,2,-10,-20,9,2].findIndex(n => n<0);
    console.log(numIndex);
    
  • 方法5:entries() keys() values()

    返回一个遍历器,可以使用数组的for...of循环进行遍历

    for (let index of ['a','b'].keys()){
        // 对key的遍历
        console.log(index); // 0 1
    }
    
    for (let ele of ['a','b'].values()){
        // 对value的遍历
        console.log(ele); // a b
    }
    
    for (let [index,ele] of ['a','b'].entries()){
        // 对键值对的遍历
        console.log(index,ele);
        // 0 'a'
        // 1 'b'
    }
    
    let letter = ['a','b','c'];
    let it = letter.entries();
    console.log(it.next().value); // 迭代取值
    console.log(it.next().value);
    console.log(it.next().value);
    
  • 方法6:includes()

    返回一个bool值,表示数组是否包含给定的值

    console.log([1,2,3].includes(2)); // true
    console.log([1,2,3].includes('4')); // false
    

11 迭代器

Iterator 是一种新的遍历机制

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: 'three', done: false}
console.log(ite.next()); // 返回一个对象
// {value: undefined, done: true}

12 生成器

generator函数。可以通过yield关键字,将函数挂起,为了改变执行流提供了可能,同时为了做异步编程提供了方案

它普通函数的区别:

1.function后面,函数名之前有个*
2.只能在函数内部使用yield表达式,让函数挂起
function* func() {
        yield 2;
        yield 3;
    }
    // 返回一个遍历器对象,可以调用next()
    let fn = func(); // 此时不执行函数。
    console.log(fn.next());
    // {value: 2, done: false}
    console.log(fn.next());
    // {value: 3, done: false}
    console.log(fn.next());
    // {value: undefined, done: true}

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

function* add() {
  console.log('start');
  // x不是yield '2'的返回值,它是next()调用恢复当前yield()执行传入的实参
  let x = yield '2';
  console.log('one:'+x);
  let y = yield '3';
  console.log('two:'+y);
  return x+y;
}
const fnn = add();
console.log(fnn.next());
// start
// {value: '2', done: false}
console.log(fnn.next(20));
// one:20
// {value: '3', done: false}
console.log(fnn.next(30));
// two:30
// {value: 50, done: true}
  • 使用场景1(生成器主要用于异步)

    function* objectEntries(obj) {
      // 获取对象的所有的key保存到数字中[name,age]
      const propKeys =  Object.keys[obj];
      for (const propkey of propKeys){
        yield [propkey,obj[propkey]]
      }
    }
    const obj = {
      name: '刘大帅',
      age: 18
    }
    obj[Symbol.iterator] = objectEntries;
    console.log(obj);
    
    for (let [key,value] of objectEntries(obj)){
      console.log(`${key}:${value}`);
    }
    
  • 使用场景2

    function* main() {
      let res = yield request("https://...com");
      console.log(res);
      // 执行后面的操作
      console.log('数据请求完成。继续操作。。')
    }
    const ite = main();
    ite.next();
    
    function request(url) {
      $.ajax({
        url,
        method: 'get',
        success(res){
          ite.next(res);
        }
      })
    }
    

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

  • 使用场景3

    function* load() {
      loadUI();
      yield showData();
      hideUI();
    }
    let itLoad = load();
    itLoad.next();
    
    function loadUI() {
      console.log('加载loading...页面');
    }
    function showData() {
      // 模拟一步操作
      setTimeout(() =>{
        console.log('数据加载完成...');
        itLoad.next();
      }, 1000);
    
    }
    function hideUI() {
      console.log('隐藏loading...页面');
    }
    

13 Promise对象

Promise是一个异步编程的解决方案。相当与一个容器,它保存着未来才会结束的事件(异步的操作)的一个结果,各种异步操作都可以用同样的方法进行处理

特点:

1.对象的状态不受外接影响,处理异步操作三个状态 pending(进行中)Resolved(成功)Rejected(失败)
2.一旦状态改变,就不会再变,任何时候都可以得到这个结果

用法:

let pro = new Promise(function (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('hello promise success!')
    }, ms)
  })
}
timeOut(2000).then((val)=>{
  console.log(val);
});

13-1 then方法介绍

// then() 方法:
// then() 第一个参数是relove回调函数,第二个参数是可选的,是reject状态回调的函数
// then() 返回一个新的promise实例,可以采用链式编程
// 比如说:
getJSON('http://...com').then((data)=>{
  console.log(data);  // 成功后返回
}).catch(err=>{
  console.log(err);  // 失败后返回
})

/*
    catch(err=>{}) 等价于 then(null,err=>{})
*/

自己封装的方法:

const getJSON = function(url){
  return new Promise((resolve,reject)=>{
    const xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.onreadystatechange = handler;
    xhr.responseType = 'json';
    xhr.setRequestHeader('Accept', 'application/json');
    // 发送
    xhr.send();
    function handler() {
      console.log(this);
      if (this.readyState === 4){
        if (this.status === 200){
          resolve(this.response);
        }else {
          reject(new Error(this.statusText))
        }
      }
    }
  })
}

getJSON('https://...com').then((data)=>{
  console.log(data);
},(error)=>{
  console.log(error);
})

13-2 resolve方法

作用:能将现有的任何对象转换成promise对象

该方法跟reject方法几乎一样

// let p = Promise.resolve("foo");  等同于以下
let p = new Promise(resolve => resolve('foo'));
console.log(p);

p.then((data)=>{
    console.log(data);
})

13-3 all方法

all方法:异步并行操作,一起做事

let n1 = new Promise((resolve,reject)=>{});
let n2 = new Promise((resolve,reject)=>{});
let n3 = new Promise((resolve,reject)=>{});

// 怎么调用呢:
let n4 = Promise.all([n1,n2,n3]);
n4.then(()=>{
    // 三个都成功,才成功返回
}).catch(err=>{
    // 如果有一个失败,则失败
})

应用:一些游戏类的素材比较多,等待图片、flash、静态资源文件。都加载文成,才进行页面的初始化。


13-4 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://..'),timeout()]).then(res=>{
    console.log(res);
    document.body.appendChild(res);
}).catch(err=>{
    console.log(err);
})

13-5 done和finally方法

不管Promise方法是否成功,都会执行。

列:

Promise.race([requestImg('https://'),timeout()]).then(res=>{
    console.log(res);
    document.body.appendChild(res);
}).catch(err=>{
    console.log(err);
}).done()

14 async用法

async异步操作:它使我们的异步操作更加方便
基本操作:async它会返回一个Promise对象
async是Generator的一个语法糖

async function fn() {
    // await命令必须在async中
    let s = await 'hello async';
    let data = await s.split('');
    return data;
}
// 如果async函数中有多个await,那么then函数会等待所有的await指令,运行完的结果采取执行。
fn().then(value => {console.log(value);}).catch(err=>{
    console.log(err)})

// ['h', 'e', 'l', 'l', 'o', ' ', 'a', 's', 'y', 'n', 'c']

15 class

// es5 造类
// 定义属性
function Person(name,age) {
    this.name = name;
    this.age = age;
}
// 定义方法
Person.prototype.sayName = function () {
    return this.name;
}
// 实例化
let p1 = new Person('刘大帅', 18)
console.log(p1);

// class
class Person2{
    // 实例化时,会立即调用。
    constructor(name,age) {
        this.name = name;
        this.age = age;
    }
    sayName(){
        return this.name;
    }
    sayAge(){
        return this.age;
    }
}
// 实例化
let p2 = new Person2('大帅逼',22);
console.log(p2);
// 调用属性:
console.log(p2.name)
// 调用方法:
console.log(p2.sayAge())

// 通过Object.assign方法,一次性添加多个方法
Object.assign(Person2.prototype,{
    sayNameAge(){
        return (`${this.name}+${this.age}`);
    },
    sayAgeName(){
        return (`${this.age}+${this.name}`);
    }
})
console.log(p2);

15-1 class类的继承

// 使用关键字 extends
class Animal{
    constructor(name,age) {
        this.name = name;
        this.age = age;
    }
    sayName(){
        return this.name;
    }
    sayAge(){
        return this.age;
    }
}

class Dog extends Animal{
    constructor(name,age,color) {
        super(name,age);   // 继承父类
        this.color = color;
    }
    sayColor(){
        return `${this.name}是${this.age}岁了,他的颜色是${this.color}`;
    }
    // 重写父类的方法
    sayName() {
        return this.name + super.sayAge() + this.color;
    }
}

let d1 = new Dog('小黄', 9, 'red');
console.log(d1);
console.log(d1.sayColor());
console.log(d1.sayName());

16 模块化实现

es6 模块功能主要有两个命令构成:export和import
export用于规定模块的对外接口 import用于输入其他模块提供的功能
一个模块就是独立的文件

  • 导入方式1:

    js文件:

    // 方式一:(推荐使用)
    export const name = '张三';
    export const age = 18;
    export function sayName() {
        return 'my name is lxx';
    }
    

    html文件:

    // 方式1:
    import {name,age,sayName} from './modules/index'
    console.log(name,age,sayName());
    
  • 导入方式2:

    js文件:

    // 方式二:
    const name = '张三';
    const age = 18;
    function sayName() {
        return 'my name is lxx';
    }
    export {name,age,sayName}
    
    const obj = {foo: 'foo'}  // 对象
    class Person{
        constructor(name,age) {
            this.name = name;
            this.age = age;
        }
    }
    
    export default Person  // 使用默认值导出
    

    html文件:

    // 方式2:
    // import Person,{name,age,sayName} from './modules/index'
    import * as f from './modules/index';
    console.log(f);
    // 取到当前对象
    console.log(f.default);
    

17 axios库

axios就是基于Promise封装的方法:

中文网站:(http://www.axios-js.com/zh-cn/docs/)

2022-09-26 14:32:30 星期一

posted @ 2022-09-26 14:32  角角边  Views(21)  Comments(0)    收藏  举报