es6面试题总结

一曲冷凌霜 提交于 2019-12-24 05:50:24

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}定义
  1. const person = {name: 'jack', age: 18};
  2. console.log('姓名:' + person.name + ' 年龄:' + person.age);
  3. console.log(`姓名:${person.name} 年龄: ${person.age}`);
  4. 复制代码

对象的简写方法

简化的对象写法

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

形参默认值

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

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

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

三点运算符

用途

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

箭头函数

  • 作用: 定义匿名函数

  • 基本语法:

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

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

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

Promise对象

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

  • 使用promise封装处理ajax请求

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

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

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

Symbol

  • 前言:ES5中对象的属性名都是字符串,容易造成重名,污染环境
  • 每次调用Symbol函数,返回一个唯一的symbol数据 一般给对象设置唯一的属性。 多了一个数据类型:Symbol
    • Symbol: 概念:ES6中的添加了一种原始数据类型symbol(已有的原始数据类型:String, Number, boolean, null, undefined, 对象)
    • 特点:
      • Symbol属性对应的值是唯一的,解决命名冲突问题
      • Symbol值不能与其他数据进行计算,包括同字符串拼串
      • for in, for of遍历时不会遍历symbol属性。
    • 使用:
      • 调用Symbol函数得到symbol值
        1. let symbol = Symbol();
        2. let obj = {};
        3. obj[symbol] = 'hello';
        4. 复制代码
      • 传参标识
        1. let symbol = Symbol('one');
        2. let symbol2 = Symbol('two');
        3. console.log(symbol);// Symbol('one')
        4. console.log(symbol2);// Symbol('two')
        5. 复制代码
      • 内置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. 概念:
  2. 1、ES6提供的解决异步编程的方案之一
  3. 2、Generator函数是一个状态机,内部封装了不同状态的数据,
  4. 3、用来生成遍历器对象
  5. 4、可暂停函数(惰性求值), yield可暂停,next方法可启动。每次返回的是yield后的表达式结果
  6. 特点:
  7. 1function 与函数名之间有一个星号
  8. 2、内部用yield表达式来定义不同的状态
  9. 例如:
  10. function* generatorExample(){
  11. let result = yield 'hello'; // 状态值为hello
  12. yield 'generator'; // 状态值为generator
  13. }
  14. 3、generator函数返回的是指针对象(接11章节里iterator),而不会执行函数内部逻辑
  15. 4、调用next方法函数内部逻辑开始执行,遇到yield表达式停止,返回{value: yield后的表达式结果/undefined, done: false/true}
  16. 5、再次调用next方法会从上一次停止时的yield处开始,直到最后
  17. 6yield语句返回结果通常为undefined, 当调用next方法时传参内容会作为启动时yield语句的返回值。
  18. 复制代码
  1. function* fn() {
  2. console.log('函数开始执行了~');
  3. const flag = true;
  4. const result = yield flag ? 123 : 456;
  5. console.log(result);
  6. console.log('函数执行完了~');
  7. }
  8. // 执行generator函数,返回值是一个iterator对象
  9. const iteratorObj = fn();
  10. console.log(iteratorObj);
  11. // 通过iterator对象的next方法执行函数体代码(推着函数动一下)
  12. const result1 = iteratorObj.next(111);
  13. console.log(result1); // {value: 123, done: false} value 看yield后面表达式的值, done 看函数是否执行完毕:没有执行完就是false 执行完了就是true
  14. const result2 = iteratorObj.next(222);
  15. console.log(result2);
  16. // 手动给对象添加iterator接口
  17. console.log(Symbol.iterator);
  18. const person = {
  19. name: 'jack',
  20. age: 18,
  21. sex: '男'
  22. }
  23. Object.prototype[Symbol.iterator] = function* () {
  24. for (let key in this) {
  25. yield this[key];
  26. }
  27. }
  28. 复制代码
  • 案例
  1. /*
  2. 需求:请求a数据,再请求b数据,请求c数据
  3. */
  4. function* generator() {
  5. console.log('函数开始执行了~');
  6. const result1 = yield setTimeout(() => {
  7. console.log('请求回来了a数据');
  8. // 请求成功,让generator继续执行
  9. iteratorObj.next('a数据');
  10. }, 3000);
  11. const result2 = yield setTimeout(() => {
  12. console.log('请求回来了b数据');
  13. // 请求成功,让generator继续执行
  14. iteratorObj.next('b数据');
  15. }, 2000);
  16. const result3 = yield setTimeout(() => {
  17. console.log('请求回来了c数据');
  18. // 请求成功,让generator继续执行
  19. iteratorObj.next('c数据');
  20. }, 1000);
  21. console.log(result1, result2, result3);
  22. console.log('函数执行完毕了~');
  23. }
  24. const iteratorObj = generator();
  25. // 为了执行第一个请求
  26. iteratorObj.next();
  27. 复制代码

