需手写面试题集锦
请实现一个instanceOf,使下面代码运行正常
function instanceOf(left, right) {
// 请完善这个函数
}
class A {}
class B extands A {}
class C {}
const b = new B()
console.log(instanceOf(b, B)) // true
console.log(instanceOf(b, A)) // true
console.log(instanceOf(b, C)) // false
分析:
本题主要考察instanceof的原理,instanceof的主要原理是沿着左边变量的__proto__跟右边变量的prototype查找,如果能找到同一个引用,则返回true。因此,在查找的过程中,会遍历左边变量的原型链,如果查找失败,则返回false.
// 实现
function instanceOf(left, right) {
let proto = left.__proto__
while(proto != null) {
if (proto === right.prototype) {
return true
}
proto = proto.__proto__
}
return false
}
「注意」⚠️⚠️⚠️:instanceof不能判断基本数据类型(返回false),只能判断引用类型。typeof能判断出除了null以外的基本数据类型,亦能判断出引用类型function,其余均为object
实现一个new操作符
function mockNew(ctor, ...rest) {
// 实现这个函数
}
function Fun(name, age) {
this.name = name
this.age = age
}
Fun.prototype.getName = function() {
return `我的名字是${this.name}`
}
const boy = mockNew(Fun, 'Jack', 18)
console.log(boy.getName())
分析new的实现过程:
- 创建一个新的对象
- 将构造函数的原型赋给新的对象
- 执行构造函数
- 如果构造函数返回值为一个对象,则返回该对象,否则,返回创建的新对象
// 实现
function mockNew(ctor, ...rest) {
if(typeof ctor !== 'function') {
return ctor
}
const obj = Object.create(ctor.prototype)
const r = ctor.apply(obj, rest)
if(typeof r === 'object') {
return r
}
return obj
}
手写bind函数
Function.prototype.bind = function(context) {
let that = this
const args = Array.prototype.slice.call(arguments, 1)
let fn = function() {}
function fBind() {
let rest = Array.prototype.slice.call(arguments)
return that.apply(this instanceof fBind ? this : context, args.concat(rest))
}
fBind.prototype = Object.create(this.prototype)
return fBind
}
call && apply
// call的实现
Function.prototype.call = function(context) {
context = context ? Object(context) : context
context.fn = this
let args = []
for(let i = 1; i < arguments.length; i++) {
args.push('arguments['+ i +']')
}
// 需要执行args.toString()
let r = eval('context.fn('+ args +')')
delete context.fn
return r
}
// apply的实现
Function.prototype.apply = function(context, args) {
context = context ? Object(context) : context
context.fn = this
if(!args) {
return context.fn
}
let r = eval('context.fn(args)')
delete context.fn
return r
}
...持续更新中...
如有错误,欢迎指正。 来都来了,点个赞呗,笔芯~