柯倪的实验室
返回文章列表

JavaScript new的解析与实现

new是干什么用的?

其实就是新建一个对象,可能有些人没怎么用过new,但是这一定用过

// 字面量创建对象 
let t1 = {
    name: 'li'
}
// 用new创建对象
// 这里是js自带的的Object函数
let t2 = new Object();
t2.name = 'li'

为什么要用new

那么问题来了,字面量创建更简单更方便,没事闲的用new创建干什么? 为什么需要new,我感觉应该换个问题,new后面的class类是干什么用的,其实new不关键,关键是用new来创造的那个对象 如果项目50个地方需要创建人物模型数据,用字面量创建的方式,容易出问题

const obj = {
    eye:'blue',
    hair:'black'
    ...
}
// 应该使用class创建
class man {
     constructor() {
       this.eye = 'blue'
     }
}
const t1 = new man()

new的具体过程

所以,new是怎么做到的?或者说,字面量创建的时候发生了什么,这一块网上的老哥已经分析很多了,直接上结论

1 新建一个内部对象

2 给这个对象指定一个原型链,对象的__proto__指向构造函数的prototype

3 返回这个内部对象

简单的说就是这么三步,new帮你干的,可以简单的理解new就是个语法糖,自己模拟的话,其实也就几步,上代码

function TestObj(num) {
	this.num = num
}
function newFun(cont, ...args) {
    //cont是构造函数,args是构造函数的所需参数
    // 新建一个对象,new出来返回的就是这个
    let obj = Object.create(cont.prototype); 
    // 给这个对象指定原型链,构造函数有什么,obj也会有
    
    let result = cont.apply(obj, args)
    //运行构造函数,把构造函数的参数挂到obj上,注意是obj
    // 
    return result instanceof Object ? result : obj
}
const test1 = newFun(TestObj,1)

let result = cont.apply(obj, args)因为这个的newFun是个函数,这一步就是把你构造函数的调用对象通过apply挂到obj内部对象上,现在构造函数内的this.num什么的都会挂到obj这个临时对象,至于真实的new需不需要创建一个obj然后挂载上去,我不知道。。。

新创建的result的作用,其实是检查构造函数有没有return对象,apply会把cont这个函数执行一遍,但是apply本身,并没有返回结果,举个例子

// 对吧,平时构造函数就是这么写的
function Test() {
    this.name = '1'
}
let obj = {};
let t1  = Test.apply(obj)
console.log(t1) //undefined

如果构造函数重写了return,new出来的结果可能有点变化

function Test() {
    this.test = 666
    return { //如果return的是基础类型,那就不影响
        name: 'sixsixsix'
    }
}
console.log(new Test()) //sixsixsix

这时候new出来的就是return返回的结果,如果重写了return并且返回的是一个对象,那么cont.apply运行结果就不是undefined,并且 return result instanceof Object ? result : obj这个的返回结果也是重写之后的对象

面试为什么爱问这

这东西可能连带着class问一下,在大型项目因为要涉及到复杂的数据类型,必然要使用class,虽然关系不大,重点是class而不是new

前端