new操作符的实现原理
new 可以用来实例化一个类,从而在内存中分配一个实例对象。
new操作符的执行过程:
- 首先创建了一个新的空对象
- 设置原型,将空对象的隐式原型设置为构造函数的 prototype 对象。
- 让函数的 this 指向这个新创建的空对象,执行构造函数的代码。为新创建的空对象添加属性。
- 判断调用函数过后的返回值类型,如果是基本数据类型,则返回创建的对象。如果是引用类型,就返回这个引用类型的对象。
代码如下
function _new() {
//获取第一个参数
const fn = Array.prototype.shift.call(arguments);
//获取后面要传入构造函数内的参数
const args = Array.from(arguments);
//判断第一个参数是否是一个函数,如果不是抛出类型错误
if (typeof fn !== 'function') {
throw new TypeError('a is not a constructor')
}
// 新建一个空对象,对象的隐式原型为构造函数的 prototype 对象
const obj = Object.create(fn.prototype)
//将构造函数内部的this指向obj,并执行,获取函数返回值
const result = fn.apply(obj, args)
//判断函数返回的值是否是引用数据类型
if (result instanceof Object) {
//如果是返回该函数的返回值
return result;
} else {
//如果不是就返回obj
return obj;
}
}
function add(name,age) {
this.name = name;
this.age = age;
}
add.prototype.say = function () {
console.log(`我叫${this.name},今年${this.age}岁`)
}
const test = _new(add,'马老板',20)
console.log(test) // add {name: '马老板', age: 20}
test.say() //我叫马老板,今年20岁