2024年Web前端最新ES6知识汇总_es6 catch后面绑定的error怎么省略,vivoWeb前端开发面试

性能优化

1.webpack打包文件体积过大?(最终打包为一个js文件)

2.如何优化webpack构建的性能

3.移动端的性能优化

4.Vue的SPA 如何优化加载速度

5.移动端300ms延迟

6.页面的重构

所有的知识点都有详细的解答,我整理成了280页PDF《前端校招面试真题精编解析》。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

//单行函数体可以同时省略 {} 和 return
const add = (x,y) => x+y;
// 多行函数体不能再化简了
const add = (x, y) => {
const sum = x + y;
return sum;
};

(3) 单行对象

      // 3.单行对象
     const add = (x, y) => {
         return {
           value: x + y
      };
    };
     const add = (x, y) => ({
      value: x + y
     });
​
   // 如果箭头函数返回单行对象,可以在 {} 外面加上 (),让浏览器不再认为那是函数体的花括号
​
    const add = (x, y) => [x, y]; //返回单行数组是不会出现简写单行对象的问题的,依旧按照化简单行函数的原则进行化简即可。
非箭头函数的this指向

(1)全局作用域于的this指向(简单) 指向的是window

// 1.全局作用域中的 this 指向
console.log(this); // window

(2)一般非箭头函数的this指向

      // 2.一般函数(非箭头函数)中的 this 指向
      // 'use strict';
      function add() {
        console.log(this);
      }
      
     // 只有在函数调用的时候 this 指向才确定,不调用的时候,不知道指向谁
     // this 指向和函数在哪儿调用没关系,只和谁在调用有关
     // 没有具体调用对象的话,this 指向 undefined,在非严格模式下,转向 window 
     
     
     // 严格模式('use strict')就指向 undefined
      add(); // undefined->window(非严格模式下,浏览器把他从undefined转化为window)
       
       
       const calc = {
        add: add
      };
      calc.add(); // calc 
      
      const adder = calc.add;
      adder(); // undefined->window(非严格模式下)
      

(2)箭头函数的this指向

      // 1.箭头函数中的 this 指向
      // 箭头函数没有自己的 this
      const calc = {
        add: () => {
          console.log(this);
        }
      };
      calc.add(); // window
      
      //首先在箭头函数作用域中寻找this,由于箭头函数没有自己的 this,因此向外寻找,外面就是全局作用域 window
      
      // 2.练习
      // 'use strict';
      const calc = {
        add: function () {
          // this
          const adder = () => {
            console.log(this);
          };
          adder();
        }
      };
      calc.add(); // calc
      
      const addFn = calc.add;
      addFn(); // 非严格模式,undefined->window
​
不适用箭头函数的场景
//(1)不能用箭头函数书写构造函数
// (2) 需要 this 指向调用对象的时候,主要用于给dom绑定事件,因为箭头函数没有自己的this
      document.onclick = function () {
      console.log(this);
      };
      document.addEventListener(
         'click',
         () => {
           console.log(this); //window
         },
         false
       );
      
 // 3.需要使用 arguments 的时候,但是箭头函数中没有 arguments
       function add() {
         console.log(arguments);
       }
       add(1, 2,3,4,5);
​
       const add = () => console.log(arguments);
       add();
​

3 解构赋值:数据解析出来=>赋值

数组:

数组的解构是:解析出右边变量的数据,赋值给相同索引值的常量/变量,不取的数据可以用逗号跳过

数组的默认值:只有当数组的成员严格===undefined的时候,默认值才能生效

        // const [a,,c] = [1,2,3];
        // const [a,b] = [];    // a = undefined, b=undefined
        // const [a =2,b] = [1];   // a = 1, b=undefined
        // const [a=1,b=2]=[];     // a = 1, b=2
        const [a=1,b=2]=[3,null];  // a = 1, b=null,没有严格等于undefined
        console.log(b);

数组的默认值如果是一个表达式,那么该默认表达式就是惰性求值的,用到的时候会执行,用不到就不执行

        const func = ()=>{
            console.log(func);
            return 2
        };
​
        // const [x=func()] = [1];  // x=1,不执行func
        // const [x=func()] = [1]; //x=2,执行func
        console.log(x);
类数组:

(1) arguments

        function func(){
            const [a,b]=arguments;
            console.log(a,b);
        };
        func(); //undefined undefined
        func(1,2) //a=1,b=2

(2) NodeList

        console.log(document.querySelectorAll('p'));  //NodeList(2) [p, p]
        const [p1,p2] = document.querySelectorAll('p');
        console.log(p1,p2); //<p></p>   <p></p>

