推荐答案
new 操作符的执行过程主要分为以下四个步骤:
- 创建一个新的空对象:首先,创建一个全新的空对象,这个对象的类型将是
object。 - 将新对象的
__proto__属性指向构造函数的prototype属性:将新创建的空对象的原型(__proto__属性)指向构造函数的原型对象(prototype属性)。这样新对象就继承了构造函数原型上的属性和方法。 - 将构造函数内部的
this指向新创建的对象,并执行构造函数中的代码:调用构造函数,并将this指向新创建的空对象。这样构造函数中的代码就可以通过this来操作新创建的对象,初始化对象的属性。 - 根据构造函数的返回值确定
new操作符的返回值:如果构造函数没有显式返回一个对象(返回null或基本数据类型),则new操作符返回第一步创建的新对象。如果构造函数显式返回一个对象,则new操作符返回这个对象。
手动实现一个 myNew 函数:
// www.javascriptcn.com code example
function myNew(constructor, ...args) {
if (typeof constructor !== 'function') {
throw new TypeError('Constructor must be a function');
}
// 1. 创建一个新对象
const obj = Object.create(constructor.prototype);
// 2. 执行构造函数,并绑定this到新对象
const result = constructor.apply(obj, args);
// 3. 处理构造函数的返回值
return (typeof result === 'object' && result !== null) || typeof result === 'function' ? result : obj;
}本题详细解读
new 操作符的作用
new 操作符的主要作用是:
- 创建对象实例:它通过调用一个构造函数来创建一个新的对象实例。
- 建立原型链:它将新对象的原型(
__proto__)链接到构造函数的原型对象(prototype),从而实现继承。 - 初始化对象状态:它执行构造函数,允许通过
this关键字来设置新对象的属性和方法。
new 操作符的执行步骤详解
创建一个新的空对象:
- 首先,
new操作符会在内存中分配一块新的空间来存储这个对象。 - 这个新对象没有任何属性,是一个空对象。
- 它的类型是
object。
- 首先,
将新对象的
__proto__属性指向构造函数的prototype属性:- 每个对象都有一个
__proto__属性,指向其原型。 - 每个函数都有一个
prototype属性,这个属性指向一个对象,该对象会被作为通过new创建的实例的原型。 - 这一步将新创建的空对象的原型链和构造函数的原型链连接起来,实现原型继承。
- 每个对象都有一个
将构造函数内部的
this指向新创建的对象,并执行构造函数中的代码:- 构造函数本质上是一个函数,它的
this指向取决于调用方式。 - 当通过
new调用时,this会被绑定到新创建的空对象。 - 构造函数内的代码就可以通过
this.xxx = ...来初始化新对象的属性。
- 构造函数本质上是一个函数,它的
根据构造函数的返回值确定
new操作符的返回值:- 默认情况下,如果构造函数没有明确返回值,
new操作符会返回新创建的对象实例。 - 如果构造函数显式返回一个对象或者函数(非
null),那么new操作符将返回构造函数返回的这个对象或者函数。 - 如果构造函数显式返回的是
null或者基本类型(如number、string、boolean、undefined、symbol),new操作符依然返回新创建的对象实例。
- 默认情况下,如果构造函数没有明确返回值,
手动实现 myNew 函数的详解
// www.javascriptcn.com code example
function myNew(constructor, ...args) {
if (typeof constructor !== 'function') {
throw new TypeError('Constructor must be a function');
}
// 1. 创建一个新对象,并将其原型指向构造函数的原型
const obj = Object.create(constructor.prototype);
// 2. 执行构造函数,并将 `this` 指向新创建的对象,传入参数
const result = constructor.apply(obj, args);
// 3. 根据构造函数的返回值确定返回
return (typeof result === 'object' && result !== null) || typeof result === 'function' ? result : obj;
}
- 类型检查: 首先检查
constructor是否是一个函数,如果不是则抛出类型错误。 - 创建对象: 使用
Object.create(constructor.prototype)创建一个新对象,这个新对象的原型(__proto__)指向constructor的原型(prototype)。 - 执行构造函数: 使用
apply调用构造函数,将this绑定到新创建的对象obj,并将参数传递给构造函数。 - 处理返回值: 判断构造函数的返回值是否是一个对象或者函数,如果是则返回构造函数的返回值,否则返回新创建的对象。
Object.create()的作用Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。这里用构造函数的prototype作为新对象的原型,实现了原型继承。
通过 myNew 函数,我们手动模拟了 new 操作符的执行过程,更深入地理解了 new 操作符背后的原理。