需求已改活已加,加班通宵看朝霞。终是上线已延期,bug还是改不完。

面试造火箭,工作拧螺丝,虽然我只想拧螺丝,可是我需要用造火箭的技术去寻找拧螺丝的工作,如何能在面试过程中让自己处于不败的地步呢,刷题是一个比较好的捷径,今天就汇总了一些比较经典的面试题,分享给大家。

题目一

题目介绍

如下为一段代码,请完善sum函数,使得 sum(1,2,3,4,5,6) 函数返回值为 21 ,需要在 sum 函数中调用 asyncAdd 函数,且不能修改asyncAdd函数

/** * 请在 sum函数中调用此函数,完成数值计算 * @param {*} a 要相加的第一个值 * @param {*} b 要相加的第二个值 * @param {*} callback 相加之后的回调函数 */function asyncAdd(a,b,callback) {  setTimeout(function(){   callback(null, a+b)  },100)}

/** * 请在此方法中调用asyncAdd方法,完成数值计算 * @param  {...any} rest 传入的参数 */async function sum(...rest) {// 请在此处完善代码}

let start = window.performance.now()sum(1, 2, 3, 4, 5, 6).then(res => {// 请保证在调用sum方法之后,返回结果21console.log(res)console.log(`程序执行共耗时: ${window.performance.now() - start}`)})

本题根据程序输出时间不同,可以划分为三个难度等级

  1. 青铜难度, 输出时长大于6秒
  2. 白银难度, 输出时长大于3秒
  3. 王者难度, 输出时长大于1秒

答案

  1. 青铜难度
async function sum(...rest) {// 取出来第一个作为初始值let result = rest.shift()// 通过for of 遍历 rest, 依次相加for(let num of rest) {// 使用promise 获取相加结果    result = await new Promise(resolve => {      asyncAdd(result, num, (_,res) => {        resolve(res)      })    })  }// 返回执行结果return result}

// 执行成功,执行时长大于6秒sum1(1, 2, 3, 4, 5,6).then(res => {console.log(`计算结果为:${res}`)})

  1. 白银难度

在青铜难度,我们把数组里面的每一项依次相加。但是也可以进行一些优化,可以并发执行多个,比如 sum(1,2,3,4,5,6),可以同时执行 1+2,3+4,5+6,这样就可以提升执行效率

async function sum(...rest) {// 如果传的值少于2个,则直接返回if (rest.length <= 1) {return rest[0] || 0  }const promises = []// 遍历将数组里面的值两个两个的执行for (let i = 0; i < rest.length; i += 2) {    promises.push(new Promise(resolve => {// 如果 rest[i+1] 是 undefined, 说明数组长度是奇数,这个是最后一个if (rest[i + 1] === undefined) {          resolve(rest[i])        } else {// 调用asyncAdd 进行计算          asyncAdd(rest[i], rest[i + 1], (_, result) => {            resolve(result)          })        }      })    )  }// 获取第一次计算结果const result = await Promise.all(promises)// 然后将第一次获取到的结果即 [3,7,11] 再次调用 sum执行return await sum(...result)}

// 执行成功,执行时长大于3秒小于4秒sum1(1, 2, 3, 4, 5,6).then(res => {console.log(`计算结果为:${res}`)})
  1. 王者难度
async function sum(...rest) {let result = 0// 隐氏类型转换, 对象 + 数字,会先调用对象的toString 方法const obj = {}  obj.toString = function() {return result  }const promises = []for(let num of rest) {    promises.push(new Promise((resolve) => {      asyncAdd(obj, num, (_, res) => {        resolve(res)      })    }).then(res => {// 在这里将 result的值改变之后,obj.toString 的返回值就变了,这时候下一个setTimeout调用时就使用了新值      result = res    }))  }await Promise.all(promises)return result}

// 执行成功,执行时长大于1秒小于2秒sum1(1, 2, 3, 4, 5,6).then(res => {console.log(`计算结果为:${res}`)})

因为js是执行在单线程里面的,所以上面的代码,我们在for of将所有的计算放到promises数组里面,然后通过Promise.all去一次性执行,这时候并不需要考虑到底先执行哪两个数字相加。因为单线程的原因,我们可以保证这几个Promise是依次执行的,这时候obj.toString返回值就是上一个Promise的返回值,多跑几遍代码你就懂了哦

题目二

题目介绍

请说明以下代码各输出了什么?

console.log(typeof (() => {}))

console.log(typeof ['前端有的玩','公众号'])

console.log(typeof null)

console.log(typeof undefined)

console.log(typeof Function.prototype)

console.log('子君' instanceof String)

console.log(new Date() instanceof Date)

答案

// 输出 functionconsole.log(typeof (() => {}))

// 输出 objectconsole.log(typeof ['前端有的玩','公众号'])

// 输出 objectconsole.log(typeof null)

// 输出 undefinedconsole.log(typeof undefined)

// 输出 functionconsole.log(typeof Function.prototype)

// 输出 falseconsole.log('子君' instanceof String)

// 输出 trueconsole.log(new Date() instanceof Date)

需要注意的是,对于 typeof, 可以正确判断除了null之外的所有基本类型,而对于引用类型,除了函数外其他都会被判断为object

对于instanceof,无法判断基本类型,但可以正确判断引用类型

题目三

题目介绍

请实现一个instanceof,让以下代码可正常运行

/** 自定义instanceof*/function instanceOf(left, right) {// 请完善以下代码,不能使用原生instanceof}

class A{}class B extends A {}class C{}

const b = new B()// 输出 trueconsole.log(instanceOf(b,B))// 输出 trueconsole.log(instanceOf(b,A))// 输出 falseconsole.log(instanceOf(b,C))

答案

本题主要考察instanceof的判断原理,instanceof主要的实现原理就是只要右边变量的 prototype 在左边变量的原型链上即可。因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false

/**  自定义instanceof*/function instanceOf(left, right) {let proto = left.__proto__while(proto){if(proto === right.prototype){return true    }    proto = proto.__proto__  }return false}

class A{}class B extends A {}class C{}

const b = new B()// 输出 trueconsole.log(instanceOf(b,B))// 输出 trueconsole.log(instanceOf(b,A))// 输出 falseconsole.log(instanceOf(b,C))

题目四

题目介绍

请模拟实现new操作符,使下面代码正常运行

function myNew(constructor, ...rest) {// 请在此处完善代码,不能直接使用 new 操作符}function Fun(name,sex) {this.name = namethis.sex = sex}Fun.prototype.getUserInfo = function() {return `我的姓名${this.name},我的性别${this.sex}`}

const fun = myNew(Fun,'子君','男')// 我的姓名子君,我的性别男console.log(fun.getUserInfo())

答案

这道题考察的是使用new操作符调用构造函数所经历的阶段:

  1. 创建一个新的对象;
  2. 将构造函数的作用域赋给新的对象;
  3. 执行构造函数中的代码;
  4. 返回新的对象;
function myNew(constructor, ...rest) {if (typeof constructor !== 'function') {return constructor;    }    //创建新的对象,关联构造函数的原型对象    const _constructor = Object.create(constructor.prototype);    //执行构造函数    const obj = constructor.apply(_constructor, rest);    //如果构造函数执行结果是对象则返回执行结果    if (typeof obj === 'object') {return obj;    } else {return _constructor;    }}function Fun(name,sex) {this.name = namethis.sex = sex}Fun.prototype.getUserInfo = function() {return `我的姓名${this.name},我的性别${this.sex}`}

const fun = myNew(Fun,'子君','男')// 我的姓名子君,我的性别男console.log(fun.getUserInfo())

题目五

题目介绍

请说出以下代码输出内容

const a = {}const b = Symbol('1')const c = Symbol('1')a[b] = '子君'a[c] = '君子'

// 我是子君还是君子呢console.log(a[b])

const d = {}const e = {key: '1'}const f = {key: '2'}d[e] = '子君'd[f] = '君子'

// 我是子君还是君子呢console.log(d[e])

答案

const a = {}const b = Symbol('1')const c = Symbol('1')a[b] = '子君'a[c] = '君子'

// 输出子君console.log(a[b])

const d = {}const e = {key: '1'}const f = {key: '2'}d[e] = '子君'd[f] = '君子'

// 输出君子console.log(d[e])

对于第一个输出,Symbol()函数会返回**「symbol」**类型的值,而Symbol函数传的参数仅仅是用于标识的,不会影响值的唯一性

对于第二个输出, 因为ef都是对象,而对象的key只能是数值或字符,所以会将对象转换为字符,对象的toString方法返回的是[object Object], 所有输出的是君子

题目六

题目介绍

请说出以下代码输出的内容

console.log([] + [])console.log({} + [])console.log([] == ![])console.log(true + false)

答案

  1. 第一行代码
// 输出 "" 空字符串console.log([] + [])

这行代码输出的是空字符串"", 包装类型在运算的时候,会先调用valueOf方法,如果valueOf返回的还是包装类型,那么再调用toString方法

// 还是 数组const val = [].valueOf()// 数组 toString 默认会将数组各项使用逗号 "," 隔开, 比如 [1,2,3].toSting 变成了"1,2,3",空数组 toString 就是空字符串const val1 = val.toString() // val1 是空字符串

所以上面的代码相当于

console.log("" + "")
  1. 第二行代码

    // 输出 "[object Object]"console.log({} + [])

    和第一题道理一样,对象 {}隐氏转换成了[object Object],然后与""相加

  2. 第三行代码

    // 输出 trueconsole.log([] == ![])

    对于===, 会严格比较两者的值,但是对于==就不一样了

    所以对于上面的代码,看下面一步一步分析

    // 这个输出 falseconsole.log(![])// 套用上面第三条 将 false 转换为 数值// 这个输出 0console.log(Number(false))// 包装类型与 基本类型 == 先将包装类型通过 valueOf toString 转换为基本类型// 输出 ""console.log([].toString())// 套用第2条, 将空字符串转换为数值、// 输出 0console.log(Number(""))// 所以console.log(0 == 0)
    1. 比如 null == undefined
    2. 如果非numbernumber比较,会将其转换为number
    3. 如果比较的双方中由一方是boolean,那么会先将boolean转换为number
  3. 第四行代码

    // 输出 1console.log(true + false)

    两个基本类型相加,如果其中一方是字符,则将其他的转换为字符相加,否则将类型转换为Number,然后相加, Number(true)1, Number(false)0, 所以结果是 1


好书尝鲜

《前端程序员面试笔试通关宝典》

8月中旬上市!

后台回复“面试”,获取试读样章!

前端面试instanceof_面试造火箭,看下这些大厂原题相关推荐

  1. 面试造火箭,工作拧螺丝?看下这些大厂原题吧(iOS开发方向)

    需求已改活已加,加班通宵看朝霞.终是上线已延期,bug还是改不完. 面试造火箭,工作拧螺丝,虽然我只想拧螺丝,可是我需要用造火箭的技术去寻找拧螺丝的工作,如何能在面试过程中让自己处于不败的地步呢,刷题 ...

  2. 扎牢基础,深入底层,面试我可造火箭:MySQL+JVM+23种设计模式

    01 MySQL优化 1.1 MySQ优化问题有哪些?怎么学? 关于这个,给大家看一份学习大纲(xmind)文件,每一个分支里面会有详细的介绍. 这里都是以图片形式展示介绍,如要下载原文件以及更多的性 ...

  3. 最搞怪面试问题TOP10:你也来试试看 (大家一起来做题)

    最搞怪面试问题TOP10:你也来试试看! 1 如果把你缩小到铅笔的大小,放入搅拌器,你要如何脱困?(高盛) 2 一枚25分美元硬币周围有多少锯齿纹?(德业众信会计师事务所) 3 功夫的哲学是什么?(美 ...

  4. 前端,通过面试去学习,综合(面试总结整理)

    前言 已经将近3年半没有出去面试了,近期在面试,对照着前端八股文准备的过程中,不禁感叹前端的东西实在是多,涉及的面太多,整个行业环境也比较卷,没办法- 在此过程中的提升确实要比平时做版本迭代需求来得快 ...

  5. 前端面试instanceof_一起回归一下每日一题这些经典面试题

    " 需求已改活已加,加班通宵看朝霞.终是上线已延期,bug还是改不完. 面试造火箭,工作拧螺丝,虽然我只想拧螺丝,可是我需要用造火箭的技术去寻找拧螺丝的工作,如何能在面试过程中让自己处于不败 ...

  6. 如何看待程序员“面试造火箭、工作拧螺丝”?| 畅言

    作者 | 桃翁 本文经授权转自前端桃园(ID:fetaoyuan) 很多人总是抱怨面试官问一些平时不常用的知识点,比如算法.网络(TCP)等等,也就是大家常说的:面试造火箭,工作拧螺丝. 但是有没有想 ...

  7. 蚂蚁前端高级工程师面试必备攻略,面试不仅仅是技术还要看回答方式以及思路.(附全套面试题)

    面试之前准备什么? 建议大家如果准备面试的话,需要做以下准备 背题 看一看最近的面经文章,了解现在公司都在面什么类型的题,准备一些常见题,然后就开刷吧!(文章末尾有为大家准备大厂常见面试题) 算法 做 ...

  8. 聊一聊,面试为什么大厂钟爱问源码,真的是(问)造火箭=>(做)拧螺丝?如何读源码?

    前言 最近身边不少玩的不错的同事跳槽,闲聊时候总会提到面试过程,提到最多的就是面试官问源码.网上很多人都认为,大厂面试的造火箭大炮,进去干拧螺丝的活,我相信很多小伙伴也有这个疑问.那为什么大厂依旧钟爱 ...

  9. 对面试造火箭的一些看法

    很多人总是抱怨面试官问一些平时不常用的知识点,比如算法呀,网络(TCP)等等,也就是大家常说的:面试造火箭,工作拧螺丝. 但是有没有想过为什么整个前端圈,或者绝大部分面试,不仅是前端,各种职位都是这样 ...

最新文章

  1. JAVA实现重建二叉树(《剑指offer》)
  2. linux技术理解,技术|理解 Linux 链接(二)
  3. 程序员必须知道的HTML常用代码有哪些?
  4. 修改HBase的rowkey设计把应用的QPS从5W提升到50W
  5. 如何使用HTML5嵌入视频
  6. clickhouse之数据存储:JBOD vs RAID
  7. 【SAP】ABAP——Web Service简介与配置方法
  8. Java介绍,什么是Java?
  9. 对PCIE设备访问及其配置空间的一点理解
  10. php链接mysql 老是die_php连接MySQL时, 为什么die(错误信息: . $conn-connect_error) 不返回错误信息?...
  11. YII Framework学习教程-YII的Model-开发规范-路径别名-命名空间-2011-11-22
  12. Kepware连接研华 ADAM-4050模块总结
  13. 尊品永耀电商源码--尊品永耀广告电商系统开发源码分享
  14. 峰谷图配置(面积图, 基于echarts)
  15. DISC 免费性格测试题
  16. 数的进制转换(任意两个进制之间的转换)
  17. Alientek I.MX6UL Linux- 第七章 ARM汇编基础
  18. 明天就要离开拉,还没准备好怎么开始
  19. Ajax.NET Professional csharp DropDownList两级联无刷新绑定
  20. 仿wordpress管理后台设计的后台管理框架

热门文章

  1. linux上离线安装mysql_Linux下安装mysql(离线安装和在线安装)
  2. mysql limit优化_MySQL:教你学会如何做性能分析与查询优化
  3. IDEA工具Terminal使用git log中文乱码的解决方法
  4. 如何在Eclipse中添加新建包,java文件,工程工具栏按钮
  5. MySQL的datetime日期格式化,和Oracle的datetime日期格式化
  6. 【转】关于Apache与Nginx的优势比较
  7. Cadence快捷键设置亲测有效!
  8. linux zsh命令行vim命令补齐,Linux使用zsh提高效率的5条建议
  9. mysql按逗号拼接起来_MySQL ----- 计算字段(Trim,Concat,as)(九)
  10. git 创建新分支,合并分支等问题