(3)函数参数

        const arr =[1,1];
        const add = ([x=0,y=0]=[]) => {
            return x+y;
        } //这里一定要是[x=0,y=0]=[]才能满足不传参数时,严格等于undefined
        
        console.log(add());  //0
        console.log(add(arr));  //2

(4)交换变量

        let x = 1;
        let y = 2;
        [y,x] = [x,y]; //这就是数组解构赋值的原理,先把右边的数据解构出来,然后根据索引值赋值给变量
        console.log(x,y);  //2,1
对象:

对象解构赋值看两点:

(1) 结构匹配 {}={}

(2)相同的属性名完成对应的属性值赋值

        const{username:username1,age:age2} = {username:'alex',age:12};
        console.log(username1,age2); 
        //这就是找到相同的属性名,然后把对应的属性值赋值到username1,age2,这样打印结果是alex 12

默认值:

(1)首先也是严格等于=== undefined时,默认值才能有效

这里注意默认值是书写方式是: username='alex’不是username:‘alex’,书写上的语法

        const Info = ({username='alex',age=12}={})=>{
            console.log(username,age);
​
        };
​
        Info() //alex 12
        Info({username:'wumingna',age:12}); //wumingna 12

(2)和数组一样,默认值如果是表达式的话,是惰性求值的

(3)当将一个已经声明的变量用于对象的解构赋值时,要加上圆括弧,数组不用在意这个

​
        let x =2;
        ({x} = {x:1});
        console.log(x);

(4)对象可以取到继承的属性,根据原型链查找

其他类型数据

字符串:

字符串的解构赋值既可以参照数组也可以按照对象,都是根据index赋值的

        // 数组
         const [a,b,,,e] = 'hello';
         console.log(a,b,e); //h,e,o
        
        // 对象
        const {0:a,1:b,3:c} = 'hello'
        console.log(a,b,c); //h,e,l

数值和布尔值

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。

let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true

上面代码中,数值和布尔值的包装对象都有toString属性,因此变量s都能取到值。

undefined和null

他们是无法转化为对象的,所以他们是不能进行结构赋值的,会报错

4 对象字面量增强

对象字面量是什么

是对象的一种写法,通常我们创建一个Object类型的实例的方法有两个

(1)实例化构造函数

var person=new Object();
person.name="Mina";
person.age=20;

(2)使用对象字面量的形式

const person = {
  name:'Mina'
  age:20
}

对象字面量有几种简洁表示法:

(1)对象的属性名和变量或者常量一样的时候,可以只写属性名

const name = 'wuva';
const person = {
    neme 
}

(2)对象方法的简介表示,省略冒号和function

const person = {
    speak(){
        console.log('speak')
    }
}

方括号语法增强

方括号语法的用法:

        const prop = 'age';
        const person = {};
        person.prop = 18; //此时属性名是prop
        person[prop] = 18; //会先对方括号中的prop的求值,此时属性名是age
​
        // 方括号语法可以写在对象字面中
        const person2 = {
            [prop] : 16
        };
        console.log(person2); // 会先对方括号中的prop的求值,此时属性名是age {age: 16}

方括号里面可以放什么

(1)${}

(2)值或者表达式

方括号和点语法的区别

点语法是方括号的一种特殊形式,

当属性名是合法字符串的时候,可以使用点语法,其他情况使用方括号语法,因此更推荐使用方括号语法

5 函数参数的默认值

(1) 函数参数默认值的生效条件是不传参或者明确传递undefined作为参数

(2) 默认参数是表达式的时候是惰性求值的

(3)小技巧:函数默认参数的设置从参数列表的右边开始设置

假如从参数列表的左边设置:

        const mul = (x=1,y) => x*y;
        console.log(mul(undefined,2)); //麻烦

6 剩余参数

剩余参数的本质:剩余参数永远都是一个数组,即使没有值,也是一个空数组

注意事项:

(1)箭头函数的参数即使只有一个剩余参数,也不能省略圆括弧

      const add = (...args) => {};

(2)使用剩余参数代替argument获取实际参数

      const add = function () {
        console.log(arguments);
      };
      const add = (...args) => {
        console.log(args);
      };
      add(1, 2);

(3)剩余参数只能是最后一个参数,之后不能再有其他参数,否则会报错

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

7 展开运算符

认识展开运算符

...[2,3,4] => 3,2,1
      // 1.认识展开运算符
      // [3, 1, 2]; ==》怎么找到数组的最大值和最小值
      // Math.min
​
      console.log(Math.min([3, 1, 2])); // math.min不能接收数组,接收的是参数列表的形式,如下面一行
      console.log(Math.min(3, 1, 2));
