0%

手写New

手写new

new的过程

要了解new,肯定要知道原生new都在‘后台’执行了哪些操作。

  1. 在内存中创建一个新的空对象
  2. 将这个对象的__proto__指向构造函数的prototype原型对象
  3. 将构造函数的作用域赋给这个对象(就是改变构造函数的this指向这个新的对象)
  4. 执行构造函数内部的代码,并将其属性和方法添加给那个新的对象
  5. 返回这个新的对象

编写

new示范

要写一个new就要先看看new是怎么使用的

1
2
3
4
5
6
7
8
9
10
11
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的流程一步一步的书写就可以实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
}
}

注意

1
let res = Con.apply(obj,args);

这一部分是改变传入构造函数的this指向为创建的空对象。而第二个参数是要传递给那个构造函数的。apply方法是会执行一次Con的,所以你传入的args就传递给了那个构造函数,当然你的构造函数里面写的无非就是this.xxx = xxx这种….

如果传入的构造函数有返回值,那么就要返回那个返回的值,前提是返回的是非空对象。都不满足则返回创建的新对象

使用

1
2
3
4
5
6
7
8
9
10
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}