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