前端|每天5道面试题(5)

5,032 阅读4分钟

每天背5道,务必背熟记住,希望能对找工作的小前端有点帮助

1、解释一下变量提升

  • 所有的声明都会提升到作用域的最顶上去。

  • 函数声明的优先级高于变量声明的优先级,并且函数声明和函数定义的部分一起被提升。

举例说明一下:

(1)变量提升

    console.log(a);  //undefined
    var a = 123; 

因为变量a的声明被提到了作用域顶端。上面代码编译后应该是下面这个样子

    var a;
    console.log(a)
    a = 123
    //所以输出内容为 undeifend

(2)函数提升

具名函数的声明有两种方式:1. 函数声明式 2. 函数字面量式

//函数声明式
function bar () {}
//变量形式声明; 
var foo = function () {}

函数 变量形式声明 和普通变量一样 提升的 只是一个没有值的变量。

函数声明式的提升现象和变量提升略有不同,函数声明式会提升到作用域最前边,并且将声明内容一起提升到最上边。

看例子:

bar()

var bar = function() {
  console.log(1);
}
// 报错:TypeError: bar is not a function


bar()
function bar() {
  console.log(1);
}
//输出结果1

2、ES6+增加了哪些新特性

  • 声明 let / const

  • 解构赋值

  • class / extend: 类声明与继承

  • Set / Map: 新的数据结构

  • 箭头函数

  • promise

  • async/await

  • 数组的扩展

  • 对象的扩展

3、let和const区别

  • let / const: 块级作用域、不存在变量提升、暂时性死区、不允许重复声明
  • const: 声明常量,无法修改(基本类型不可修改,引用类型如对象和数组,可以修改)

4、async和await的用途?

async函数是generator函数的语法糖 ,async函数始终返回一个Promise,await可以实现一个"等待"的功能,async/await被称为异步编程的终极解决方案,即用同步的形式书写异步代码,并且能够更优雅的实现异步代码顺序执行以及在发生异步的错误时提供更精准的错误信息

5、对promise的理解,手写promise,或者问如何解决回调地狱

 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise提供统一的API,各种异步操作都可以用同样的方法进行处理。

有三个状态:

  1. 等待中(pending)
  2. 完成了(resolved)
  3. 拒绝了(rejected)

Promise缺点:

  • 首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。
  • 其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
  • 第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

解决了什么问题:

Promise 的出现解决了 之前的回调地狱问题,并且Promise 实现了链式调用,也就是说每次调用 then 之后返回的都是一个 Promise , 并且是一个全新的Promise 。是因为Promise 的状态不可变。如果你在then中使用了return ,那么 return 的值会被 Promise .resolve 包装。

手写promise【重点】

//newPromise.js

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class NewPromise {
    constructor(executor) {
        executor(this.resolve,this.reject)
    }
    //promise状态
    status = PENDING
    value = undefined
    reason = undefined
    //值默认没有
    resolve = value => {
        //如果状态不是等待,阻止程序向下执行
        if(this.status !== PENDING)return
        this.status = FULFILLED
        this.value = value
    }
    //使用箭头函数的原因:直接调用一个普通函数,函数里面的this指向是undefined的
    reject = reason => {
        if(this.status !== PENDING)return
        //将状态更改为失败
        this.status = REJECTED
        this.reason = reason
    }
    //判断promise的状态,返回回调函数,需要传递value和reason
    then(successCallback,failCallback){
        //判断状态
        if(this.status === FULFILLED){
            successCallback(this.value)
        }else if(this.status === REJECTED){
            failCallback(this.reason)
        }
    }
}

module.exports = NewPromise

一个名叫“格子啊”的网友写的promise,大家看看有毛病吗

class promise {
  constructor(fn) {
    this.state = 'pending'
    this.resolveCbs = []
    this.rejectCbs = []
    this.resolve = this.resolve.bind(this)
    this.reject = this.reject.bind(this)
    fn(this.resolve, this.reject)
  }

  resolve(data) {
    this.successData = data
    this.state = 'resolve'
    this.resolveCbs.forEach(cb => {
      cb && cb(this.successData)
    })
  }

  reject(data) {
    this.failData = data
    this.state = 'reject'
    this.rejectCbs.forEach(cb => {
      cb && cb(this.failData)
    })
  }

  then(cb) {
    cb && this.resolveCbs.push(cb)
    return this
  }

  catch(cb) {
    cb && this.rejectCbs.push(cb)
    return this
  }
}

本着能为找工作中的前端帮一点小忙的初衷,借鉴了掘金里面很多大佬的文章,如有侵权请告知