async函数

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

class类

  1. 通过class定义类/实现类的继承
  2. 在类中通过constructor定义构造方法
  3. 通过new来创建类的实例
  4. 通过extends来实现类的继承
  5. 通过super调用父类的构造方法
  6. 重写从父类中继承的一般方法
  1. // 定义类:构造函数
  2. class Father {
  3. // 给实例对象添加属性
  4. constructor(name, age) {
  5. this.name = name;
  6. this.age = age;
  7. }
  8. // 给实例对象添加方法
  9. setName(name) {
  10. this.name = name;
  11. }
  12. }
  13. // 定义子类继承父类,自动继承父类的属性和方法
  14. // 使用继承必须在constructor函数中调用super方法或者不写constructor
  15. class Son extends Father{
  16. // 给实例对象添加属性
  17. constructor(name, age, sex) {
  18. super(name, age); // 调用父类的构造方法: constructor
  19. this.sex = sex;
  20. }
  21. // 给实例对象添加方法
  22. setAge(age) {
  23. this.age = age;
  24. }
  25. }
  26. console.log(Father.prototype);
  27. console.log(typeof Son);
  28. const s = new Son('bob', 20, '男');
  29. console.log(s);
  30. 复制代码

字符串扩展

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

数值扩展

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

数组扩展

  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的元素下标
  1. // 伪数组对象
  2. const btns = document.querySelectorAll('button');
  3. // 将伪数组转化为真数组
  4. const newBtns1 = Array.from(btns);
  5. console.log(newBtns1);
  6. const newBtns2 = Array.prototype.slice.call(btns);
  7. console.log(newBtns2);
  8. const newBtns3 = [...btns];
  9. console.log(newBtns3);
  10. console.log(Array.of(1, true, {})); // [1, true, {}]
  11. const arr = [{age: 18}, {age: 19}, {age: 20}, {age: 21}];
  12. // const obj = arr.find((item, index, arr) => item.age === 20);
  13. const index = arr.findIndex((item, index, arr) => item.age === 20);
  14. console.log(index);
  15. 复制代码

对象扩展

  1. Object.is(v1, v2)
    • 判断2个数据是否完全相等
  2. Object.assign(target, source1, source2..)
    • 将源对象的属性复制到目标对象上
  3. 直接操作 proto 属性
  1. let obj2 = {};
  2. obj2.__proto__ = obj1;
  3. 复制代码
  1. // 全等运算符的问题
  2. console.log(0 === -0); // true false
  3. console.log(NaN === NaN); // false true
  4. // Object.is方法解决
  5. console.log(Object.is(1, 1)); // true
  6. console.log(Object.is(0, -0)); // false
  7. console.log(Object.is(NaN, NaN)); // true
  8. //is方法用原生实现
  9. function is(a, b) {
  10. /*if (a === b) {
  11. // 判断 0 和 -0 的特殊情况 返回 false
  12. // 0 和 0 / -0 和 -0 的情况返回 true
  13. // return !(-a === b);
  14. return !(-1 / a === 1 / b);
  15. } else {
  16. // 判断 NaN 和 NaN 的特殊情况
  17. return a !== a && b !== b;
  18. }*/
  19. // return a === b ? ((-1 / a === 1 / b) ? false : true) : (a !== a && b !== b ? true : false);
  20. // return (a === b && (!(-1 / a === 1 / b)) || (a !== a && b !== b);
  21. return a === b ? !(-1 / a === 1 / b) : a !== a && b !== b;
  22. }
  23. console.log(is(0, -0)); // false
  24. console.log(is(0, 0)); // true
  25. console.log(is({}, {})); // false
  26. console.log(is(NaN, NaN)); // true
  27. console.log(is(true, true)); // true
  28. const obj = {};
  29. const obj1 = {name: 'jack'};
  30. const obj2 = {age: 18};
  31. // 将后面目标对象上的属性和方法复制到源对象上
  32. const result = Object.assign(obj, obj1, obj2);
  33. console.log(result === obj);
  34. 复制代码

