Appearance
判断 new 调用
javascript
function Foo() {
// 判断自身是否被 new 关键字进行调用
}
Foo()
new Foo()
一、通过构造函数名称
javascript
function Foo() {
const name = this.constructor.name
if (name === 'Foo') {
console.log('构造函数调用1');
} else {
console.log('普通函数调用1');
}
}
二、通过元属性 new.target
javascript
function Foo() {
const target = new.target
if (target === undefined) {
console.log('普通函数调用2');
} else {
console.log('构造函数调用2');
}
}
三、通过构造函数对比
javascript
function Foo() {
if (this.constructor === Foo) {
console.log('构造函数调用3');
} else {
console.log('普通函数调用3');
}
}
四、通过 [[prototype]]
属性
javascript
function Foo() {
const p1 = Object.getPrototypeOf(this);
const p2 = Foo.prototype;
if (p1 === p2) {
console.log('构造函数调用4');
} else {
console.log('普通函数调用4');
}
}
Test Cases
javascript
describe('isNewCall', () => {
let isNewCall;
let Fn = () => {};
function tester() {
new Fn();
expect(isNewCall).toBeTruthy();
Fn();
expect(isNewCall).toBeFalsy();
}
it('byConstructorName', () => {
Fn = function () {
const name = this.constructor.name;
isNewCall = name === 'Fn';
};
tester();
});
it('byNewTarget', () => {
Fn = function () {
const target = new.target;
isNewCall = target !== undefined;
};
tester();
});
it('byConstructorReference', () => {
Fn = function () {
isNewCall = this.constructor === Fn;
};
tester();
});
it('byPrototype', () => {
Fn = function () {
const p1 = Object.getPrototypeOf(this);
const p2 = Fn.prototype;
isNewCall = p1 === p2;
};
tester();
});
});