Javascript中new操作符的实现原理及手写
new 是什么
在JavaScript中,
new
是一个用于创建对象实例的关键字。它用于调用构造函数,并返回一个新的对象。
- 使用
new
关键字创建的对象,可以访问构造函数中定义的属性和方法以及构造函数原型链中的属性和方法。
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype.sayName = function () {
console.log(this.name)
}
const person1 = new Person('xxx', 20)
console.log(person1) // Person {name: "xxx", age: 20}
t.sayName() // 'xxx'
- 如果在构建函数中显式加上原始类型的返回值,可以发现,这个返回值并没有作用:
function Test(name) {
this.name = name
return 1
}
const t = new Test('xxx')
console.log(t.name) // 'xxx'
- 如果在构建函数中返回一个对象的话,这个返回值会被正常使用:
function Test(name) {
this.name = name;
return {name:'hhh'};
}
const t = new Test('xxx')
console.log(t.name) // 'hhh'
实现原理
new
关键字的实现原理可以分为以下几个步骤:
- 创建一个新的空对象。
- 将新创建的对象的
__proto__
属性指向构造函数的prototype
属性。 - 将构造函数的
this
关键字指向新创建的对象。 - 执行构造函数中的代码,给这个空对象添加属性和方法。
- 如果构造函数没有显式返回一个对象,则返回新创建的对象。
手写 new 操作符
- 现在我们已经清楚地掌握了
new
的执行过程,那么我们就动手来实现一下new
:
function myNew(constructor, ...args) {
// 创建一个空对象
const obj = {};
// 设置原型链
Object.setPrototypeOf(obj, constructor.prototype);
// 将构建函数的this指向新对象,并执行构造函数的代码
const result = constructor.apply(obj, args);
// 如果构造函数返回的是对象,则返回该对象;否则返回新创建的对象
return Object.prototype.toString.call(result) === '[object Object]' ? result : obj;
}
- 测试
function myNew(constructor, ...args) {
// 创建一个空对象
const obj = {};
// 设置原型链
Object.setPrototypeOf(obj, constructor.prototype);
// 将构建函数的this指向新对象,并执行构造函数的代码
const result = constructor.apply(obj, args);
// 如果构造函数返回的是对象,则返回该对象;否则返回新创建的对象
return Object.prototype.toString.call(result) === '[object Object]' ? result : obj;
}
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.say = function () {
console.log(this.name)
}
let p = myNew(Person, "xxx", 21)
console.log(p) // Person { name: 'xxx', age: 21 }
p.say() // xxx
小结
以上我对new操作符的理解,本人水平有限,如有错误欢迎在评论区指正,一起讨论!(๑•̀ㅂ•́)و✧
转载自:https://juejin.cn/post/7281276425219522560