深度克隆

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

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
  1. const arr = [2, 5, 8, 5, 1, 4, 8];
  2. const s1 = new Set(arr);
  3. console.log(s1);
  4. // 数组去重
  5. console.log([...new Set(arr)]);
  6. s1.add(9);
  7. console.log(s1);
  8. console.log(s1.has(9));
  9. s1.clear();
  10. console.log(s1);
  11. // 无序的 key不重复的多个key-value的集合体
  12. const array = [1, 2, 3];
  13. const m1 = new Map([[{name: 'jack'}, function fn() {}], [array, true], [array, false]]);
  14. console.log(m1);
  15. 复制代码

ES7(常用的)

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

ES8(常用的)

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

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

ES9(常用的)Promise.finally

  1. const promise = new Promise((resolve, reject) => setTimeout(reject, 1000));
  2. promise
  3. .then(() => {
  4. console.log('then');
  5. })
  6. .catch(() => {
  7. console.log('catch');
  8. })
  9. .finally(() => {
  10. // 不管成功还是失败都会触发
  11. console.log('finally');
  12. })
  13. 复制代码

ES10(常用的)

  • Array扩展方法
    • 数组降维、数组的扁平化
  1. // 数组降维、数组的扁平化
  2. const arr = [[1, 2], [[[3]]], [[4], [[[[5]], 6]]]];
  3. console.log(arr.flat(1));
  4. console.log(arr.flat(Infinity));
  5. /*
  6. 1. flat 全部降成1维
  7. 2. 可以传参,根据参数降维
  8. flat方法的实现源代码
  9. Array.prototype.flat = function (num) {
  10. // this 就指向要处理的数组 --> arr.flat()
  11. let result = [];
  12. /!*this.forEach((item, index) => {
  13. if (Array.isArray(item)) {
  14. result = result.concat(item.flat());
  15. } else {
  16. result.push(item);
  17. }
  18. })*!/
  19. this.forEach((item) => Array.isArray(item) ? result = result.concat(item.flat()) : result.push(item));
  20. return result;
  21. }
  22. Array.prototype.flat = function (num) {
  23. // this 就指向要处理的数组 --> arr.flat()
  24. num--;
  25. if (num < 0) return this;
  26. let result = [];
  27. /!*this.forEach((item, index) => {
  28. if (Array.isArray(item)) {
  29. result = result.concat(item.flat());
  30. } else {
  31. result.push(item);
  32. }
  33. })*!/
  34. this.forEach((item) => Array.isArray(item) ? result = result.concat(item.flat(num)) : result.push(item));
  35. return result;
  36. }
  37. */
  38. 复制代码
  • 动态import
  1. // 按需加载
  2. document.getElementById('btn').onclick = function () {
  3. // 只会加载一次
  4. import('./a.js');
  5. }
  6. 复制代码

