new
new详解
一、实例化
形式1:构造函数(ES5)
function Person(name) {
this.name = name
}
Person.prototype.sayHi = function() {
console.log('hi,', this.name)
}
let p = new Person('rory');
p.sayHi(); // hi, rory
console.log(p.__proto__ === Person.prototype); // true
形式2:类(ES6)
class Person {
constructor(name) {
this.name = name;
}
sayHi() {
console.log('hi,', this.name)
}
}
let p = new Person('rory');
p.sayHi(); // hi, rory
console.log(p.__proto__ === Person.prototype); // true
二、构造函数实例化过程:
声明一个空对象
改变原型:将空对象的原型(__proto__)指向构造函数的原型对象(prototype)
改变this:将构造函数的this指向空对象
返回结果:判断构造函数执行结果是否是对象,是则直接返回执行结果,否则返回声明的那个空对象
三、手动实现new:
function myNew(constructor, ...args) {
// 1.声明一个实例对象
let obj = {};
// 2.将实例对象的原型指向构造函数的原型对象
Object.setPrototypeOf(obj, constructor.prototype)
// 3.将构造函数的this指向此实例对象
const result = constructor.call(obj, ...args)
// 4.返回此实例对象
return typeof result === 'object' ? result : obj
}
验证:构造函数有返回值的情况
function Person() {
this.name = 'yuyy'
}
const p = new Person();
console.log(p); // Person { name: 'yuyy' }
function Person1() {
this.name = 'yuyy'
return { age: 18 }
}
const p1 = new Person1();
console.log(p1); // { age: 18 }
function Person2() {
this.name = 'yuyy'
return 1
}
const p2 = new Person2();
console.log(p2); // Person2 { name: 'yuyy' }
四、new.target
检测函数或构造方法是否是通过new运算符被调用的
普通的函数调用:new -> undefined
有new的构造函数调用:new -> 构造函数名
function Foo() {
console.log(new.target?.name);
}
Foo();
new Foo();
输出:
undefined
Foo
参考:
Last updated