# new 的过程
使用 new 调用构造函数:new 的大致过程为:
- 创建一个空的简单 JavaScript 对象(即 {} ),且其原型对象为构造函数的原型对象
- 将步骤 1 新创建的对象作为构造函数的上下文
this
,执行后得到返回值 - 如果该函数没有返回引用类型的值(null 除外),则返回
this
,否则返回该引用类型的值。
function myNew(...args) {
// 1.获取构造函数
const constructor = args.shift();
// 2.创建空对象并设置原型
const obj = Object.create(constructor.prototype);
// 3.绑定this并执行构造函数
const result = constructor.apply(obj, args);
// 4.返回构造函数显示返回的值或新对象
return isObject(result) ? result : obj;
}
function isObject(obj) {
return obj !== null && typeof obj === 'object';
}
new 调用构造函数时,如果构造函数返回了引用类型的值,则 new 会返回这个引用类型的值。
// 引用类型
function constr() {
this.name = 'constr';
}
var instance = new constr();
function constr1() {
this.name = 'constr1';
return { name: 'another object name' };
}
var instance1 = new constr1();
function constr2() {
this.name = 'constr2';
return [1, 2, 3];
}
var instance2 = new constr2();
function constr3() {
this.name = 'constr3';
return new Set([1, 2, 3]);
}
var instance3 = new constr3();
function constr4() {
this.name = 'constr4';
return new WeakSet();
}
var instance4 = new constr4();
function constr5() {
this.name = 'constr5';
return new Map();
}
var instance5 = new constr5();
function constr6() {
this.name = 'constr6';
return new WeakMap();
}
var instance6 = new constr6();
function constr7() {
this.name = 'constr7';
return new Date();
}
var instance7 = new constr7();
function constr8() {
this.name = 'constr8';
return new RegExp();
}
var instance8 = new constr8();
function constr9() {
this.name = 'constr9';
return function foo() {};
}
var instance9 = new constr9();
function constr10() {
this.name = 'constr10';
return new String('some text');
}
var instance10 = new constr10();
function constr11() {
this.name = 'constr11';
return new Number('123');
}
var instance11 = new constr11();
function constr12() {
this.name = 'constr12';
return new Boolean(false);
}
var instance12 = new constr12();
function constr13() {
this.name = 'constr13';
return Math;
}
var instance13 = new constr13();
// 基本类型
function constr14() {
this.name = 'constr14';
return null;
}
var instance14 = new constr14();
function constr15() {
this.name = 'constr15';
return undefined;
}
var instance15 = new constr15();
function constr16() {
this.name = 'constr16';
return true;
}
var instance16 = new constr16();
function constr17() {
this.name = 'constr17';
return false;
}
var instance17 = new constr17();
function constr18() {
this.name = 'constr18';
return 123;
}
var instance18 = new constr18();
function constr19() {
this.name = 'constr19';
return NaN;
}
var instance19 = new constr19();
function constr20() {
this.name = 'constr20';
return '456';
}
var instance20 = new constr20();
function constr21() {
this.name = 'constr21';
return Symbol('foo');
}
var instance21 = new constr21();
function constr22() {
this.name = 'constr22';
return 123n;
}
var instance22 = new constr22();
console.log('instance', instance); // {name: "constr"}
console.log('instance1', instance1); // {name: "another object name"}
console.log('instance2', instance2); // [1, 2, 3]
console.log('instance3', instance3); // Set(3) {1, 2, 3}
console.log('instance4', instance4); // WeakSet {}
console.log('instance5', instance5); // Map(0) {}
console.log('instance6', instance6); // WeakMap {}
console.log('instance7', instance7); // Mon Mar 29 2021 15:44:20 GMT+0800 (中国标准时间)
console.log('instance8', instance8); // /(?:)/
console.log('instance9', instance9); // ƒ foo() {}
console.log('instance10', instance10); // String {"some text"}
console.log('instance11', instance11); // Number {123}
console.log('instance12', instance12); // Boolean {false}
console.log('instance13', instance13); // Math
console.log('instance14', instance14); // {name: "constr14"}
console.log('instance15', instance15); // {name: "constr15"}
console.log('instance16', instance16); // {name: "constr16"}
console.log('instance17', instance17); // {name: "constr17"}
console.log('instance18', instance18); // {name: "constr18"}
console.log('instance19', instance19); // {name: "constr19"}
console.log('instance20', instance20); // {name: "constr20"}
console.log('instance21', instance21); // {name: "constr21"}
console.log('instance22', instance22); // {name: "constr22"}