title: ES6面试题
date: 2019-10-12 20:23:00
updated: 2019-10-12 20:23:00
tags: ['web前端面试']
ES6面试题
来自面试经历后自我总结和网上各种渠道的收集(侵删)
1. promise相关
Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法
Promise对象有以下两个特点。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
- 状态可能有三种状态:等待(pending)、已完成(fulfilled)、已拒绝(rejected)
- promise
- promise 的状态只可能从“等待”转到“完成”态或者“拒绝”态,不能逆向转换,同时“完成”态和“拒绝”态不能相互转换
- then
- promise 必须实现then方法,而且then必须返回一个 promise ,同一个 promise 的then可以调用多次(链式),并且回调的执行顺序跟它们被定义时的顺序一致
- then方法接受两个参数,第一个参数是成功时的回调,在 promise 由“等待”态转换到“完成”态时调用,另一个是失败时的回调,在 promise 由“等待”态转换到“拒绝”态时调用
-
基本用法
function loadImg(src) { var promise = new Promise(function(resolve, reject) { var img = document.createElement('img') img.onload = function () { resolve(img) } img.onerror = function () { reject('图片加载失败') } img.src = src; }) return promise } var src = 'https://csdnimg.cn/cdn/content-toolbar/csdn-logo_.png?v=20190924.1' var result = loadImg(src) result.then(function(img) { console.log(1, img.height); return img }, function () { console.log(2, '2error'); })
-
如何异常捕获(Error和reject都要考虑)
function loadImg(src) { var promise = new Promise(function(resolve, reject) { var img = document.createElement('img') img.onload = function () { resolve(img) } img.onerror = function () { reject('图片加载失败') } img.src = src; }) return promise } var src = 'https://csdnimg.cn/cdn/content-toolbar/csdn-logo_.png?v=20190924.1' var src = 'https://csdnimg.cn/cdn/content-toolbar/csdn-logo_.png1?v=20190924.1' var result = loadImg(src) result.then(function(img) { console.log(1, img.height); return img }).then(function(img) { console.log(1, img.width); }).catch(function (ex) { console.log('catch:', ex); })
-
多个串联-链式执行好处
// 串联操作 var src1 = 'https://csdnimg.cn/cdn/content-toolbar/csdn-logo_.png?v=20190924.1' var result1 = loadImg(src1) var src2 = 'https://upload.jianshu.io/users/upload_avatars/3680705/53474ecc-5d15-4c80-97cb-558ff676dd52.jpeg?imageMogr2/auto-orient/strip|imageView2/1/w/80/h/80/format/webp' var result2 = loadImg(src2) // 特别注意前一个then的返回值 result1.then(function(img1) { console.log("result1第一个图片加载完毕", img1.width); return result2 }).then(function(img2) { console.log("result2第二个图片加载完毕", img2.width); }).catch(function (ex) { console.log('catch:', ex); })
-
Promise.all 和 Promise.race
all的用法
与then同级的另一个方法,all方法,该方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后并且执行结果都是成功的时候才执行回调。race的用法
all是等所有的异步操作都执行完了再执行then方法,那么race方法就是相反的,谁先执行完成就先执行回调。// Promise.all() 和 Promise.race() var src1 = 'https://csdnimg.cn/cdn/content-toolbar/csdn-logo_.png?v=20190924.1' var result1 = loadImg(src1) var src2 = 'https://upload.jianshu.io/users/upload_avatars/3680705/53474ecc-5d15-4c80-97cb-558ff676dd52.jpeg?imageMogr2/auto-orient/strip|imageView2/1/w/80/h/80/format/webp' var result2 = loadImg(src2) Promise.all([result1, result2]).then(function (datas) { console.log('all', datas[0]) console.log('all', datas[1]) }) Promise.race([result1, result2]).then(function (data) { console.log('race', data) })
- Promise标准-状态变化,then函数
2. async 和 await
-
基本语法
function loadImg(src) { var promise = new Promise(function(resolve, reject) { var img = document.createElement('img') img.onload = function () { resolve(img) } img.onerror = function () { reject('图片加载失败') } img.src = src; }) return promise } // async 和 await var asyncLoad = async function() { var src1 = 'https://csdnimg.cn/cdn/content-toolbar/csdn-logo_.png?v=20190924.1' var src2 = 'https://upload.jianshu.io/users/upload_avatars/3680705/53474ecc-5d15-4c80-97cb-558ff676dd52.jpeg?imageMogr2/auto-orient/strip|imageView2/1/w/80/h/80/format/webp' var result1 = await loadImg(src1) var result2 = await loadImg(src2) }
使用了Promise,并没有和Promise冲突
完全是同步的写法,再也没有回调函数
但是:改变不了js单线程,、异步的本质
3. class用法
// es5
function Animal() {
this.eat = function() {
console.log('animal eat')
}
}
function Dog() {
this.bark = function() {
console.log('dog bark')
}
}
Dog.prototype = new Animal()
// 哈士奇
var hashiqi = new Dog();
// ES6的写法
class Animal {
eat () {
console.log('animal eat')
}
}
class Dog extends Animal {
bark () {
console.log('dog bark')
}
}
var hashiqi = new Dog();
4. ES6中Class 与 普通构造函数有何区别
- class本质上是构造函数的语法糖;
- class在语法上更贴近面向对象的写法;
- class实现继承更加易读易理解;
5. ES6中var/let/const的区别
- let
let声明只在他所在的代码域中有效
let 不存在变量提升,变量需要先声明然后再使用,否则报错
-
暂时性死区
块级作用域内存在let命令,它所声明的变量就绑定在这个区域,不再受外部影响;如下代码:var tmp = 123; if (true) { tmp = 'abc'; let tmp; console.log(tmp); // tmp is not defined }
let 不允许重复声明
不允许在相同作用域内,重复声明同一个变量。
- const
- const 声明一个只读的常量,一旦声明,常量的值就不允许改变。
- const的作用域与let命令相同;只在声明所在的块级作用域内有效。
5. const定义的对象属性是否可以改变
const 指针指向的地址不可以变化,指向地址的内容可以变化。
6. 箭头函数
https://www.jianshu.com/p/c1ee12a328d2
7. ES6新特性
- 不一样的变量声明:const和let
- 模板字符串
- 箭头函数(Arrow Functions)
- 函数的参数默认值
- 对象和数组解构
- Promise
8. map与filter
https://www.cnblogs.com/BillyYoung/p/11323459.html
两个都是用来遍历数组且都有返回值
- map
let arr1 = [1,2,3];
let arr2 = arr1.map((value,key,arr) => {
console.log(value) // 1,2,3
console.log(key) // 0,1,2
console.log(arr) //[1,2,3] [1,2,3] [1,2,3]
return value * value;
})
console.log(arr1); // [ 1, 2, 3 ]
console.log(arr2); // [ 1, 4, 9 ]
- filter
过滤函数,返回符合条件的元素数组。返回值是个布尔值
let arr1 = [1,2,3];
let arr2 = arr1.filter((value,key,arr) => {
console.log(value) // 1,2,3
console.log(key) // 0,1,2
console.log(arr) // [1,2,3]
return value >= 3 ? false : true; //内部走的就是value>=3 成立吗,成立的部分返回,不成立的部分不返回。
})
console.log(arr1); // [ 1, 2, 3 ]
console.log(arr2); // [ 1, 2 ]
数组去重
let arr5 = [1, 2, 2, 3, 4, 5, 5, 6];
let newArr4 = arr5.filter((x, index, self) => {
return self.indexOf(x) === index
})
console.log(newArr4) //[1,2,3,4,5,6]