Skip to content

手动实现(一):new 和 instanceof #17

@chenwangji

Description

@chenwangji

新的一年,新的开始。最近的开发过程越来越感觉基础不够扎实,很多知识的理解都很片面,所以打算以这一个系列开始自己的基础夯实之路,希望自己能坚持下去。

手动实现 new

new 的原理

new 的作用是实例化一个类,所以紧接的必须是一个构造函数(或者 class)。

具体执行过程:

  1. 创建一个空对象
  2. 将该对象的 __proto__ 属性指向构造函数的 prototype
  3. 构造函数的执行上下文指向该对象,然后执行构造函数
  4. 如果构造函数的返回结果是对象,则直接返回这个对象;否则隐式返回最开始创建的那个对象。

具体代码实现如下:

/**
 * 手动实现 new 操作符
 * @param {*} fn 构造函数,第二个及后面的参数传递给构造函数
 */
function New(fn) {
    const instance = {}
    instance.__proto__ = fn.prototype

    const args = Array.prototype.slice.call(arguments, 1)
    const res = fn.apply(instance, args)

    // 如果构造函数有返回值并且为对象时,直接用该返回值,否则返回前面生成的实例
    if (res !== null && (typeof res === 'object' || typeof res === 'function')) {
        return res
    }
    return instance
}

// test
function Dog(name) {
    this.name = name
}

var dog = New(Dog, 'Tony')
console.log(dog.name) // 'Tony'
console.log(dog instanceof Dog) // true

手动实现 instanceof

instanceof 原理

instanceof 用于判断左侧值是否是右侧值的实例,所以左侧必须是一个对象,而右侧是一个类。

具体原理是 instanceof 会查找原型链,知道 null 之前如果还不是这个对象的实例则会返回 false,否则返回 true

具体实现:

/**
 * 
 * @param {*} instance 实例
 * @param {*} clazz 类
 */
 function instanceOf(instance, clazz) {
    if ( typeof clazz !== 'function') throw new Error('Right-hand error')
    if (instance === null || (typeof instance !== 'object' && typeof instance !== 'function')) return false

    const proto = clazz.prototype
    while (instance.__proto__) {
        if (instance.__proto__ === proto) return true
        instance = instance.__proto__
    }
    return false
 }

 // test
 var one = new Number(1)
 console.log(
    instanceOf(one, Number), // true
    instanceOf(one, Object) // true
 )

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions