阅读 150

2021常见的最新大厂面试题总结(js基础篇1)

这是我参与更文挑战的第4天,活动详情查看: 更文挑战

['1', '2', '3'].map(parseInt) what & why ?

第一眼看到这个题目的时候,脑海跳出的答案是 [1, 2, 3],但是真正的答案是[1, NaN, NaN]。 首先让我们回顾一下,map 函数的第一个参数 callback。这个 callback 一共可以 接收三个参数,其中第一个参数代表当前被处理的元素,而第二个参数代表该 元素的索引。 arr.map(callback: (value: T, index: number, array: T[]) => U, thisArg?: any); 而 parseInt 则是用来解析字符串的,使字符串成为指定基数的整数。接收两个 参数,第一个表示被处理的值(字符串),第二个表示为解析时的基数。 parseInt(string, radix)按照 10了解这两个函数后,我们可以模拟一下运行情况 parseInt('1', 0)按照10为基数处理。这个时候返回1, parseInt("2", 1) ,基数为1 (1进制),表示的数中,最大值小于2,所以无法解析,返回NaN,parseInt("3", 2),基数为2(2进制)表示的数中,最大值小于3,所以无法解析,返回NaN。

setTimeout、Promise、Async/Await 的区别

blog.csdn.net/yun_hou/art…

异步笔试题请写出下面代码的运行结果

// 执行顺序 ,自己运行看看,相关知识点,event loop
async function async1() {
  console.log('async1 start');
  await async2();
  console.log('async1 end');
}
async function async2() {
  console.log('async2');
}
console.log('script start');
setTimeout(function () {
  console.log('setTimeout');
}, 0);
async1();
new Promise(function (resolve) {
  console.log('promise1');
  resolve();
}).then(function () {
  console.log('promise2');
});
console.log('script end');

复制代码

去重扁平化排序

已知如下数组,编写一个程序将数组扁平化去并除其中重复部分数据,最终得 到一个升序且不重复的数组 var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; 答:使用 Set 方法去重,flat(Infinity)扁平化

Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b})
//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
复制代码

JS 异步解决方案的发展历程以及优缺点。

1、回调函数(callback)

优点:解决了同步的问题(只要有一个任务耗时很长,后面的任务都必须排队 等着,会拖延整个程序的执行。) 缺点:回调地狱,不能用 try catch 捕获错误,不能 return

2、Promise

优点:解决了回调地狱的问题

缺点:无法取消 Promise ,错误需要通过回调函数来捕获 3、Generator

特点:可以控制函数的执行,可以配合 co 函数库使用

4、Async/await

优点:代码清晰,不用像 Promise 写一大堆 then 链,处理了回调地狱的问题 缺点:await 将异步代码改造成同步代码,如果多个异步操作没有依赖性而使 用 await 会导致性能上的降低。

实现一个 sleep 函数

比如 sleep(1000) 意味着等待 1000 毫秒,可从 Promise、Generator、Async/Await 等角度实现

const sleep(time) => {
   return new Promise(resolve => setTimeout(resolve, time));
}
sleep(1000).then(() => {})
复制代码

call 和 apply 的区别是什么,哪个性能更好一些

  1. Function.prototype.apply 和 Function.prototype.call 的作用是一样的,区 别在于传入参数的不同;
  2. 第一个参数都是,指定函数体内 this 的指向;
  3. 第二个参数开始不同,apply 是传入带下标的集合,数组或者类数组, apply 把它传给函数作为参数,call 从第二个开始传入的参数是不固定的,都会 传给函数作为参数。
  4. call 比 apply 的性能要好,平常可以多用 call, call 传入参数的格式正是内 部所需要的格式

实现 (5).add(3).minus(2) 功能

5+3-2,结果为 6

Number.prototype.add = function (n) {
    return this.valueOf() + n;
};
Number.prototype.minus = function(n) {
    return this.valueOf() - n;
}
复制代码

箭头函数与普通函数(function)的区别是什么?构 造函数(function)可以使用 new 生成实例,那么箭头函数可 以吗?为什么?

箭头函数是普通函数的简写,可以更优雅的定义一个函数,和普通函数相比,有以下几点差异:

  1. 函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象
  2. 不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 rest参数代替。
  3. 不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数。不可以使用 new 命令,因为:
  4. 没有自己的 this,无法调用 call,apply。
  5. 没有 prototype 属性 ,而 new 命令在执行时需要将构造函数的prototype 赋值给新的对象的 proto

a.b.c.d 和 a['b']['c']['d'],哪个性能更高?

应该是 a.b.c.d 比 a['b']['c']['d'] 性能高点,后者还要考虑 [ ] 中是变量的情况, 再者,从两种形式的结构来看,显然编译器解析前者要比后者容易些,自然也 就快一点。

为什么普通 for 循环的性能远远高于 forEach 的 性能,请解释其中的原因。

  • for 循环没有任何额外的函数调用栈和上下文;
  • forEach 函数签名实际上是
array.forEach(function(currentValue, index, arr), thisValue)
复制代码

它不是普通的 for 循环的语法糖,还有诸多参数和上下文需要在执行的时候考 虑进来,这里可能拖慢性能;

介绍下 Promise.all 使用、原理实现及错误处理

const p = Promise.all([p1, p2, p3]);
复制代码

Promise.all 方法接受一个数组作为参数,p1、p2、p3 都是 Promise 实例,如果 不是,就会先调用下面讲到的 Promise.resolve 方法,将参数转为 Promise 实例, 再进一步处理。(Promise.all方法的参数可以不是数组,但必须具有 Iterator 接 口,且返回的每个成员都是 Promise 实例。)

文章分类
前端
文章标签