都2020年了,你应该知道如何手写New了吧

接着上一篇,咱们继续来研究如何手写。web

1、手写new

1.new运算符都作了什么

  1. 新建一个对象。
  2. 执行prototype链接。
  3. 将构造函数的做用域赋给新对象。
  4. 绑定this指向,执行构造函数中的代码。
  5. 返回这个对象。

2.简单实现

function myNew(context) {

    // 新建一个对象
    var res = new Object();
    
    // 获取传递的参数,第一个参数表明传入的构造函数,也就是这个即将建立的这个实例的构造函数,截取掉
    const args = [...arguments].slice(1);
  
    // 将建立的res的this绑定到传进来的这个构造函数context
    context.apply(res, args);
  
    return res;
}

function Hdove(name) {
  this.name = name;
}

var example = myNew(Hdove, 'LJ');

console.log(example); // {name: "LJ"}

复制代码

3.继续改造

来,咱们先看一下真实的new操做符bash

function Hdove(name) {
  this.name = name;
}

Hdove.prototype.age = 25;

Hdove.prototype.sayName = function() {
    console.log(this.name);
};

var obj = new Hdove('LJ');

console.log(obj.name); // LJ
console.log(obj.age); // 25
obj.sayName(); // LJ

复制代码

继续修改咱们的代码app

function myNew(context) {

    var res = new Object();
    
    // 判断构造函数上有没有原型,有的话进行添加
    if(context.prototype) {
        res.__proto__ = context.prototype
    }
    
    const args = [...arguments].slice(1);
  
    context.apply(res, args);
  
    return res;
}

function Hdove(name) {
  this.name = name;
}

Hdove.prototype.age = 25;

Hdove.prototype.sayName = function() {
    console.log(this.name);
};

var example = myNew(Hdove, 'LJ');

console.log(example);

经过下图咱们能够看出原型已经成功绑定了,完美

复制代码

距离成功还有一步,咱们加足马力函数

4.改造升级

咱们继续看一下原生的new 操做符post

1.返回一个对象
function Hdove(name) {
  this.name = name;
  return {
    name: 'return出来的'
  }
}

var obj = new Hdove('LJ');  
console.log(obj); // {name: "return出来的"}

2.返回基本类型
function Hdove(name) {
  this.name = name;
  return '123';
}


var obj = new Hdove('LJ');  
console.log(obj); // {name: "LJ"}

3.返回一个方法
function Hdove(name) {
  this.name = name;
  return function() {
    console.log(123);
  };
}


var obj = new Hdove('LJ');  
console.log(obj); // function () { window.runnerWindow.proxyConsole.log(123); }

复制代码

有没有发现神奇的事情发生了,当咱们在构造函数中返回一个对象类型A的时候,这个时候咱们使用new操做符,实际上返回的就是这个A,反之,返回的是咱们新建的这个对象,开始实现!ui

function myNew(context) {

    var res = new Object();
    
    // 判断构造函数上有没有原型,有的话进行添加
    if(context.prototype) {
        res.__proto__ = context.prototype
    }
    
    const args = [...arguments].slice(1);
  
    const ret = context.apply(res, args);
    
    // 判断ret 是否是object或者function,由于null也属于object,因此要单独排除
    if((typeof ret === 'object' || typeof ret === 'function') && ret !== null) {
      return ret;
    }
    return res;
}

function Hdove1(name) {
  this.name = name;
}

function Hdove2(name) {
  this.name = name;
  return {
    name: 'return出来的数据'
  }
}

var example1 = myNew(Hdove1, 'LJ');
var example2 = myNew(Hdove2, 'LJ');

console.log(example1); // { name: LJ }
console.log(example2); // { name: return出来的数据 }

复制代码

5.完整版

function myNew(context) {

    var res = new Object();
    
    if(context.prototype) {
        res.__proto__ = context.prototype
    }
    
    const args = [...arguments].slice(1);
  
    const ret = context.apply(res, args);
    
    if((typeof ret === 'object' || typeof ret === 'function') && ret !== null) {
      return ret;
    }
    return res;
}

复制代码

6.推荐阅读

相关文章
相关标签/搜索