函数节流和函数防抖

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

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

                        <li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#csdnc-thumbsup"></use>
                        </svg><span class="name">点赞</span>
                        <span class="count"></span>
                        </a></li>
                        <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;popu_824&quot;}"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-csdnc-Collection-G"></use>
                        </svg><span class="name">收藏</span></a></li>
                        <li class="tool-item tool-active is-share"><a href="javascript:;"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-csdnc-fenxiang"></use>
                        </svg>分享</a></li>
                        <!--打赏开始-->
                                                <!--打赏结束-->
                                                <li class="tool-item tool-more">
                            <a>
                            <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
                            </a>
                            <ul class="more-box">
                                <li class="item"><a class="article-report">文章举报</a></li>
                            </ul>
                        </li>
                                            </ul>
                </div>
                            </div>
            <div class="person-messagebox">
                <div class="left-message"><a href="https://blog.csdn.net/weixin_33862041">
                    <img src="https://profile.csdnimg.cn/0/5/2/3_weixin_33862041" class="avatar_pic" username="weixin_33862041">
                                            <img src="https://g.csdnimg.cn/static/user-reg-year/1x/4.png" class="user-years">
                                    </a></div>
                <div class="middle-message">
                                        <div class="title"><span class="tit"><a href="https://blog.csdn.net/weixin_33862041" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}" target="_blank">weixin_33862041</a></span>
                                            </div>
                    <div class="text"><span>发布了148 篇原创文章</span> · <span>获赞 33</span> · <span>访问量 15万+</span></div>
                </div>
                                <div class="right-message">
                                            <a href="https://im.csdn.net/im/main.html?userName=weixin_33862041" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信
                        </a>
                                                            <a class="btn btn-sm  bt-button personal-watch" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}">关注</a>
                                    </div>
                            </div>
                    </div>
    

    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}定义
    1. const person = {name: 'jack', age: 18};
    2. console.log('姓名:' + person.name + ' 年龄:' + person.age);
    3. console.log(`姓名:${person.name} 年龄: ${person.age}`);
    4. 复制代码

    对象的简写方法

    简化的对象写法

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

    形参默认值

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

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

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

    三点运算符

    用途

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

    箭头函数

    • 作用: 定义匿名函数

    • 基本语法:

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

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

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

    Promise对象

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

    • 使用promise封装处理ajax请求

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

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

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

    Symbol

    • 前言:ES5中对象的属性名都是字符串,容易造成重名,污染环境
    • 每次调用Symbol函数,返回一个唯一的symbol数据 一般给对象设置唯一的属性。 多了一个数据类型:Symbol
      • Symbol: 概念:ES6中的添加了一种原始数据类型symbol(已有的原始数据类型:String, Number, boolean, null, undefined, 对象)
      • 特点:
        • Symbol属性对应的值是唯一的,解决命名冲突问题
        • Symbol值不能与其他数据进行计算,包括同字符串拼串
        • for in, for of遍历时不会遍历symbol属性。
      • 使用:
        • 调用Symbol函数得到symbol值
          1. let symbol = Symbol();
          2. let obj = {};
          3. obj[symbol] = 'hello';
          4. 复制代码
        • 传参标识
          1. let symbol = Symbol('one');
          2. let symbol2 = Symbol('two');
          3. console.log(symbol);// Symbol('one')
          4. console.log(symbol2);// Symbol('two')
          5. 复制代码
        • 内置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. 概念:
    2. 1、ES6提供的解决异步编程的方案之一
    3. 2、Generator函数是一个状态机,内部封装了不同状态的数据,
    4. 3、用来生成遍历器对象
    5. 4、可暂停函数(惰性求值), yield可暂停,next方法可启动。每次返回的是yield后的表达式结果
    6. 特点:
    7. 1function 与函数名之间有一个星号
    8. 2、内部用yield表达式来定义不同的状态
    9. 例如:
    10. function* generatorExample(){
    11. let result = yield 'hello'; // 状态值为hello
    12. yield 'generator'; // 状态值为generator
    13. }
    14. 3、generator函数返回的是指针对象(接11章节里iterator),而不会执行函数内部逻辑
    15. 4、调用next方法函数内部逻辑开始执行,遇到yield表达式停止,返回{value: yield后的表达式结果/undefined, done: false/true}
    16. 5、再次调用next方法会从上一次停止时的yield处开始,直到最后
    17. 6yield语句返回结果通常为undefined, 当调用next方法时传参内容会作为启动时yield语句的返回值。
    18. 复制代码
    1. function* fn() {
    2. console.log('函数开始执行了~');
    3. const flag = true;
    4. const result = yield flag ? 123 : 456;
    5. console.log(result);
    6. console.log('函数执行完了~');
    7. }
    8. // 执行generator函数,返回值是一个iterator对象
    9. const iteratorObj = fn();
    10. console.log(iteratorObj);
    11. // 通过iterator对象的next方法执行函数体代码(推着函数动一下)
    12. const result1 = iteratorObj.next(111);
    13. console.log(result1); // {value: 123, done: false} value 看yield后面表达式的值, done 看函数是否执行完毕:没有执行完就是false 执行完了就是true
    14. const result2 = iteratorObj.next(222);
    15. console.log(result2);
    16. // 手动给对象添加iterator接口
    17. console.log(Symbol.iterator);
    18. const person = {
    19. name: 'jack',
    20. age: 18,
    21. sex: '男'
    22. }
    23. Object.prototype[Symbol.iterator] = function* () {
    24. for (let key in this) {
    25. yield this[key];
    26. }
    27. }
    28. 复制代码
    • 案例
    1. /*
    2. 需求:请求a数据,再请求b数据,请求c数据
    3. */
    4. function* generator() {
    5. console.log('函数开始执行了~');
    6. const result1 = yield setTimeout(() => {
    7. console.log('请求回来了a数据');
    8. // 请求成功,让generator继续执行
    9. iteratorObj.next('a数据');
    10. }, 3000);
    11. const result2 = yield setTimeout(() => {
    12. console.log('请求回来了b数据');
    13. // 请求成功,让generator继续执行
    14. iteratorObj.next('b数据');
    15. }, 2000);
    16. const result3 = yield setTimeout(() => {
    17. console.log('请求回来了c数据');
    18. // 请求成功,让generator继续执行
    19. iteratorObj.next('c数据');
    20. }, 1000);
    21. console.log(result1, result2, result3);
    22. console.log('函数执行完毕了~');
    23. }
    24. const iteratorObj = generator();
    25. // 为了执行第一个请求
    26. iteratorObj.next();
    27. 复制代码

    async函数

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

    class类

    1. 通过class定义类/实现类的继承
    2. 在类中通过constructor定义构造方法
    3. 通过new来创建类的实例
    4. 通过extends来实现类的继承
    5. 通过super调用父类的构造方法
    6. 重写从父类中继承的一般方法
    1. // 定义类:构造函数
    2. class Father {
    3. // 给实例对象添加属性
    4. constructor(name, age) {
    5. this.name = name;
    6. this.age = age;
    7. }
    8. // 给实例对象添加方法
    9. setName(name) {
    10. this.name = name;
    11. }
    12. }
    13. // 定义子类继承父类,自动继承父类的属性和方法
    14. // 使用继承必须在constructor函数中调用super方法或者不写constructor
    15. class Son extends Father{
    16. // 给实例对象添加属性
    17. constructor(name, age, sex) {
    18. super(name, age); // 调用父类的构造方法: constructor
    19. this.sex = sex;
    20. }
    21. // 给实例对象添加方法
    22. setAge(age) {
    23. this.age = age;
    24. }
    25. }
    26. console.log(Father.prototype);
    27. console.log(typeof Son);
    28. const s = new Son('bob', 20, '男');
    29. console.log(s);
    30. 复制代码

    字符串扩展

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

    数值扩展

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

    数组扩展

    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的元素下标
    1. // 伪数组对象
    2. const btns = document.querySelectorAll('button');
    3. // 将伪数组转化为真数组
    4. const newBtns1 = Array.from(btns);
    5. console.log(newBtns1);
    6. const newBtns2 = Array.prototype.slice.call(btns);
    7. console.log(newBtns2);
    8. const newBtns3 = [...btns];
    9. console.log(newBtns3);
    10. console.log(Array.of(1, true, {})); // [1, true, {}]
    11. const arr = [{age: 18}, {age: 19}, {age: 20}, {age: 21}];
    12. // const obj = arr.find((item, index, arr) => item.age === 20);
    13. const index = arr.findIndex((item, index, arr) => item.age === 20);
    14. console.log(index);
    15. 复制代码

    对象扩展

    1. Object.is(v1, v2)
      • 判断2个数据是否完全相等
    2. Object.assign(target, source1, source2..)
      • 将源对象的属性复制到目标对象上
    3. 直接操作 proto 属性
    1. let obj2 = {};
    2. obj2.__proto__ = obj1;
    3. 复制代码
    1. // 全等运算符的问题
    2. console.log(0 === -0); // true false
    3. console.log(NaN === NaN); // false true
    4. // Object.is方法解决
    5. console.log(Object.is(1, 1)); // true
    6. console.log(Object.is(0, -0)); // false
    7. console.log(Object.is(NaN, NaN)); // true
    8. //is方法用原生实现
    9. function is(a, b) {
    10. /*if (a === b) {
    11. // 判断 0 和 -0 的特殊情况 返回 false
    12. // 0 和 0 / -0 和 -0 的情况返回 true
    13. // return !(-a === b);
    14. return !(-1 / a === 1 / b);
    15. } else {
    16. // 判断 NaN 和 NaN 的特殊情况
    17. return a !== a && b !== b;
    18. }*/
    19. // return a === b ? ((-1 / a === 1 / b) ? false : true) : (a !== a && b !== b ? true : false);
    20. // return (a === b && (!(-1 / a === 1 / b)) || (a !== a && b !== b);
    21. return a === b ? !(-1 / a === 1 / b) : a !== a && b !== b;
    22. }
    23. console.log(is(0, -0)); // false
    24. console.log(is(0, 0)); // true
    25. console.log(is({}, {})); // false
    26. console.log(is(NaN, NaN)); // true
    27. console.log(is(true, true)); // true
    28. const obj = {};
    29. const obj1 = {name: 'jack'};
    30. const obj2 = {age: 18};
    31. // 将后面目标对象上的属性和方法复制到源对象上
    32. const result = Object.assign(obj, obj1, obj2);
    33. console.log(result === obj);
    34. 复制代码

    深度克隆

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

    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
    1. const arr = [2, 5, 8, 5, 1, 4, 8];
    2. const s1 = new Set(arr);
    3. console.log(s1);
    4. // 数组去重
    5. console.log([...new Set(arr)]);
    6. s1.add(9);
    7. console.log(s1);
    8. console.log(s1.has(9));
    9. s1.clear();
    10. console.log(s1);
    11. // 无序的 key不重复的多个key-value的集合体
    12. const array = [1, 2, 3];
    13. const m1 = new Map([[{name: 'jack'}, function fn() {}], [array, true], [array, false]]);
    14. console.log(m1);
    15. 复制代码

    ES7(常用的)

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

    ES8(常用的)

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

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

    ES9(常用的)Promise.finally

    1. const promise = new Promise((resolve, reject) => setTimeout(reject, 1000));
    2. promise
    3. .then(() => {
    4. console.log('then');
    5. })
    6. .catch(() => {
    7. console.log('catch');
    8. })
    9. .finally(() => {
    10. // 不管成功还是失败都会触发
    11. console.log('finally');
    12. })
    13. 复制代码

    ES10(常用的)

    • Array扩展方法
      • 数组降维、数组的扁平化
    1. // 数组降维、数组的扁平化
    2. const arr = [[1, 2], [[[3]]], [[4], [[[[5]], 6]]]];
    3. console.log(arr.flat(1));
    4. console.log(arr.flat(Infinity));
    5. /*
    6. 1. flat 全部降成1维
    7. 2. 可以传参,根据参数降维
    8. flat方法的实现源代码
    9. Array.prototype.flat = function (num) {
    10. // this 就指向要处理的数组 --> arr.flat()
    11. let result = [];
    12. /!*this.forEach((item, index) => {
    13. if (Array.isArray(item)) {
    14. result = result.concat(item.flat());
    15. } else {
    16. result.push(item);
    17. }
    18. })*!/
    19. this.forEach((item) => Array.isArray(item) ? result = result.concat(item.flat()) : result.push(item));
    20. return result;
    21. }
    22. Array.prototype.flat = function (num) {
    23. // this 就指向要处理的数组 --> arr.flat()
    24. num--;
    25. if (num < 0) return this;
    26. let result = [];
    27. /!*this.forEach((item, index) => {
    28. if (Array.isArray(item)) {
    29. result = result.concat(item.flat());
    30. } else {
    31. result.push(item);
    32. }
    33. })*!/
    34. this.forEach((item) => Array.isArray(item) ? result = result.concat(item.flat(num)) : result.push(item));
    35. return result;
    36. }
    37. */
    38. 复制代码
    • 动态import
    1. // 按需加载
    2. document.getElementById('btn').onclick = function () {
    3. // 只会加载一次
    4. import('./a.js');
    5. }
    6. 复制代码

    函数节流和函数防抖

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

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

    易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
    该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!