new操作符

new

基础

new会创建空的新对象{},这个对象会被作为构造函数的上下文(就是this)

新对象会链接到原型,内部属性 [[Prototype]] (__proto__ 指向构造函数的 prototype 属性)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Person(name, age) { // 构造函数首字母通常大写,以区分普通函数
this.name = name;
this.age = age;
}

Person.prototype.greet = function () { // 设置原型上的方法
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

// 使用 new 创建实例
const alice = new Person('Alice', 25); // 创建了一个新的对象 {...} // alice.__proto__ -> Person.prototype
console.log(alice.name); // 输出 'Alice'
console.log(alice.age); // 输出 25
alice.greet(); // 输出 'Hello, my name is Alice and I am 25 years old.'

注意:只要构造函数含有this,避免忘记使用 new 调用构造函数,否则 this 会指向全局对象(严格模式下为 undefined

手写

1
2
3
4
5
6
7
8
9
10
function myNew(constructor, ...args) {
// 1. 创建一个空对象,并继承构造函数的 prototype
const obj = Object.create(constructor.prototype);

// 2. 执行构造函数,并将 this 绑定到新对象上
const result = constructor.apply(obj, args);

// 3. 如果构造函数返回的是一个对象,则返回这个对象,否则返回新创建的对象
return (typeof result === 'object' && result !== null) ? result : obj;
}
1
2
3
4
5
6
7
8
function Person(name, age) {
this.name = name;
this.age = age;
}

Person.prototype.sayHello = function() { // 原型上的方法
console.log(`Hello, I'm ${this.name}`);
};
1
2
3
4
5
const p1 = new Person('Alice', 25);
p1.sayHello(); // 输出 "Hello, I'm Alice"

const p2 = myNew(Person, 'Bob', 30);
p2.sayHello(); // 输出 "Hello, I'm Bob"