https://www.lagagain.com/post/7%E5%A4%A9%E6%90%9E%E6%87%82js%E9%80%B2%E9%9A%8E%E8%AD%B0%E9%A1%8Cday02-new-factory/
題目
function FooConstructor(name){
this.name = name;
this.hello = function(){
console.log(`Hello, ${this.name}`);
}
}
var obj2 = new FooConstructor("Foo");
var obj3 = {};
obj3.constructor = FooConstructor;
obj3.constructor("Kitty");
obj3.hello(); // => Hello, Kitty
var obj4 = {};
obj4.__proto__ = FooConstructor.prototype;
obj4.constructor("K-on");
obj4.hello(); // => Hello, K-on
Object.is(obj3.constructor, obj4.constructor); // true
考題
FooConstructor.prototype.bye = function(){console.log(`Bye Bye, ${this.name}`)};
obj2.bye(); // => Bye Bye, Foo
// obj3.bye(); // error! 沒繼承到`FooConstructor`,不受影響
obj4.bye(); // => Bye Bye, K-on
var name; // just declare
console.log(name); // => underfined
FooConstructor("JavaScript"); // 沒寫到new
// Oops! 怎麼被改到了??
console.log(name); // Javascript
可以改寫func如下避免:
The new.target meta-property lets you detect whether a function or constructor was called using the new operator.
function FooConstructor(name){
if (!new.target) throw "FooConstructor() must be called with new";
this.name = name;
this.hello = function(){
console.log(`Hello, ${this.name}`);
}
}