面试终于告一段落,来总结一下比较有意思的面试题吧
- 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、有了解过函数式编程么?说一下你了解的纯函数
- 本人比较菜,这道题答的并不是很好,只说出了固定的输入有固定的输出
具体可以参考:https://llh911001.gitbooks.io/mostly-adequate-guide-chinese/content/
6、了解EventLoop么,简述一下
- 这道题能说的多细就多细,比较加分
7、数组的去重
- 不多做解释了,这个题目的答案太多了,看下别人总结的吧
https://segmentfault.com/a/1190000016418021
8、instanceof 可以正确判断对象的原理是什么?
- 其实
instanceof
主要的实现原理就是只要右边变量的prototype
在左边变量的原型链上即可。因此,instanceof
在查找的过程中会遍历左边变量的原型链,直到找到右边变量的prototype
,如果查找失败,则会返回false
,告诉我们左边变量并非是右边变量的实例。
9、可以在不新添加变量的情况下,对于一个数组进行排序么?
- 这是排序中的堆排序,可以背一下
10、vue 中 scope 的实现原理
- 其实就是通过
PostCss
给对应的节点添加了一个data
属性,通过css
属性选择器来控制
11、观察者模式与订阅发布模式是一样的么?
-
本人傻傻的回答了一样的,结果....
但是事实上,确实不一样,难受啊 -
在观察者模式中,观察者是知道
Subject
的,Subject
一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。 -
在发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。
-
观察者模式大多数时候是同步的,比如当事件触发,
Subject
就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)。 -
观察者 模式需要在单个应用程序地址空间中实现,而发布-订阅更像交叉应用模式
网友评论