阅读 108

new与instanceof的实现

new的实现

new做了什么

  1. 创建一个新对象
  2. 将新对象的原型指向构造函数的原型
  3. 将构造函数内部的this指向这个新对象
  4. 将新的对象return出去

new是怎么做的

function myNew(){
//首先先新建一个对象a
  var obj = {}
//将数组对象的shift方法用在arguments上,获取arguments[0]的值b,并删除arguments的第一项
  var b = [].shift.call(arguments)
//新对象的原型指向构造函数的原型
  obj.__proto__ = b.prototype 
//给剩余的arguments定义一个变量c
  var c = arguments
//将构造函数的this指向obj对象,并传递参数c,如果构造函数有返回值,将返回值定义为res
  var res = b.apply(obj,c)
//判断res是否是对象,如果是则返回这个值,如果不是则返回obj对象
//这个地方是new的一个特性,当构造函数返回一个对象时,new这个构造函数就返回这个对象
  return res instanceof Object ? res : obj}
复制代码

测试我们的myNew函数

function Cy(name,age){
        this.name=name
        this.age=age
     }
     Cy.prototype.fun=function(){
         console.log(this.age)
     }
     var a=myNew(Cy,'lsq',23)
     console.log(a)
复制代码

instanceof的实现

instanceof是做什么的

instanceof 严格来说是java的一个双目运算符,用来测试一个对象是否为一个类的实例,JavaScript是引入了这个运算符

  • 我们使用上面new的代码进行测试

    console.log(a instanceof Cy)//true
    //这段代码相当于于
    console.log(a.__proto__==Cy.prototype)//true
    复制代码
  • 除此之外,还有以下代码

    console.log(a instanceof Object)//true
    console.log(a.__proto__==Object.prototype)//false
    console.log(a.__proto__.__proto__==Object.prototype)//true
    复制代码
  • 也就是说,instanceof会将被测试对象的原型链上的所有原型都来判断是否是类的实例,如果是返回true

instanceof是怎么做的

function myInstanceof(left,right){
//首先看看左边对象的原型与右边构造函数的原型是否相等,如果相等返回true
    let r = right.prototype
    let l = left.__proto__
    if(l===r){
      return true
    }
//然后如果他们不相等,就查找原型链再来比较,如果原型指向null那就不比较了直接返回false
else
    if(l!==r&&l.__proto__!==null){
       return  myInstanceof(l,right)
    }
     return false
    }
复制代码

测试我们的myInstanceof函数

function Cy(name,age){
        this.name=name
        this.age=age
     }
     Cy.prototype.fun=function(){
         console.log(this.age)
     }
     var a=new Cy('lsq',23)
console.log(myInstanceof(a,Cy))//true
console.log( myInstanceof(a,Object))//true
console.log( myInstanceof(a,Array))//false
复制代码