new操作做了什么
在写new之前,我们需要了解new到底做了啥
const fn=function (name,age){
this.name=name
this.age=age
}
fn.prototype.say=()=>{
console.log('你好我是周杰伦')
}
const obj=new fn('周杰伦',38)
console.log(obj)
上面的new对构造函数做了以下工作:
1、返回一个对象
2、将此对象的原型与构造函数的原型链相链接
3、执行构造函数,并且把构造函数的属性都设置到这个对象上(通过this)
手写new功能
下面我们来写一个create
函数来模拟new
的功能
function create(fn,...args){
if(!(fn instanceof Function)){
throw new Error('你传入的参数不是函数')
}
let obj={}
if(fn.prototype){ //箭头函数没有原型链
obj=Object.create(fn.prototype)
}else{
obj.__proto__={constructor:fn}
}
//接原型链
fn.call(obj,...args)//把fn的属性赋给这个对象
return obj
}
const obj=create(fn,'周杰伦',38)
console.log(obj)
上面的构造函数需要传入构造函数和其他参数,在刚开始会使用fn的原型链创建一个空对象obj,由于传入的构造函数不一定有原型链,(因为有些无聊的人可能会传一个匿名函数,匿名函数没有原型链也不支持this,不过依然可以帮造一个原型出来)
自带new的构造函数
根据上面的特性,还可以自己写一个自带new功能的构造函数
function constructor(name,age){
const obj=Object.create(constructor.prototype)
Object.assign(obj,{name:name,age:age})
return obj
}
constructor.prototype={
constructor:constructor,
say(){console.log('我是周杰伦')}
}
const obj=constructor('周杰伦',38)
打一下obj
看看
属性都赋值上了,原型链也加上了,应该没啥问题~