- Published on
JS之手写 new
- Authors

- Name
- 叫我小N就好啦
- GitHub
- @MinorN
手写 new
回想一下,我们是怎么使用 new 关键字的?
function Cat(name) {
this.name = name
}
Cat.prototype.sayHello = function () {
console.log(`hello!${this.name}`)
}
const c = new Cat('小N')
c.sayHello() // hello!小N
简单来说,new 做了3个关键事
- 创建一个空对象
- 运行函数,并且绑定
this - 返回这个对象
那么有了以上的思路,我们来实现一个简单版本的 new
function myNew(func, ...rest) {
const obj = {} // 创建一个空对象
func.apply(obj, rest)
return obj
}
// 现在我们来测试一下
function Cat(name) {
this.name = name
}
const c2 = myNew(Cat, '小N')
console.log(c2)
可以看出来成功了,但是如果 Cat 有添加方法呢?
function myNew(func, ...rest) {
const obj = {} // 创建一个空对象
func.apply(obj, rest)
return obj
}
// 现在我们来测试一下
function Cat(name) {
this.name = name
}
Cat.prototype.sayHello = function () {
console.log(`hello!${this.name}`)
}
const c2 = myNew(Cat, '小N')
c2.sayHello()
发现报错了(没有 sayHello)这个方法,这是因为我们的原型链并没有绑定上,所以需要完善我们的 new
function myNew(func, ...rest) {
let obj = Object.create(func.prototype) // 原型链
let ret = func.apply(obj, rest)
return obj
}
function Cat(name) {
this.name = name
}
Cat.prototype.sayHello = function () {
console.log(`hello!${this.name}`)
}
const c2 = myNew(Cat, '小N')
c2.sayHello()
再次运行,发现成功了,我们来看一下 log 一下 c2.__proto__,可以很明显的看到,原型上有 sayHello 的方法。