Ответ 1
function F() {
var r = function() {
return {};
};
r.__proto__ = this.__proto__;
return r;
}
var f = new F();
f instanceof F;
true
f();
Object
Работает только в браузерах с __proto__
function F() {
return function() {
return {};
}
}
var f = new F();
f instanceof F; // returns false
Насколько я понимаю, если я хочу, чтобы instanceof
работал, мне нужно вернуть this
из конструктора. Но я хочу, чтобы конструктор возвращал функцию, и я не могу назначить this
.
Итак, это действительно невозможно или может быть сделано каким-то образом, для f = new F()
для возврата функции и еще f instanceof F
для возврата true?
function F() {
var r = function() {
return {};
};
r.__proto__ = this.__proto__;
return r;
}
var f = new F();
f instanceof F;
true
f();
Object
Работает только в браузерах с __proto__
Конечно, вы можете сделать все функции instanceof F
, установив F.prototype = Function.prototype;
.
К сожалению, похоже, что ECMAScript не позволяет создавать подкласс функций.
Однако вы можете сделать это в Gecko, используя устаревшее свойство __proto__
:
function F() {
function f() {
return {};
}
f.__proto__ = F.prototype;
return f;
}
F.prototype.__proto__ = F.__proto__;
Для всех, кто сегодня сталкивается с этим, с ES6/2015 появляется новый синтаксис, который вы можете использовать, чтобы избежать устаревшего свойства __proto__
; Object.setPrototypeOf
. Обратите внимание, что MDN предупреждает, что это медленная/дорогая операция.
function F() {
const f = function() {
return {};
}
Object.setPrototypeOf(f, F.prototype);
return f;
}
var f = new F();
f instanceof F; // returns true
f(); // returns {}
Заметьте также, что это немного странно, если вы хотите инициализировать значения в конструкторе. Вам нужно установить их в качестве реквизита для функции, которую вы вернете, но последующие дополнения к прототипу будут ссылаться на них как на 'this'. например.
function F() {
const f = function() {
return {};
}
f.favoriteBand = 'The Books';
Object.setPrototypeOf(f, F.prototype);
return f;
}
F.prototype.getFavoriteBand = function(){ return this.favoriteBand; }
var f = new F();
f.getFavoriteBand() // returns 'The Books'
В вашем примере F не является конструктором, это функция, которая возвращает анонимный конструктор, который вы затем вызываете new. instanceof работает, просматривая цепочку прототипов, поэтому ваш код не работает, потому что вы неправильно настроили прототипы.
Этот page имеет хорошее объяснение конструкторов JavaScript и как подкласс.
Взгляните на следующий код и посмотрите, помогает ли он.
function F() {
this.whoami = 'F';
this.whatami = 'F';
}
function Sub() {
this.whoami = 'G';
}
Sub.prototype = new F();
function G() {
return new Sub;
}
var f = new G();
console.log(f instanceof F); // returns false
console.log(f.whoami);
console.log(f.whatami);