​
      // [3, 1, 2]->3, 1, 2
​
  // 2.数组展开运算符的基本用法
      console.log(Math.min(...[3, 1, 2]));
      // 相当于
      console.log(Math.min(3, 1, 2));
​

区分剩余参数和展开运算符

根本区别:

剩余参数: 3,2,1 --> [3,2,1]

展开运算符: [3,2,1] -->3,2,1

数组的展开运算符的应用

(1)复制数组(地址不相同)

      // const a = [1, 2];
      // // const b = a;
      // // a[0] = 3;
      // // console.log(b); //这样指向的同一个地址,修改a,b也会变
​
      const c = [...a];
      // const c = [1, 2];
      a[0] = 3;
      console.log(a);
      console.log(c);

(2)合并数组

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

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



(3)字符串/类数组 转为数组,这样就能使用数组的方法了

      //字符串
      console.log([...'alex'])  // ["a","l","e","x"]
      //类数组
     // (1) arguments
      function func() {
        console.log([...arguments]);
      }
      func(1, 2);
      //(2) NodeList
      console.log([...document.querySelectorAll('p')].push);



对象的展开运算符

(1)对象不能直接展开,要在{}中展开,将属性罗列出来放到{}中 构成一个新的对象

      const apple = {
        color: '红色',
        shape: '球形',
        taste: '甜'
      };
      console.log({...apple});  //{color: '红色', shape: '球形', taste: '甜'}
    //   console.log(...apple); //报错
    //   console.log([...apple]); //报错



(2)合并对象,中间用逗号隔开,合并的对象具有所有属性,相同的属性后者覆盖前者

      const apple = {
        color: '红色',
        shape: '球形',
        taste: '甜'
      };
      const pen = {
        color: '黑色',
        shape: '圆柱形',
        use: '写字'
      };
      console.log({ ...apple, ...pen }); //{color: '黑色', shape: '圆柱形', taste: '甜', use: '写字'}



注意事项

(1)如果展开一个空对象,则没有任何效果

(2)展开的不是一个对象的时候,会自动将其转化为对象,再将其属性罗列出来,找不到属性时候就是空对象

(3)展开的是字符串的时候,会自动将字符串转换为一个类数组对象,返回的不是一个空对象

(4)对于对象的展开,不会展开对象中的对象

对象展开运算符的应用

(1)复制对象(地址不同)

      // const a = { x: 1, y: 2 };
      // // const b = a; //这样其实是地址相同

      const c = { ...a }; //正确的复制操作
      // console.log(c, c === a);



(2)默认参数和实际参数

      const logUser = userParam => {
        const defaultParam = {
          username: 'ZhangSan',
          age: 0,
          sex: 'male'
        };

        const param = { ...defaultParam, ...userParam };
        // const param = { ...defaultParam, ...undefined };
        console.log(param.username);
        // const { username, age, sex } = { ...defaultParam, ...userParam };
        // console.log(username, age, sex);
      };
      logUser();



7 Set和Map

Set

认识Set

Set是一个无序且没有重复值的数据结构,Set是没有下标标识每个值的,因此不能像数组一样通过下标值访问Set成员

const s = new Set([1,2,3,3,4])
console.log(s)



小知识点:Set内部NaN被视为相等的元素只会加入一个,但是其实NaN !== NaN, 但是两个空对象视为两个不同的元素

Set的方法和属性

属性:Set.size:返回 Set 实例的成员总数。

操作方法:

  • Set.add(value) :添加某个值,返回 Set 结构本身。
  • Set.delete(value) :删除某个值,返回一个布尔值,表示删除是否成功。
  • Set.has(value) :返回一个布尔值,表示该值是否为 Set 的成员。
  • Set.clear() :清除所有成员,没有返回值。

遍历方法: Set的遍历顺序就是成员的添加顺序

Set 结构的实例有四个遍历方法,可以用于遍历成员。

  • Set.keys() :返回键名的遍历器
  • Set.values() :返回键值的遍历器
  • Set.entries() :返回键值对的遍历器
  • Set.forEach() :使用回调函数遍历每个成员
let s = new Set([1,2,3]);
        s.forEach(function(value,key,set){
            console.log(value); 
            console.log(this); //#document
},document);

 // 该函数的参数与数组的 forEach 一致,依次为键值、键名、集合本身(上例省略了该参数),doucument所在参数位置是修改函数的this指向,不写就是默认window



keys方法、 values方法、 entries方法返回的都是遍历器对象。由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和 values方法的是相等的,都是成员的值。这意味着,可以省略values方法,直接用 for...of 循环遍历 Set

let set = new Set(['red', 'green', 'blue']);
for (let x of set) {
  console.log(x);
}



