构造函数和普通函数的区别(重写内置new)

224 阅读1分钟

构造函数

如函数用来初始化(使用new操作符)一个新建的对象,我们称之为构造函数(constructor);

function Person() {
    this.name = 'mike'
    this.age = 18
}
new Person()

普通函数

不使用new运算符的函数就是普通函数

function person() {
   console.log('function')
}
person()

构造函数VS普通函数

  1. 构造函数使用new关键词调用,普通函数使用小括号执行;
  2. 构造函数中this指向创建的实例对象,普通函数this在严格模式下指向undefined,非严格模式下指向window
  3. 构造函数默认返回的是构造函数的实例对象,普通函数需要return返回值,没有return默认返回的是undefined
  4. 构造函数首字母一般大写,普通函数首字母一般小写

重写内置new

function _new(fn, params) {

    //箭头函数没有prototype,所以不能被new
    //symbol和bigInt虽然有prototype,也不能被new
    // 所以此处要先判断这几种情况
    if (!fn?.prototype || typeof fn === 'symbol' || typeof fn === 'bigInt') {
        throw new TypeError('fn is not a constructor')
    }
    
    //1、创建一个空对象,使空对象的__proto__指向fn.prototype
    let obj = object.create(fn.prototype);
    
    //2、fn执行并且this指向创建的对象
    let result = fn.call(obj, ...params)
    
    //3、判断fn的返回值,如果没有返回值或返回值是原始数据类型,则默认返回创建的对象;如果返回值是引用数据类型,则返回fn的执行结果
    if(typeof result !== 'null' && /^(object|function)$/.test(typeof result)) {
        return result
    }
    return obj
    
}