中级面试题

面试终于告一段落,来总结一下比较有意思的面试题吧

  • 1-8这部分我认为是最难的,但也是最加分的题目,只要这些问题讲明白,面试管对你的看法会有大大的提升

1. 可以实现一个 bind 函数么?

Function.prototype.myBind = function(thisArg) {
  /* 有人经常会将这一步防御式判断省略,但这里也是一个考点
  * 什么情况下 this 的指向不是一个 'function' ?
  */ 
  if (typeof this !== 'function') return;
  var _self = this
  var args = Array.prototype.slice.call(arguments, 1)
  var fnNop = function () {} // 定义一个空函数
  var fnBound = function () {
    // 这里是另一个考点,this 的指向问题,还有使用 instanceof 判断的理由
    var _this = this instanceof _self ? this : thisArg

    return _self.apply(_this, args.concat(Array.prototype.slice.call(arguments)))
  }
  // 维护原型关系
  if (this.prototype) {
    fnNop.prototype = this.prototype;
  }

  fnBound.prototype = new fnNop();

  return fnBound;
}

这道题其实包含的东西特别多,需要好好理解从函数定义、函数执行、函数的原型、this 的指向等,所以我将这道题放到第一位,务必好好理解。

2、有没有使用过 async 和 await ,了解其中的原理么,如何优雅的统一处理错误?

原理的话大家好好看看阮老师的书就好了,上面介绍的很详细。
如何优雅的处理,我认为在这篇博客中,会有很大的收获:https://juejin.im/post/5c49eb28f265da613a545a4b

3、有没有使用过 Promise , 可以实现一个 Promise.all 么?

  • 首先你需要了解一下 Promise.all 做了什么
    1、接收一个 Promise 实例的数组或具有 Iterator 接口的对象
    2、如果元素不是 Promise 对象,则使用 Promise.resolve 转成 Promise 对象
    3、如果全部成功,状态变为 resolved,返回值将组成一个数组传给回调
    4、只要有一个失败,状态就变为 rejected,返回值将直接传递给回调
    all() 的返回值也是新的 Promise 对象

直接上一段代码(别人的)

function promiseAll(promises) {
  return new Promise(function(resolve, reject) {
  // 防御式判断必须要有
    if (!isArray(promises)) {
      return reject(new TypeError('arguments must be an array'));
    }
    var resolvedCounter = 0;
    var promiseNum = promises.length;
    var resolvedValues = new Array(promiseNum);
    // 根据传入的数组长度,循环
    for (var i = 0; i < promiseNum; i++) {
      (function(i) {
        Promise.resolve(promises[i]).then(function(value) {
          resolvedCounter++
          resolvedValues[i] = value
          if (resolvedCounter == promiseNum) {
            return resolve(resolvedValues)
          }
        }, function(reason) {
          return reject(reason)
        })
      })(i)
    }
  })
}

4、在平常开发中,我们对于一个负责的对象,想获取其中的一个值,经常会写一些 a && a.b && a.b.c ,但是我们只想获取其中的一个值啊,写一个函数实现当前需求

  • 首先最简单的思路就是切割,循环
function path (obj,path) {
  let res = null;
  let aPath = path.split('.');
  aPath.foreach((sPath) => {
    if(sPath in obj){
      res = obj[sPath];
      obj = obj[sPath];
    }
  })
  return res;
}

高阶一点,可以看下 lodash 中的 get 函数

5、有了解过函数式编程么?说一下你了解的纯函数

6、了解EventLoop么,简述一下

  • 这道题能说的多细就多细,比较加分

7、数组的去重

8、instanceof 可以正确判断对象的原理是什么?

  • 其实 instanceof主要的实现原理就是只要右边变量的 prototype 在左边变量的原型链上即可。因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false,告诉我们左边变量并非是右边变量的实例。

9、可以在不新添加变量的情况下,对于一个数组进行排序么?

  • 这是排序中的堆排序,可以背一下

10、vue 中 scope 的实现原理

  • 其实就是通过 PostCss 给对应的节点添加了一个data属性,通过 css 属性选择器来控制

11、观察者模式与订阅发布模式是一样的么?

  • 本人傻傻的回答了一样的,结果....
    但是事实上,确实不一样,难受啊

  • 在观察者模式中,观察者是知道 Subject 的,Subject 一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。

  • 在发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。

  • 观察者模式大多数时候是同步的,比如当事件触发,Subject 就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)。

  • 观察者 模式需要在单个应用程序地址空间中实现,而发布-订阅更像交叉应用模式

注:此文档会持续更新,一场面试就是一场学习,愿大家都有一个好的归宿

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 半年前在知乎浏览到一个帖子,是关于如何面试iOS工程师。由于当时公司正在招聘iOS工程师,自己也面试了不少同学,就...
    Crazy2015阅读 1,279评论 0 15
  • 一、选择题 1.要动态改变层中的内容可以使用的方法有? A:innerHTML B:innerText C:通过设...
    Arthas_Xue阅读 619评论 0 4
  • 什么是arc?(arc是为了解决什么问题诞生的?) 现在有不少程序员是直接从arc上手的,从没接触过mrc,对ar...
    NinaX阅读 524评论 0 1
  • IELTS的写作分为两个部分 第一部分:曲线图,表格,饼图..etc 这种曲线图、表格、饼图….等等的图型是最能掌...
    Riche阅读 304评论 0 0
  • 大家都很喜欢与诚实正直友善的人做好朋友,然而除了好朋友之外,生活里还有朋友。通常,朋友里隔三差五就会出现那么几个小...
    賴床專業戶阅读 331评论 0 0