面试时面试官想要听到什么答案(关于es6中let、const、promise、块级作用域的问题)

es6有哪些属性

问题

常用的es6语法有哪些

问题描述

作为es6问题的开始的一个问题,想通过这个问题知道对方写代码时是否在用es6,是否知道自己用的是es6。但是大部分都说不上来几个(其实突然问我,我也不一定能说很多,当然面试多了之后就可以随口就来),所以我都怀疑这个问题有没有问的必要,对方这个问题其实回答的多少我后面还是该怎么问还是怎么问,也并不影响此次面试。

期望答案

  1. let、const
  2. 解构赋值
  3. 末班字符串
  4. 箭头函数
  5. 函数默认值
  6. promise
  7. set、map结构
  8. class类
  9. symbol
  10. Iterator 和 for...of 循环.
  11. 数值的扩展方法
  12. 数组的扩展方法
  13. 正则的扩展方法
  14. 对象的扩展方法
  15. 。。。。。。 以上为一些常用到的,还有一些不常用的就不一一列举了

var、let、const

问题

说下var、let、const的区别

问题描述

一个非常基础的问题,基本都是回答的差不多,不过有时候会说var和let的区别为一个没有作用域一个有作用域,显然这是一个误区。const是常量这个都知道,但是他可变的情况就很少有人清楚,阮一峰的《ECMAScript 6 入门》有详细的说明。

期望答案

  1. let、const不存在变量提升,var存在变量提升
  2. let、const不能重复声明,var可以重复声明
  3. let、const有块级作用域,var没有块级作用域

补充:

  1. 块级作用域为 {} 只要被包裹在在{}中都是一个块级作用域,比如:if、for、function、或者是直接只写一个{}

  2. const声明一个只读的常量。一旦声明,常量的值就不能改变。

    本质: const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

    所以const声明的对象、数组在对内部进行操作时是并不会报错的,即const声明的可变情况。

块级作用域和函数声明

问题

块级作用域对函数声明有什么影响或改变

问题描述

这个问题我并没有在面试中问过,因为这个问题其实很抽象而且很难去说明,而且这个环境问题就很难去模拟,下面是我在查阅了一些文档和书之后的一些理解,如果有问题,敬请斧正。

阮一峰的《ECMAScript 6 入门》中let、const中有一节是对这一块的描述。

期望答案

ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。但是,浏览器没有遵守这个规定,为了兼容以前的旧代码,还是支持在块级作用域之中声明函数,不会报错。

ES5环境下可以实现下面代码

demo()  // 打印 bbb

var flag = true
if (flag) {
    function demo() {
        console.log('aaa')
    }
} else {
    function demo() {
        console.log('bbb')
    }
}
复制代码

执行此代码时,会先将函数声明提升到顶部而并不会根据判断在下面进行声明,打印bbb是因为第一个声明被第二个声明覆盖了(《你不知道的javaScript》第一部分第四章第三节),实际为下面代码:

function demo() {
    console.log('aaa')
}
function demo() {
    console.log('bbb')
}
var flag
demo()  // 打印 bbb
flag = true
if (flag) {
    
} else {
    
}
复制代码

ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。

如果改变了块级作用域内声明的函数的处理规则,显然会对老代码产生很大影响。为了减轻因此产生的不兼容问题,ES6 在附录 B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。

  1. 允许在块级作用域内声明函数。
  2. 函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
  3. 同时,函数声明还会提升到所在的块级作用域的头部。

注意,上面三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作let处理。

上面代码的执行顺序会变为

var flag
var demo
demo()  // demo is not a function

flag = true
if (flag) {
    function demo() {
        console.log('aaa')
    }
} else {
    function demo() {
        console.log('bbb')
    }
}
复制代码

promise

问题

一般情况这个问题我会给面试者出一个代码题

console.log(1)
let promise = new Promise((resolve, reject) => {
    console.log(2)
    resolve()
    console.log(3)
})
setTimeout(() => {
    console.log(4)
}, 0);
console.log(5)
promise.then(() => {
    console.log(6)
})
console.log(7)
复制代码

问题描述

正确执行顺序我会放在期望答案的最后,防止在看题时看到结果。

这个问题主要问的是两个关键点:1. promise在构造时内部就已经执行结束。2. promise.then和setTimeout的执行顺序

期望答案

关键点1:在Promise对象new的时候,Promise内部resolve前后就都执行了,resolve只与then有关(resolve调用时的参数为then的参数),并不会阻止后面代码的执行。

关键点2:promise.then的执行时间会早于setTimeout,promise和setTimeout都可以处理异步问题,promise为微任务setTimeout为宏任务,promise.then会在本次任务的最后的去调用,而setTimeout会开启一个新的任务去执行其内部的内容,即下一次任务的开始。所以6比4先打印。

问题执行结果:1 2 3 5 7 6 4

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页