Set构造函数的参数

1.数组

2.字符串、argument、NodeList、Set等具有 iterable 接口的其他数据结构。

Set的注意事项

1.判断重复的方式

      // Set 对重复值的判断基本遵循严格相等(===)
      // 但是对于 NaN 的判断与 === 不同,Set 中 NaN 等于 NaN
      // 两个空对象是不严格相等的
      const s = new Set([1, 2, 1]); 
      const s = new Set([NaN, 2, NaN,{},{}]); // {NaN,2,{},{}}

      console.log(NaN === NaN); //false NaN其实是不等于NaN的
      console.log({} === {}); //false



  • 什么时候用Set

(1)数组或者字符串去重

(2)只需要遍历,不需要通过下标去访问

(3)为了使用Set的属性和方法时

Set去重(最常用)

1 数组去重

      // 方法1:
        new_s1 = [...new Set(s)];
        //方法2:
        new_s2 = Array.from(new Set(s)) ; //Array.from 方法可以将 Set 结构转为数组
        console.log(new_s2);



2.字符串去重

Set->数组->字符串

        const s = new Set('abbagn');
        console.log([...s].join('')); //abgn



Map

认识Map

map也是一种键值对的数据结构,由于对象的键只能采用字符串,这给他带来了很大的限制,为了能够让各种类型的值都可以当做键,由此提出来Map数据结构。

Map的属性和方法

属性:

Map.size :返回Map结构的成员总数 ,对象没有size属性

操作方法:

(1)Map.set(key,value): 添加新成员,如果key已经存在,后者覆盖前者,set 方法返回的是当前的 Map 对象,因此可以采用链式写法。

let map = new Map()
  .set(1, 'a')
  .set(2, 'b')
  .set(3, 'c');



(2)Map.get(key) :通过键获取某个成员。如果找不到的话,返回undefined

(3)Map.has(key) : 返回一个布尔值,表示某个键是否在当前 Map 对象之中

(4)Map.delete(key): 删除某个键,返回 true 。如果删除失败,返回 false ,不报错

(5)Map.clear(): 一键清除

遍历方法:

  • Map.keys() :返回键名的遍历器。
  • Map.values() :返回键值的遍历器。
  • Map.entries() :返回所有成员的遍历器。
  • Map.forEach() :遍历 Map 的所有成员。
        m.forEach(function(value,key,m){
            console.log(value,key); 
            console.log(this); //doucument
        },document)



Map构造函数的参数

    <script>
      // 1.数组
      // 只能传二维数组,而且必须体现出键和值
      console.log(
        new Map([
          ['name', 'alex'], //第一个键值对
          ['age', 18]
        ])
      );

      // 2.Set、Map 等
      // Set
      // Set 中也必须体现出键和值,一般还是二维数组的形式
      // const s = new Set([
      //   ['name', 'alex'],
      //   ['age', 18]
      // ]);
      // console.log(new Map(s));
      // console.log(s);

      // Map
      // 复制了一个新的 Map
      const m1 = new Map([
        ['name', 'alex'],
        ['age', 18]
      ]);
      console.log(m1);
      const m2 = new Map(m1);
      console.log(m2, m2 === m1); // false
    </script>



Map的注意事项

  1. 判断键名是否相等,遵循严格相等,例外的就是NaN也是等于NaN
  2. 什么时候使用Map:

如果只是需要key->value的结构或者需要字符串以外的值作为键,使用Map更合适,因为Map相对对象具有更多的方法

与其他数据结构的互相转换

(1) Map转数组

const myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
[...myMap]  // [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]



(2) 数组转Map

new Map([[true, 7], [{foo: 3}, ['abc']}])



(3) Map 转为对象

    function mapToObj(m){
        let obj = Object.create(null);
        m.forEach(function(key,value){
            obj[key] = value;

        });
        return obj;
    }

    const myMap = new Map().set('yes', true).set('no', false);
    console.log(mapToObj(myMap)); //{true: 'yes', false: 'no'}



(4)对象转Map,可以通过Object.entries()函数 或者如上写一个转换函数

let obj = {"a":1, "b":2};
let map = new Map(Object.entries(obj));



8 遍历器和For…of…

认识遍历器

1.遍历器(迭代器) Iterator

2.寻找 Iterator

      console.log([1, 2][Symbol.iterator]());
      const it = [1, 2][Symbol.iterator]();
      console.log(it); // Array Iterator {}



