JavaScript 关键字instanceof、new实现原理

时间:2021-1-8 作者:admin

开篇

相信从事前端开发的小伙伴对instanceofnew关键字应该不陌生,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

结语

至此instanceofnew的运作机制已经实现完成,有问题欢迎在评论中指出。

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。