博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ES6和ES7、8、9、10常用的
阅读量:6347 次
发布时间:2019-06-22

本文共 18319 字,大约阅读时间需要 61 分钟。

ES6

let和const

  • let
    1. 作用: 与var类似, 用于声明一个变量
    2. 特点: 在块作用域内有效 不能重复声明 不会预处理, 不存在提升
    3. 应用: 循环遍历加监听 使用let取代var是趋势
  • const
    1. 作用: 定义一个常量
    2. 特点: 不能修改 其它特点同let
    3. 应用: 保存不用改变的数据
  • let 定义 变量
  • const 定义 常量
    1. 默认变量使用let定义,今后let使用很多,只有确定不变的量用const 90%以上用let定义的
    2. 默认变量使用const定义,今后const使用很多,只有确定可变的量用let 90%以上用const定义的 默认就用const定义,只有后面的值发生变化,在改为let

变量的解构赋值

  1. 理解:
  • 从对象或数组中提取数据, 并赋值给变量(多个)
    • const person = {name: 'jack', age: 18}; const { age, sex, name } = person; console.log(name, age, sex);
  1. 对象的解构赋值: 没有顺序关系 let {n, a} = {n:'tom', a:12}
  2. 数组的解构赋值: 根据顺序一一对应 let [a,b] = [1, 'atguigu'];
  3. 用途
    • 给多个形参赋值
  4. 对函数参数解构赋值,一个解构赋值语法对应一个参数(与结构赋值语法中多少个变量没有关系)

模板字符串

  1. 模板字符串 : 简化字符串的拼接
  • 模板字符串必须用 `` 包含
  • 变化的部分使用${xxx}定义
const person = {name: 'jack', age: 18};  console.log('姓名:' + person.name + ' 年龄:' + person.age);  console.log(`姓名:${person.name} 年龄: ${person.age}`);复制代码

对象的简写方法

简化的对象写法

  • 省略同名的属性值
  • 省略方法的function
  • 例如:
    let y = 2;let point = {  x,  y,  setX (x) {this.x = x}};复制代码

形参默认值

形参的默认值----当不传入参数的时候默认使用形参里的默认值

function Point(x = 1,y = 2) {this.x = x;this.y = y;}复制代码

默认值:没有传值就使用默认值,传值了就使用传入的值

三点运算符

用途

  1. rest(可变)参数
    • 用来取代arguments 但比 arguments 灵活,只能是最后部分形参参数
    function fun(...values) {    console.log(arguments);    arguments.forEach(function (item, index) {        console.log(item, index);    });    console.log(values);    values.forEach(function (item, index) {        console.log(item, index);    })}fun(1,2,3);复制代码
  2. 扩展运算符