3.使用 Iterator

      const it = [1, 2][Symbol.iterator](); //返回一个遍历器的对象
      console.log(it.next()); // {value: 1, done: false}
      console.log(it.next()); // {value: 2, done: false} 此时遍历并没有结束,因为此时done为false,还要接着遍历
      console.log(it.next()); // {value: undefined, done: true} ,此时done为true,遍历完成
      console.log(it.next()); // {value: undefined, done: true}
      
      // it:可遍历对象(可迭代对象)
      // Symbol.iterator:可遍历对象的生成方法



4.什么是 Iterator,主要是下面这个过程被称为iterator

  // 4.什么是 Iterator,主要是下面这个过程被称为iterator
  // Symbol.iterator(可遍历对象的生成方法) -> it(可遍历对象) -> it.next() -> it.next() -> ...(直到 done 为 true)



遍历器的意义

  1. 遍历数组、 Set 、Map等:for of, forEach

遍历对象:for in 循环

例子

     //for...of 循环只会遍历出那些 done 为 false 时,对应的 value 值
      const arr = [1, 2, 3];
      for (const item of arr) {
        console.log(item);
      }
      //for...of的本质
      const it = arr[Symbol.iterator]();
      let next = it.next();
      console.log(next);
      while (!next.done) {
        console.log(next.value);
        next = it.next();
        console.log(next);
      }

      // 2.与 break、continue 一起使用
      const arr = [1, 2, 3];
      for (const item of arr) {
        if (item === 2) {
          // break;
          continue;
        }
        console.log(item);
      }

      // 3.在 for...of 中取得数组的索引
      const arr = [1, 2, 3];

      // keys() 得到的是索引的可遍历对象,可以遍历出索引值
      console.log(arr.keys()); //得到一个可遍历对象
      for (const key of arr.keys()) {
        console.log(key); //0 1 2
      }

      //values() 得到的是值的可遍历对象,可以遍历出值
      for (const value of arr.values()) {
        console.log(value);
      }  //和下面的方法结果一样,这种方式其实没有必要
      for (const value of arr) {
        console.log(value);
      }

      // entries() 得到的是索引+值组成的数组的可遍历对象
      for (const entries of arr.entries()) {
        console.log(entries); // [0,1] [1,2] [2,3]
      }

      // 结合解构赋值,将索引和值结构出来[index,value]
      for (const [index, value] of arr.entries()) {
        console.log(index, value);
      } 
      
//对象的遍历
      let es6 = {
	  	edition: 6,
 	 	committee: "TC39",
 		 standard: "ECMA-262"
		};
		
	  for (let e in es6) {
		  console.log(e);
		}



2.如何更方便的使用 Iterator

 Iterator 遍历器是一个统一的遍历方式,无论是数组还是对象,都可以使用iterator遍历,但是将Symbol.iterator->it->next()这种机制很麻烦,所以我们一般不会直接使用 Iterator 去遍历,通常也不会用,但是我们需要了解iterator的运行机制即可,开发人员利用这套遍历的流程封装好了,即for..of



原生可遍历和非原生可遍历

for ……of……只能循环原生可遍历数据

何为原生可遍历数据:只要有Symblo.iterator()方法且这个方法可以生成可遍历的对象就是原生可遍历

原生可遍历:数组、字符串、类数组、Set、Map

非原生可遍历:

(1) 一般的对象,对象的遍历一般使用 for…in,也可以手动添加 Symbol.iterator 方法变成可遍历对象; (2) 有 length 和索引属性的对象,可以额外添加一个方法,因为比较简单,这里给出一个小例子

 //原生可遍历的例子
 for (const item of [1, 2, 3]) {
    console.log(item);
  }
  for (const item of 'hi') {
    console.log(item);
  }
  for (const item of new Set([1, 2])) {
    console.log(item);
  }
  for (const elem of document.querySelectorAll('p')) {
    console.log(elem);
    elem.style.color = 'red';
  }
  
 // 一般的对象手动添加Symbol.iterator 方法
  const person = { sex: 'male', age: 18 };
  person[Symbol.iterator] = () => {
    let index = 0;
    return {
      next() {
        index++;
        if (index === 1) {
          return {
            value: person.age, //手动可随意指定
            done: false
          };
        } else if (index === 2) {
          return {
            value: person.sex,
            done: false
          };
        } else {
          return {
            done: true
          };
        }


### 最后

如果你已经下定决心要转行做编程行业,在最开始的时候就要对自己的学习有一个基本的规划,还要对这个行业的技术需求有一个基本的了解。有一个已就业为目的的学习目标,然后为之努力,坚持到底。如果你有幸看到这篇文章,希望对你有所帮助,祝你转行成功。

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)**

![](https://img-blog.csdnimg.cn/img_convert/54a6b04f29167333b139d2753f60db9f.png)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值