开篇
相信从事前端开发的小伙伴对instanceof和new关键字应该不陌生,isntanceof主要用来判断类型,返回布尔值,new主要用来实例化类函数,接下来我们来实现一下这两个方法。
实现instanceof
实例场景
// 声明变量 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只有函数对象才有。
实现new
实例场景
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函数
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的运作机制已经实现完成,有问题欢迎在评论中指出。