Вопрос по javascript, oop, constructor – Может ли конструктор JavaScript вернуть функцию и сохранить наследование?

13
function F() {
    return function() {
        return {};
    }
}

var f = new F();
f instanceof F; // returns false

Насколько я понимаю, если я хочуinstanceof на работу, мне нужно вернутьсяthis от конструктора. Но я хочу, чтобы конструктор возвращал функцию, и я не могу присвоитьthis.

Итак, действительно ли это невозможно или это можно сделать как-то, дляf = new F() вернуть функцию и ещеf instanceof F вернуть истину?

@Niklas: да :) Felix Kling
Почему вы хотите, чтобы instanceof работал? Это обычно считается вредным. zetlen
Вы можете вернуть функцию, так как функция является объектом. Но очевидно,f instanceof F не будет правдой, так как это не так. Felix Kling
Феликс: Тавтология так же, как тавтология? :) Niklas B.
Остается вопрос: чего вы хотите достичь? Niklas B.

Ваш Ответ

4   ответа
8
function F() {
    var r = function() {
        return {};
    };

    r.__proto__ = this.__proto__;
    return r;
}

var f = new F();
f instanceof F;
true
f();
Object

__proto__

Error: User Rate Limit Exceeded Sixtease
1

кто сталкивался с этим сегодня, с ES6 / 2015 имеет новый синтаксис, который вы можете использовать, чтобы избежать устаревшего__proto__ имущество;Object.setPrototypeOf, Обратите внимание, чтоМДН предупреждает что это медленная / дорогая операция.

function F() {
    const f = function() {
        return {};
    }
    Object.setPrototypeOf(f, F.prototype);
    return f;
}

var f = new F();
f instanceof F; // returns true
f(); // returns {}

Также обратите внимание, что это немного странно, если вы хотите инициализировать значения в конструкторе. Вам нужно установить их как реквизиты для функции, которую вы вернете, но последующие добавления к прототипу будут ссылаться на них как «это». например

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'
5

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__;
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded.applyError: User Rate Limit Exceeded.callError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Sixtease
Error: User Rate Limit Exceeded
0

это функция, которая возвращает анонимный конструктор, который вы затем вызываете new. instanceof работает, просматривая цепочку прототипов, поэтому ваш код не работает, потому что вы не настроили прототипы правильно.

этостраница имеет хорошее объяснение конструкторов 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);
​

Похожие вопросы