Skip to content

实现new的过程

js
function Ctor() {}

function myNew(ctor, ...args) {
  if (typeof ctor !== 'function') {
    throw 'must be function'
  }
  var newObj = Object.create(ctor.prototype) // 创建一个继承自ctor.prototype的新对象
  var ctorReturnresult = ctor.apply(newObj, args) // 将构造函数ctor的this绑定到newObj中
  var isObject = typeof ctorReturnresult === 'object' && ctorReturnresult !== null
  var isFunction = typeof ctorReturnresult === 'function'
  if (isObject || isFunction) {
    return ctorReturnresult
  }
  return newObj
}
js
function myNew(fn, ...args) {
  let instance = Object.create(fn.prototype)
  let res = fn.apply(instance, args)
  // 确保返回的是一个对象(万一fn不是构造函数)
  return typeof res === 'object' ? res : instance
}
js
function myNew(fn, ...args) {
  let obj = Object.create(fn.prototype)
  let res = fn.call(obj, ...args)
  if (res && (typeof res === 'object' || typeof res === 'function')) {
    return res
  }
  return obj
}

// 用法如下:
function Person(name, age) {
  this.name = name
  this.age = age
}
Person.prototype.say = function () {
  console.log(this.age)
}
let p1 = myNew(Person, 'lihua', 18)
console.log(p1.name)
console.log(p1)
p1.say()
js
// 第一版
function myNew() {
  var obj = new Object()
  Constructor = [].shift.call(arguments)
  obj.__proto__ = Constructor.prototype
  Constructor.apply(obj, arguments)
  return obj
}
// 第二版
function myNew() {
  var obj = new Object()
  Constructor = [].shift.call(arguments)
  obj.__proto__ = Constructor.prototype
  var ret = Constructor.apply(obj, arguments)
  return typeof ret === 'object' ? ret : obj
}

function newOperator(ctor) {
  // 创建了一个全新的对象。
  // 这个对象会被执行[[Prototype]](也就是__proto__)链接。
  // 生成的新对象会绑定到函数调用的this。
  // 通过new创建的每个对象将最终被[[Prototype]]链接到这个函数的prototype对象上。
  // 如果函数没有返回对象类型Object(包含Functoin, Array, Date, RegExg, Error),那么new表达式中的函数调用会自动返回这个新的对象。
  if (typeof ctor !== 'function') {
    throw 'newOperator function the first param must be a function'
  }
  //es6 new.target是指向构造函数的
  newOperator.target = ctor
  // 1.创建一个全新的对象
  // 2.并且执行[[Prototype]]链接
  // 4.通过`new`创建的每个对象将最终被`[[Prototype]]`链接到这个函数的`prototype`对象上
  var newObj = Object.create(ctor.prototype)
  // ES5 arguments转成数组 当然也可以用ES6 [...arguments], Aarry.from(arguments);
  // 除去ctor构造函数的其余参数
  var argsArr = [].slice.call(arguments, 1)
  // 3.生成的新对象会绑定到函数调用的`this`
  // 获取到ctor函数返回结果
  var ctorReturnResult = ctor.apply(newObj, argsArr)
  var isObject = typeof ctorReturnResult === 'object' && ctorReturnResult !== null
  var isFunction = typeof ctorReturnResult === 'function'
  if (isObject || isFunction) {
    return ctorReturnResult
  }
  return newObj
}

// 其他版本
function MyNew(ctor, ...args) {
  if (typeof ctor !== 'function') throw 'cotor must be a function'
  let obj = Object.create(ctor.prototype)
  let res = ctor.call(obj, ...args)
  let isObject = typeof res === 'object' && res !== null
  let isFunction = typeof res === 'function'
  return isObject || isFunction ? res : obj
}

如有转载或 CV 的请标注本站原文地址