title: 手写New
date: 2022-09-14 16:38:38
tags:
- js
categories: - JS
手写new
new的过程
要了解new,肯定要知道原生new都在‘后台’执行了哪些操作。
- 在内存中创建一个新的空对象
- 将这个对象的
__proto__
指向构造函数的prototype
原型对象- 将构造函数的作用域赋给这个对象(就是改变构造函数的this指向这个新的对象)
- 执行构造函数内部的代码,并将其属性和方法添加给那个新的对象
- 返回这个新的对象
编写
new示范
要写一个new就要先看看new是怎么使用的
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function(){
console.log('Hello world!');
}
let myPerson = new Person('张三',19);
myPerson.sayHi(); // Hello world
console.log(myPerson); // Person {name: '张三', age: 19}
自制
按照原生new的流程一步一步的书写就可以实现
function myNew(Con,...args) {
// 1.在内存中创建一个空对象
let obj = {};
// 2.将新对象的原型指针指向构造函数的原型属性
obj.__proto__ = Con.prototype;
// 3.构造函数内部的this被赋值为这个新对象(即this指向新对象)
// 4.执行构造函数内部的代码(给新对象添加属性)
let res = Con.apply(obj,args);// apply会执行Con函数,当然此时的this已经是obj了
// 5.如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象
if (res instanceof Object) {
return res
}else{
return obj
}
}
注意
let res = Con.apply(obj,args);
这一部分是改变传入构造函数的this指向为创建的空对象。而第二个参数是要传递给那个构造函数的。apply方法是会执行一次Con的,所以你传入的args就传递给了那个构造函数,当然你的构造函数里面写的无非就是this.xxx = xxx
这种…
如果传入的构造函数有返回值,那么就要返回那个返回的值,前提是返回的是非空对象。都不满足则返回创建的新对象
使用
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function(){
console.log('Hello world!');
}
let myPerson = myNew(Person,'张三',19)
myPerson.sayHi(); // Hello world
console.log(myPerson); // Person {name: '张三', age: 19}