let arr1 = [1,3,5];  let arr2 = [2,...arr1,6];  arr2.push(...arr1);  function sum(a, ...args) {    // ...运算符 取代 arguments    console.log(args); // 真数组    console.log(arguments); // 伪数组  }复制代码

箭头函数

  • 作用: 定义匿名函数

  • 基本语法:

    • 没有参数: () => console.log('xxxx')
    • 一个参数: i => i+2
    • 大于一个参数: (i,j) => i+j
    • 函数体不用大括号: 默认返回结果
    • 函数体如果有多个语句, 需要用{}包围,若有需要返回的内容,需要手动返回
  • 使用场景: 多用来定义回调函数

  • 箭头函数的特点: 1、简洁 2、箭头函数没有自己的this,箭头函数的this不是调用的时候决定的,而是在定义的时候处在的对象就是它的this 3、扩展理解: 箭头函数的this看外层的是否有函数, 如果有,外层函数的this就是内部箭头函数的this, 如果没有,则this是window。

// 箭头函数  const fn = () => {};  // 形参只有一个, 可以省略括号  const fn1 = x => { console.log(x); };  // 形参没有或者有多个  const fn2 = (x, y) => {};  console.log(fn1(1));  // 当代码只有一条语法时, 可以省略大括号,会将语句结果作为函数的返回值返回  const fn3 = x => x + 1;  console.log(fn3(1));  // 当代码没有或多条语句时  const fn4 = x => {    console.log(x);    return x + 1;  }复制代码

Promise对象

  1. promise就是一个异步编程的解决方案,用来解决回调地狱问题
  2. 理解:
  • Promise对象: 代表了未来某个将要发生的事件(通常是一个异步操作)
  • 有了promise对象, 可以将异步操作以同步的流程表达出来, 避免了层层嵌套的回调函数(俗称'回调地狱')
  • ES6的Promise是一个构造函数, 用来生成promise实例
  1. 使用promise基本步骤(2步):
  • 创建promise对象
    let promise = new Promise((resolve, reject) => {    //初始化promise状态为 pending  //执行异步操作  if(异步操作成功) {    resolve(value);//修改promise的状态为fullfilled  } else {    reject(errMsg);//修改promise的状态为rejected  }})复制代码
  • 调用promise的then()
    promise.then(function(  result => console.log(result),  errorMsg => alert(errorMsg)))复制代码
  1. promise对象的3个状态
  • pending: 初始化状态
  • fullfilled: 成功状态
  • rejected: 失败状态
  1. 应用:
  • 使用promise实现超时处理

  • 使用promise封装处理ajax请求

    let request = new XMLHttpRequest();request.onreadystatechange = function () {}request.responseType = 'json';request.open("GET", url);request.send();复制代码
  • new Promise(), 会创建promise实例对象,实例对象内部默认是pending状态(初始化状态)

    • resolve() 将promise状态由初始化状态改为 fullfilled 成功的状态
    • reject() 将promise状态由初始化状态改为 rejected 失败的状态
    • promise状态只能有初始化状态改为成功/失败的状态。不能由成功变成失败或者失败变成成功
  • promise实例对象, then方法

promise.then((result) => {// 当promise对象状态变成成功的状态时,会调用当前函数// 成功的回调函数可以接受resolve方法传入参数console.log('成功的回调函数触发了~');console.log(result);sum(1, 2);}, (error) => {// 当promise对象状态变成失败的状态时,会调用当前函数// 失败的回调函数可以接受reject方法传入参数console.log('失败的回调函数触发了~');console.log(error);})复制代码

Symbol

  • 前言:ES5中对象的属性名都是字符串,容易造成重名,污染环境
  • 每次调用Symbol函数,返回一个唯一的symbol数据 一般给对象设置唯一的属性。 多了一个数据类型:Symbol
    • Symbol: 概念:ES6中的添加了一种原始数据类型symbol(已有的原始数据类型:String, Number, boolean, null, undefined, 对象)
    • 特点:
      • Symbol属性对应的值是唯一的,解决命名冲突问题
      • Symbol值不能与其他数据进行计算,包括同字符串拼串
      • for in, for of遍历时不会遍历symbol属性。
    • 使用:
      • 调用Symbol函数得到symbol值
        let symbol = Symbol();let obj = {};obj[symbol] = 'hello';复制代码
      • 传参标识
        let symbol = Symbol('one');let symbol2 = Symbol('two');console.log(symbol);// Symbol('one')console.log(symbol2);// Symbol('two')复制代码
      • 内置Symbol值
        • 除了定义自己使用的Symbol值以外,ES6还提供了11个内置的Symbol值,指向语言内部使用的方法。
        • Symbol.iterator
        • 对象的Symbol.iterator属性,指向该对象的默认遍历器方法(后边讲)

Iterator遍历器

  • 概念: iterator是一种接口机制,为各种不同的数据结构提供统一的访问机制
  • 作用:
    • 为各种数据结构,提供一个统一的、简便的访问接口;
    • 使得数据结构的成员能够按某种次序排列;
    • ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费。 工作原理:
    • 创建一个指针对象(遍历器对象),指向数据结构的起始位置。
    • 第一次调用next方法,指针自动指向数据结构的第一个成员
    • 接下来不断调用next方法,指针会一直往后移动,直到指向最后一个成员
    • 每调用next方法返回的是一个包含value和done的对象,{value: 当前成员的值,done: 布尔值}
      • value表示当前成员的值,done对应的布尔值表示当前的数据的结构是否遍历结束。
      • 当遍历结束的时候返回的value值是undefined,done值为false 原生具备iterator接口的数据(可用for of遍历)
    • Array
    • arguments
    • set容器
    • map容器
    • String
    • 。。。
  • iterator是一个接口机制,为了让所有数据用统一的方式遍历( for of )
    • 通过查看数据类型上是否有Symbol(Symbol.iterator)方法
    • String 、Array、Set、Map、 arguments、dom元素集合(querySelectorAll)
  • 遍历的方法
    • forEach只能数组使用,推荐使用
    • for 只能数组使用, 性能最好
    • while / do while 任意值使用
    • for in 通常用于对象
    • for of 当你不确定要遍历的是什么数据类型。这时候用for of

Generator函数

概念:  1、ES6提供的解决异步编程的方案之一  2、Generator函数是一个状态机,内部封装了不同状态的数据,  3、用来生成遍历器对象  4、可暂停函数(惰性求值), yield可暂停,next方法可启动。每次返回的是yield后的表达式结果特点:  1、function 与函数名之间有一个星号  2、内部用yield表达式来定义不同的状态  例如:    function* generatorExample(){      let result = yield 'hello';  // 状态值为hello      yield 'generator'; // 状态值为generator    }  3、generator函数返回的是指针对象(接11章节里iterator),而不会执行函数内部逻辑  4、调用next方法函数内部逻辑开始执行,遇到yield表达式停止,返回{value: yield后的表达式结果/undefined, done: false/true}  5、再次调用next方法会从上一次停止时的yield处开始,直到最后  6、yield语句返回结果通常为undefined, 当调用next方法时传参内容会作为启动时yield语句的返回值。复制代码
function* fn() {    console.log('函数开始执行了~');    const flag = true;    const result = yield flag ? 123 : 456;    console.log(result);    console.log('函数执行完了~');  }  // 执行generator函数,返回值是一个iterator对象  const iteratorObj = fn();  console.log(iteratorObj);  // 通过iterator对象的next方法执行函数体代码(推着函数动一下)  const result1 = iteratorObj.next(111);  console.log(result1);  // {value: 123, done: false}  value 看yield后面表达式的值, done 看函数是否执行完毕:没有执行完就是false 执行完了就是true  const result2 = iteratorObj.next(222);  console.log(result2);  // 手动给对象添加iterator接口  console.log(Symbol.iterator);  const person = {    name: 'jack',    age: 18,    sex: '男'  }  Object.prototype[Symbol.iterator] = function* () {    for (let key in this) {      yield this[key];    }  }复制代码
  • 案例
/* 需求:请求a数据,再请求b数据,请求c数据   */  function* generator() {    console.log('函数开始执行了~');    const result1 = yield setTimeout(() => {      console.log('请求回来了a数据');      // 请求成功,让generator继续执行      iteratorObj.next('a数据');    }, 3000);    const result2 = yield setTimeout(() => {      console.log('请求回来了b数据');      // 请求成功,让generator继续执行      iteratorObj.next('b数据');    }, 2000);    const result3 = yield setTimeout(() => {      console.log('请求回来了c数据');      // 请求成功,让generator继续执行      iteratorObj.next('c数据');    }, 1000);    console.log(result1, result2, result3);    console.log('函数执行完毕了~');  }  const iteratorObj = generator();  // 为了执行第一个请求  iteratorObj.next();复制代码

async函数

  • async函数(源自ES2017 - ES8)
  • 概念: 真正意义上去解决异步回调的问题,同步流程表达异步操作 本质: Generator的语法糖
  • 语法: async function foo(){ await 异步操作; await 异步操作; }
  • 特点:
    • 不需要像Generator去调用next方法,遇到await等待,当前的异步操作完成就往下执行
    • 返回的总是Promise对象,可以用then方法进行下一步操作
    • async取代Generator函数的星号*,await取代Generator的yield
    • 语意上更为明确,使用简单,经临床验证,暂时没有任何副作用
  • 案例1
async function asyncFn() {    console.log('函数开始执行了~');    /* const promise = new Promise((resolve, reject) => setTimeout(() => reject(123456), 2000));    const promise = new Promise((resolve, reject) => setTimeout(reject.bind(null, 123456), 2000));    */    const promise = new Promise((resolve, reject) => setTimeout(resolve.bind(null, 123456), 2000));    // const promise = Promise.resolve();    // await只等promise对象:等promise对象状态由初始化变成成功状态。    // (一旦promise对象状态是初始化状态,一直等。一旦promise对象状态变成成功的状态,就不等了,执行后面代码)    // 一旦promise对象状态变成失败的状态,就不执行后面代码(如果捕获了async函数promise的异常,就不报错,没有捕获,就会报错)    // result的值就是resolve()传入的参数    const result = await promise;    console.log(result);    await promise;    console.log('函数执行完毕了~');    return 666;  }  // async函数返回值是一个promise对象: 默认是resolved状态  // 如果函数中有promise对象变成失败的状态,就是rejected状态  const result = asyncFn();  result    // 看async函数里面返回值,就是result的值    .then((result) => {      console.log(result);    })    .catch((error) => {      console.log(error);    })  console.log(result);复制代码
  • 案例2
async function asyncFn() {    const result1 = await new Promise((resolve, reject) => {      setTimeout(() => {        console.log('a数据请求成功了~');        resolve('a数据');      }, 3000)    })    const result2 = await new Promise((resolve, reject) => {      setTimeout(() => {        console.log('b数据请求成功了~');        resolve('b数据');      }, 2000)    })    const result3 = await new Promise((resolve, reject) => {      setTimeout(() => {        console.log('c数据请求成功了~');        resolve('c数据');      }, 2000)    })    console.log(result1, result2, result3);    return [result1, result2, result3];  }  const promise = asyncFn();  promise    .then((res) => {      console.log(res); // [result1, result2, result3]    })复制代码

class类

  1. 通过class定义类/实现类的继承
  2. 在类中通过constructor定义构造方法
  3. 通过new来创建类的实例
  4. 通过extends来实现类的继承
  5. 通过super调用父类的构造方法
  6. 重写从父类中继承的一般方法
// 定义类:构造函数  class Father {    // 给实例对象添加属性    constructor(name, age) {      this.name = name;      this.age = age;    }    // 给实例对象添加方法    setName(name) {      this.name = name;    }  }  // 定义子类继承父类,自动继承父类的属性和方法  // 使用继承必须在constructor函数中调用super方法或者不写constructor  class Son extends Father{    // 给实例对象添加属性    constructor(name, age, sex) {      super(name, age); // 调用父类的构造方法: constructor      this.sex = sex;    }    // 给实例对象添加方法    setAge(age) {      this.age = age;    }  }  console.log(Father.prototype);  console.log(typeof Son);  const s = new Son('bob', 20, '男');  console.log(s);复制代码

字符串扩展

  1. String.prototype.includes(str) : 判断是否包含指定的字符串
  2. String.prototype.startsWith(str) : 判断是否以指定字符串开头
  3. String.prototype.endsWith(str) : 判断是否以指定字符串结尾
  4. String.prototype.repeat(count) : 重复指定次数
const str = 'atguigu';  console.log(str.includes('gug')); // true  console.log(str.startsWith('atg')); // true  console.log(str.endsWith('gu')); // true  console.log(str.repeat(3)); // 'atguiguatguiguatguigu'复制代码

数值扩展

  1. 二进制与八进制数值表示法: 二进制用0b, 八进制用0o
  2. Number.isFinite(i) : 判断是否是有限大的数
  3. Number.isNaN(i) : 判断是否是NaN
  4. Number.isInteger(i) : 判断是否是整数
  5. Number.parseInt(str) : 将字符串转换为对应的数值
  6. Math.trunc(i) : 直接去除小数部分
console.log(0o666); // 0 - 7  console.log(0b1010); // 0 - 1   8421法  console.log(Infinity); // 正无穷大  console.log(-Infinity); // 负无穷大  console.log(NaN); // not a number  console.log(Number.isFinite(Infinity)); // false  console.log(Number.isNaN(NaN)); // true  x !== x  console.log(NaN === NaN); // NaN不与任何数相等,包括它自身  console.log(Number.isInteger(1.1)); // false  console.log(Number.parseInt('123a.123')); // 123  整型:整数  console.log(Number.parseFloat('123.123')); // 123.123 浮点型:小数  console.log(Math.trunc(456.865)); // 456  console.log(Math.floor(456.865)); // 456复制代码

数组扩展

  1. Array.from(v) : 将伪数组对象或可遍历对象转换为真数组
  2. Array.of(v1, v2, v3) : 将一系列值转换成数组
  3. Array.prototype.find(function(value, index, arr){return true}) : 找出第一个满足条件返回true的元素
  4. Array.prototype.findIndex(function(value, index, arr){return true}) : 找出第一个满足条件返回true的元素下标
// 伪数组对象  const btns = document.querySelectorAll('button');  // 将伪数组转化为真数组  const newBtns1 = Array.from(btns);  console.log(newBtns1);  const newBtns2 = Array.prototype.slice.call(btns);  console.log(newBtns2);  const newBtns3 = [...btns];  console.log(newBtns3);  console.log(Array.of(1, true, {})); // [1, true, {}]  const arr = [{age: 18}, {age: 19}, {age: 20}, {age: 21}];  // const obj = arr.find((item, index, arr) => item.age === 20);  const index = arr.findIndex((item, index, arr) => item.age === 20);  console.log(index);复制代码

对象扩展

  1. Object.is(v1, v2)
    • 判断2个数据是否完全相等
  2. Object.assign(target, source1, source2..)
    • 将源对象的属性复制到目标对象上
  3. 直接操作 proto 属性
let obj2 = {};obj2.__proto__ = obj1;复制代码
// 全等运算符的问题  console.log(0 === -0); // true  false  console.log(NaN === NaN); // false  true  // Object.is方法解决  console.log(Object.is(1, 1)); // true  console.log(Object.is(0, -0)); // false  console.log(Object.is(NaN, NaN)); // true//is方法用原生实现  function is(a, b) {    /*if (a === b) {      // 判断 0 和 -0 的特殊情况 返回 false      // 0 和 0 / -0 和 -0 的情况返回 true      // return !(-a === b);      return !(-1 / a === 1 / b);    } else {      // 判断 NaN 和 NaN 的特殊情况      return a !== a && b !== b;    }*/    // return a === b ? ((-1 / a === 1 / b) ? false : true) : (a !== a && b !== b ? true : false);    // return (a === b && (!(-1 / a === 1 / b)) || (a !== a && b !== b);    return a === b ? !(-1 / a === 1 / b) : a !== a && b !== b;  }  console.log(is(0, -0)); // false  console.log(is(0, 0)); // true  console.log(is({}, {})); // false  console.log(is(NaN, NaN)); // true  console.log(is(true, true)); // true  const obj = {};  const obj1 = {name: 'jack'};  const obj2 = {age: 18};  // 将后面目标对象上的属性和方法复制到源对象上  const result = Object.assign(obj, obj1, obj2);  console.log(result === obj);复制代码

深度克隆

  • 数据类型:
    • 数据分为基本的数据类型(String, Number, boolean, Null, Undefined)和对象数据类型
    • 基本数据类型: 特点: 存储的是该对象的实际数据
    • 对象数据类型: 特点: 存储的是该对象在栈中引用,真实的数据存放在堆内存里
  • 复制数据
    • 基本数据类型存放的就是实际的数据,可直接复制 let number2 = 2; let number1 = number2;
    • 克隆数据:对象/数组
      • 区别: 浅拷贝/深度拷贝 判断: 拷贝是否全部产生了新的数据还是拷贝的是数据的引用
        • 知识点:对象数据存放的是对象在栈内存的引用,直接复制的是对象的引用
        let obj = {username: 'kobe'}let obj1 = obj; // obj1```复制了obj在栈内存的引用复制代码
      2、常用的拷贝技术
      • arr.concat(): 数组浅拷贝 2). arr.slice(): 数组浅拷贝
      • JSON.parse(JSON.stringify(arr/obj)): 数组或对象深拷贝, 但不能处理函数数据
      • 浅拷贝包含函数数据的对象/数组
      • 深拷贝包含函数数据的对象/数组
  • 浅度克隆
let obj3 = Object.assign({}, obj1);  obj3.hobby.push('rap');  console.log(obj3);  console.log(obj1);复制代码
  • 深度克隆
    • JSON能实现深度克隆,不能克隆函数数据
let obj1 = {name: 'jack', age: 18, hobby: ['篮球', '唱', '跳'], setName (name) {this.name = name;}};const json = JSON.stringify(obj1);const obj4 = JSON.parse(json);console.log(obj1, obj4);obj4.hobby.push('rap');console.log(obj1, obj4);复制代码
// 检查数据类型  function checkType(target) {    return Object.prototype.toString.call(target).slice(8, -1);  }复制代码
// 深度克隆: 深度克隆所有数据  function deepClone(target) {    // 因为不确定克隆的是什么数据,但是能确定的是一定是引用数据类型    let result = null;    // 检查数据的类型    const type = checkType(target);    // 判断数据的类型,如果是对象/数组就处理,不是就直接返回    if (type === 'Object') {      result = {};    } else if (type === 'Array') {      result = [];    } else {      // 其他类型就直接返回      return target;    }    // for in 即能遍历对象也能遍历数组    for (let key in target) {      // 获取属性值      const value = target[key];      // 将克隆的值作为新对象的某个属性的值      // const newValue = deepClone(value);      // result[key] = newValue;      result[key] = deepClone(value);    }    return result;  }  const person = {name: 'jack', age: 18, hobby: ['篮球', '唱', '跳'], sex: { option1: '男', option2: '女' }, setName (name) {this.name = name;}};  const newObj = deepClone(person);  newObj.hobby.push('rap');  console.log(person, newObj);复制代码

Set和Map数据结构

  1. Set容器 : 无序不可重复的多个value的集合体
    • Set()
    • Set(array)
    • Set.prototype.add(value) 给set容器添加一个值
    • Set.prototype.delete(value) 删除一个
    • Set.prototype.has(value)
    • Set.prototype.clear() 清空所有
    • size
  2. Map容器 : 无序的 key不重复的多个key-value的集合体
    • Map()
    • Map(array)
    • set(key, value)//添加
    • get(key)
    • delete(key)
    • has(key)
    • clear()
    • size
const arr = [2, 5, 8, 5, 1, 4, 8];  const s1 = new Set(arr);  console.log(s1);  // 数组去重  console.log([...new Set(arr)]);  s1.add(9);  console.log(s1);  console.log(s1.has(9));  s1.clear();  console.log(s1);  // 无序的 key不重复的多个key-value的集合体  const array = [1, 2, 3];  const m1 = new Map([[{name: 'jack'}, function fn() {}], [array, true], [array, false]]);  console.log(m1);复制代码

ES7(常用的)

  1. 指数运算符(幂): **
  2. Array.prototype.includes(value) : 判断数组中是否包含指定value
console.log(3 ** 3);//27const arr = [1, 2, 5, 6, 8];console.log(arr.includes(3));//true复制代码

ES8(常用的)

==async函数也是ES8中提出的==

  • Object.values()
  • Object.entries()
  • Object.keys()
const person = {name: 'jack', age: 18}; // [['name', 'jack'], ['age': 18]]  // 提取对象中所有属性名,作为一个数组返回  console.log(Object.keys(person));  // 提取对象中所有属性值,作为一个数组返回  console.log(Object.values(person));  console.log(Object.entries(person)); // [['name', 'jack'], ['age': 18]]复制代码

ES9(常用的)Promise.finally

const promise = new Promise((resolve, reject) => setTimeout(reject, 1000));  promise    .then(() => {      console.log('then');    })    .catch(() => {      console.log('catch');    })    .finally(() => {      // 不管成功还是失败都会触发      console.log('finally');    })复制代码

ES10(常用的)

  • Array扩展方法
    • 数组降维、数组的扁平化
// 数组降维、数组的扁平化  const arr = [[1, 2], [[[3]]], [[4], [[[[5]], 6]]]];  console.log(arr.flat(1));  console.log(arr.flat(Infinity));/*    1. flat 全部降成1维    2. 可以传参,根据参数降维  flat方法的实现源代码  Array.prototype.flat = function (num) {    // this 就指向要处理的数组  --> arr.flat()    let result = [];    /!*this.forEach((item, index) => {      if (Array.isArray(item)) {        result = result.concat(item.flat());      } else {        result.push(item);      }    })*!/    this.forEach((item) => Array.isArray(item) ? result = result.concat(item.flat()) : result.push(item));    return result;  }  Array.prototype.flat = function (num) {    // this 就指向要处理的数组  --> arr.flat()    num--;    if (num < 0) return this;    let result = [];    /!*this.forEach((item, index) => {      if (Array.isArray(item)) {        result = result.concat(item.flat());      } else {        result.push(item);      }    })*!/    this.forEach((item) => Array.isArray(item) ? result = result.concat(item.flat(num)) : result.push(item));    return result;  }*/复制代码
  • 动态import
// 按需加载  document.getElementById('btn').onclick = function () {    // 只会加载一次    import('./a.js');  }复制代码

函数节流和函数防抖

  • 节流函数
// 绑定滚轮事件  // 需求:滚轮事件发现单位时间内触发回调函数的次数太多,性能不好  // 解决:让函数调用次数更少  // 节流函数:在单位时间内让函数只调用一次  document.onscroll = throttle(function (e) {    console.log('滚轮事件触发了~');    console.log(e);    console.log(this);  }, 1000)  // 节流函数  function throttle(fn, time) {    // 开始时间    let startTime = 0;    // 实际上下面函数就是DOM事件回调函数    return function () {      // 结束时间: 调用当前函数的时间      const endTime = Date.now();      // fn函数的this指向问题,参数有问题(少event)      if (endTime - startTime >= time) {        // 大于1s, 可以触发, 小于1s就不触发        fn.apply(this, arguments);        // 重置开始时间        startTime = endTime;      }    }  }复制代码
  • 防抖函数
// 绑定滚轮事件  // 需求:滚轮事件发现单位时间内触发回调函数的次数太多,性能不好  // 解决:让函数调用次数更少  // 节流函数:在单位时间内让函数只调用一次,是第一次生效  // 防抖函数:在单位时间内让函数只调用一次,是最后一次生效  document.onscroll = debounce(function (e) {    console.log('滚轮事件触发了~');    console.log(e);    console.log(this);  }, 1000)  // 防抖函数  function debounce(fn, time) {    let timerId = null;    // 实际上下面函数就是DOM事件回调函数    return function () {      clearTimeout(timerId);      const args = arguments;      timerId = setTimeout(() => {        // fn函数的this指向问题,参数有问题(少event)        // 大于1s, 可以触发, 小于1s就不触发        fn.apply(this, args);      }, time);    }  }复制代码

转载于:https://juejin.im/post/5cebd136f265da1bc94eccf1

你可能感兴趣的文章
程序员写300行代码获1.5万月薪,网友:我可以敲到公司破产
查看>>
重要宣布:Flutter 首个发布预览版
查看>>
广东移动与阿里巴巴宣布共建反诈实验室
查看>>
[译] Laravel-mix 3.0 中文文档
查看>>
深入理解Java SPI之入门篇
查看>>
机器学习之决策树
查看>>
我的阿里之路+Java面经考点
查看>>
Kotlin——中级篇(四):继承类详解
查看>>
windows10 chrome 调试 ios safari 方法
查看>>
QML学习笔记(七)-如何查看帮助手册中的控件例子
查看>>
旧手机的新玩法:postmarketOS 已适配上百款安卓手机
查看>>
InitAdmin 201904 更新,首创云后台概念
查看>>
jvm系列文章
查看>>
Countly 19.02.1 发布,实时移动和 web 分析报告平台
查看>>
自定义 标签
查看>>
百度贴吧发贴回贴POST接口
查看>>
【Recorder.js+百度语音识别】全栈方案技术细节
查看>>
PS背后的神秘AI力量 是Adobe憋了十年的神功
查看>>
加速Web自动化测试
查看>>
8月分享与总结
查看>>