ES6面试篇

ES6新增

  • let、const、块级作用域、箭头函数、模板字符串、BigInt,Symbol数据类型
  • 解构赋值(数组、对象)
  • 字符串新增方法
  • 数组新增方法(扩展运算符)
  • 对象新增方法
  • 新的数据结构Set 和 Map
  • Proxy
  • Promise
  • async和await

let、const、块级作用域

  1. let声明的变量没有变量提升,必须先声明后使用;

  2. 暂时性死区。let声明的变量只能在当前块级作用域内使用

  3. let不允许在同一作用域重复声明同一个变量;

  4. const声明常量,声明就必须赋值,切不能修改;

  5. 块级作用域内可以声明函数,但是类似var会将函数声明提升到块级作用域的头部;

  6. JavaScript 大于16 位的整数是无法精确表示的,不适合进行科学和金融方面的精确计算。二是大于或等于2的1024次方的数值,JavaScript 无法表示,会返回Infinity

    BigInt(123) // 123n  //后边加n
    
  7. Symbol一种新的原始数据类型,表示独一无二的值。可用于对象的属性,防止属性名的冲突

    let s = Symbol();
    typeof s // "symbol"
    let a = {
          
          
      [s]: 'Hello!'
    };
    

箭头函数

(argument1, argument2, … argumentN) => {
    
    
// function body
}
括号内的是参数列表,后跟“胖箭头”(=>),最后是函数体。
  1. 非常简洁的语法,省略 function 关键字;

    如果函数体是单个表达式,则可以不使用花括号并将其置于内联中(省略大括号直接将表达式写在一行中)。 表达式的结果将由函数返回。 
    const add = (a, b) => a + b;
    
    如果只有一个参数,你甚至可以省略参数的括号
    const getFirst = array => array[0];
    
  2. this指向的是定义时所在的对象(跟着爹走);Call,apply,bind不能够改变箭头函数的this指向;

  3. 箭头函数中没有prototype原型

  4. 箭头函数没有constrcutor没有构造器

  5. 不能够使用new进行实例化

  6. 箭头函数中不能够使用arguments对象,用剩余参数来代替;

使用场景

  • 数组的循环,不改变this的指向;
  • promise的then方法传入成功的回调
  • vuex中mapState引入state中一些data

不适用场景:

  1. 定义对象方法
对象的方法中this指向调用这个方法的对象
let obj = {
    
    
	a:1,
	b(){
    
     console.log(this.a) }
}
obj.b()  //1  this指向obj,所以可以获取到对象的属性a

若b换成箭头函数,则this就指向window,获取不到对象的属性
  1. 定义原型方法 :使用构造函数,this也是指向window
  2. 定义构造函数

定义构造函数是不允许使用箭头函数的,系统会抛出异常

  1. 定义事件回调函数。

    绑定点击事件回调中this也是指向window

解构赋值(数组、对象)

let [a, b, c] = [1, 2, 3]; //数组的结构
let [foo = true] = [];  //设置默认值
let {
    
     foo, bar } = {
    
     foo: 'aaa', bar: 'bbb' }; 
let {
    
     foo: baz } = {
    
     foo: 'aaa', bar: 'bbb' }; //别名

字符串新增方法

  1. for … of… 循环

  2. 模板字符串 ${变量}

  3. //第二个参数,表示开始搜索的位置(位置就是索引)
    let s = 'Hello world!';
    
    s.startsWith('world', 6) // true  startWith从第n个位置开始直到结束
    s.endsWith('Hello', 5) // true    endsWith针对前n个字符
    s.includes('Hello', 6) // false   includes从第n个位置开始直到结束
    
    'hello'.repeat(2) // "hellohello"  //字符串重复n次,n=0则为空字符串
    
    'x'.padStart(4, 'ab') // 'abax'
    'x'.padEnd(5, 'ab') // 'xabab'
    
    const s = '  abc  ';
    s.trim() // "abc"          消除前后空格
    s.trimStart() // "abc  "   消除前空格
    s.trimEnd() // "  abc"	   消除后空格
    
    'aabbcc'.replaceAll('b', '_') 2021年参数可以为字符串,也可以全局正则(/b/g)
    

    数组新增方法(扩展运算符)

    1. 扩展运算符:将数组转为参数序列

      console.log(...[1, 2, 3])// 1 2 3 可用于合并数组
      
    2. Array.from()将类似数组的对象转为数组

      Array.of()方法用于将一组值,转换为数组

      let arrayLike = {
              
              
          '0': 'a',
          '1': 'b',
          '2': 'c',
          length: 3
      };
      let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
      Array.of(3, 11, 8) // [3,11,8]
      
    3. 数组实例的 find() 和 findIndex()

      [1, 4, -5, 10].find((n) => n < 0) // -5 第一个符合条件的数组成员
      [1, 4, -5, 10].findIndex((n) => n < 0) // 2 第一个符合条件的数组成员的索引
      
    4. includes()

