Расширение класса Javascript: вызов функции базового класса из функции дочернего класса: кажется, вызывает статический метод - PullRequest
2 голосов
/ 19 января 2012

Это сложно объяснить, но я занимаюсь этим уже несколько дней. Я "расширяю" один Javascript "класс" на другой, но вызов метода базового класса из метода дочернего класса не работает должным образом. Кажется, что метод базового класса «действует» как статический метод: свойства, которые определены в дочернем классе, так или иначе имеют свои значения по умолчанию при вызове метода базового класса из метода дочернего класса.

Для простоты я не включил свой сложный код, но создал простой пример того, что я делаю:

function extend(Child, Parent){
    var F = function(){};
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    Child.prototype.constructor = Child;
    Child.base = Parent.prototype;
}

function BaseClass(){
}

BaseClass.prototype.randomNumber = 0;
BaseClass.prototype.functionA = function(){
     this.randomNumber = 200;
     this.functionB();
}

BaseClass.prototype.functionB = function(){
     alert(this.randomNumber);
     console.info(this);
}

function ChildClass(){

    this.functionB = function(){
         ChildClass.base.functionB();
    };
}

extend(ChildClass, BaseClass); 
var childInstance = new ChildClass();
childInstance.functionA();

Я использую firebug для входа в консоль. Он выводит "Baseclass", и this.randomNumber как-то равно 0, в то время как он установлен в 200 в функции A.

метод расширения, который я использую, аналогичен методу из Yahoo.lang.extend, который я тоже пробовал с тем же результатом.

Я не могу понять, что я что-то упустил, или это только один из недостатков "расширения" Javascript, и я фактически вызываю здесь "статический" метод. Помощь будет высоко ценится здесь. Надеюсь, понятно, что я пытаюсь сделать здесь, потому что мне сложно выразить это словами. Большое спасибо заранее!

1 Ответ

5 голосов
/ 19 января 2012

Что происходит в этой строке кода:

ChildClass.base.functionB();

... это то, что functionB вызывается с this, указывающим на ChildClass.base.Это связано с тем, что this в JavaScript полностью определяется как функция называется , а не там, где она определена (в отличие от многих других языков, имеющих это ключевое слово).Чтобы сделать этот вызов, сохраняя значение this, вы должны использовать call:

ChildClass.base.functionB.call(this);

..., который явно устанавливает this во время вызова, чтобы быть тем, что вы передаете (this, в данном случае).Подробнее: Мифические методы | Вы должны помнить this


Кстати, если вас интересуют иерархии наследования и выполнение вызовов в родительский объект (я выиграл 'Не говоря уже о «классе», JavaScript не имеет классов), я написал это несколько лет назад: Простые, эффективные Supercalls в JavaScript Он использует терминологию, подобную «классу»,что на самом деле не должно (это всего лишь вспомогательные методы, упрощающие подключение иерархий прототипов наследования), и он предшествует ECMAScript 5 (последняя версия JavaScript), который предлагает некоторые функции, которые будут применяться.Поэтому мне нужно обновить его, но это может быть полезно для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...