相信从事前端开发的小伙伴对instanceof和new关键字应该不陌生,isntanceof主要用来判断类型,返回布尔值,new主要用来实例化类函数,接下来咱们来实现一下这两个方法。javascript
// 声明变量
const str = '123'
const num = 123
// 打印
console.log(str instanceof String) // true
console.log(num instanceof Number) // true
复制代码
能够看出instanceof主体分左右两边,左边是待校验类型,右边是目标类型,下面咱们来实现一个:前端
// 主函数
function newInstanceof(current, target) {
// 获取左边的__proto__
let left = current.__proto__
// 获取右边的prototype
let right = target.prototype
// while循环查找左边的__proto__
while(left) {
if(left === right) {
return true
}
left = left.__proto__
}
return false
}
// 测试
const res1 = newInstanceof('123', String)
console.log(res1) // true
const res2 = newInstanceof(123, Number)
console.log(res2) // true
复制代码
这里咱们主要要说明的是__proto__和prototype,__proto__指向构造该对象的构造函数的原型,prototype指的是包含全部实例共享的属性和方法,咱们一般称之为原型对象。全部对象都有__proto__属性,而prototype只有函数对象才有。java
function Foo(value) {
this.value = value
return value
}
Foo.prototype.set = function() {
console.log(this.value)
}
const res = new Foo('init')
res.set() // init
res.value // init
复制代码
以上代码能够看出new以后的对象具有实例化对象的prototype全部属性和私有属性,这里咱们再改造一下Foo函数markdown
function Foo(value) {
this.value = value
return {
obj: 'return object'
}
}
const res = new Foo('init')
console.log(res) // {obj: 'return object'}
复制代码
两个Foo函数,返回普通类型,实例化以后获得的是继承得对象;返回引用类型,实例化以后获得的是该类型,基于这个特性咱们来实现一下函数
function newInstanceof(fn,...args) {
// 建立新对象,赋值fn得prototype
const obj = Object.create(fn.prototype)
// 改变fn的this指向,从新指向obj
const res = fn.call(obj,...args)
return res instanceof Object ? res : obj
}
// 测试返回引用类型
function Foo(value) {
this.value = value
return {
obj: value
}
}
const res = newInstanceof(Foo, 'init')
res.obj // init
// 测试返回普通类型
function Bar(value) {
this.value = value
return this.value
}
const resBar = newInstanceof(Bar, 'bar')
resBar.value // bar
复制代码
至此instanceof和new的运做机制已经实现完成,有问题欢迎在评论中指出。测试