对象的新增方法

  1. Object.is() 比较两个值是否严格相等

    +0 === -0 //true
    NaN === NaN // false
    
    Object.is(+0, -0) // false
    Object.is(NaN, NaN) // true
    
  2. Object.assign() 对象的合并

  3. Object.setPrototypeOf(object, prototype)和Object.getPrototypeOf() 读取或设置当前对象的原型对象

    let a = {
          
          x:1}
    Object.setPrototypeOf(a, {
          
          y:2})
    console.log(a.y)   //2
    Object.getPrototypeOf(a)  //{y: 2}
    
  4. Object.keys(),Object.values(),Object.entries(),Object.fromEntries()

    var obj = {
          
           foo: 'bar', baz: 42 };
    Object.keys(obj)    // ["foo", "baz"]
    Object.values(obj)  // ["bar", 42]
    Object.entries(obj) // [ ["foo", "bar"], ["baz", 42] ]
    Object.fromEntries([ ['foo', 'bar'], ['baz', 42]]) // { foo: "bar", baz: 42 }
    

新的数据结构Set 和 Map

  1. Set类似于数组,但是成员的值都是唯一的,没有重复的值。

  2. Set的属性size(长度);

  3. Size的方法:add()、delete()、has()、clear()

    // 数组去重
    [...new Set(array)]
    
    let s = new Set([1,2]); //let s = new Set()
    s.add(3)    //Set(3) {1, 2, 3}
    Array.from(s) //[1,2,3] 转换为数组
    s.delete(1) //true 删除成功
    s.has(1)    //false
    s.clear()   //全部清空 Set(0) {}
    s.size      //0
    
  4. Map 数据结构。它类似于对象,也是键值对的集合

    const map = new Map([
      ['name', '张三'],
      ['title', 'Author']
    ]);     //Map(2) {"name" => "张三", "title" => "Author"}
    //原型方法
    map.size // 2
    map.has('name')    // true是否有属性
    map.get('name')    // "张三" 读取属性
    map.set("age", 18) //设置属性
    map.delete('name') //删除属性
    map.clear()        //清除所有属性
    
    [...map.keys()]    //["name", "title", "age"]
    [...map.values()]  // ["组件", "Author", 18]
    [...map.entries()] //[["name", "组件"],["title", "Author"]]
    
  5. Set和Map都可以使用for…of循环

Proxy

  1. 在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写

    var proxy = new Proxy(target, handler);
    //参数:目标对象和处理器handler
    var proxy = new Proxy({
          
          }, {
          
          
      get: function(target, propKey) {
          
          
        return 35;
      }
    });
    let obj = Object.create(proxy);
    obj.time // 35
    
  2. 处理器拦截操作有:13种

    • get(target, propKey, receiver) 拦截对象属性的读取,比如proxy.foo
    • set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = v
    • has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值
    • deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值

promise

  1. Promise 是异步编程的一种解决方案。回调地狱:异步请求套异步请求,所以可以使用promise

  2. 异步:定时器、ajax、事件处理(点击事件等)、nodejs读取文件

  3. Promise对象有以下两个特点

    • Promise的三个状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)

    • 状态不受外界影响,只取决于异步操作的结果。

    • 一旦状态改变,就不会再变,任何时候都可以得到这个结果,从pending变为fulfilled和从pending变为rejected

  4. Promise原型对象的方法(实例也可以调用):then() 、catch()、finally()

  5. Promise的Api:

    • Promise.all([p1,p2,p3],()=>{ }) //全部成功才成功,有一个失败就失败
    • Promise.race([p1,p2,p3],()=>{}) //只要一个执行完成即可执行回调,最先执行完的状态
    • Promise.allSettled() 所有执行完,状态只会是失败
    • Promise.any() 只要一个成功就成功
    • Promise.resolve() 将现有对象转为 Promise 对象
    • Promise.reject(reason) 返回一个新的 Promise 实例,该实例的状态为rejected
    • Promise.try() 和Promise.catch()不管是否包含异步操作,都用then方法指定下一步流程,用catch方法处理f抛出的错误。Promise.try就是模拟try代码块,就像promise.catch模拟的是catch代码块。捕获所有同步和异步的错误。
    //axios就是将ajax使用promise封装的
    function axios(){
          
          
      	p = new Promise((resolve,reject)=>{
          
          
            $.ajax({
          
          
                url:'',
                success(){
          
          
                    resolve(1)
                },
                fail(){
          
          
                    reject(2)
                }
            })
        })
    	return p
    }
    axios().then((data)=>{
          
          
    	console.log(data)  //1
    }).catch(data=>{
          
          
    	console.log(data)   //2
    })
    //若使用async和await
    async fn()=>{
          
          
    	let data = await axios()
    	console.log(data)
    }
    

    async和await

    async和await将异步方法定义为同步,原理就是generate+yield(暂停),执行next()得到暂停的值的语法糖;

Generator

  1. Generator 函数是 ES6 提供的一种异步编程解决方案。
  2. Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态
  3. Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行
  4. 每次调用遍历器对象的next方法,就会返回一个有着valuedone两个属性的对象。value属性表示当前的内部状态的值,是yield表达式后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束

class

构造函数的定义和调用

// function Person (){
    
    
    //   this.name='建林'
    //   this.age=18
    //   this.say=function(){
    
    
    //     console.log('say方法')
    //   }
    // }
    
    new一个构造函数的实例即可调用属性和方法

   //class的定义和使用
    class Person {
    
    
        constructor(){
    
      //里边方属性
           this.name='建林'
           this.age=18
        }

        say() {
    
    
          console.log('say方法')
        }
    }

    class Teacher extends Person {
    
     //extends继承父类的属性和方法
    	//复杂写法
        constructor(){
    
    
            super();// 继承必须写super 他就是父类 上面的那个 constructor
            this.score = 100
            this.name='思聪'
        }
        //简单写法,不需要this
         score = 100
         name='思聪'

        eat(){
    
    
          console.log('eat')
        }

    }
	//调用
    let t1=new Teacher()
    console.log(t1.name) //思聪

遍历器(Iterator)

遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。

Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费。

Iterator 的遍历过程是这样的。

(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。

(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。

(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。

(4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。

每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含valuedone两个属性的对象。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。

下面是一个模拟next方法返回值的例子。

var it = makeIterator(['a', 'b']);

it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next() // { value: undefined, done: true }

function makeIterator(array) {
    
    
  var nextIndex = 0;
  return {
    
    
    next: function() {
    
    
      return nextIndex < array.length ?
        {
    
    value: array[nextIndex++], done: false} :
        {
    
    value: undefined, done: true};
    }
  };
}

TypeScript

JavaScript的超集,有更严格的类型要求

let num:number = 99
function add(x:number,y:number):number{
    
    
	return x+y  //参数x和y都必须是number类型,且返回值也是number类型
}

ES6装饰器decorator

  • 装饰器是一个函数,修饰类class

  • 在类或类的属性方法名之前写@函数名,实现一些代码的复用

    //装饰器是一个函数,给类或其方法加上一些其他的属性或者其他逻辑
    function test(target){
    	target.name = '张三'
    	console.log(‘类调用了’)
    }
    

猜你喜欢

转载自blog.csdn.net/weixin_43848576/article/details/115675020