Я пишу простую игру платформы с помощью JavaScript и html5. Я использую JavaScript способом OO. Для получения работы наследования, я использую следующее;
// http://www.sitepoint.com/blogs/2006/01/17/javascript-inheritance/
function copyPrototype(descendant, parent) {
var sConstructor = parent.toString();
var aMatch = sConstructor.match(/\s*function (.*)\(/);
if (aMatch != null) { descendant.prototype[aMatch[1]] = parent; }
for (var m in parent.prototype) {
descendant.prototype[m] = parent.prototype[m];
}
};
Ради этого сообщения рассматривают следующий пример;
function A() {
this.Name = 'Class A'
}
A.prototype.PrintName = function () {
alert(this.Name);
}
function B() {
this.A();
}
copyPrototype(B, A);
function C() {
this.B();
}
copyPrototype(C, B);
var instC = new C();
if (instC instanceof A)
alert ('horray!');
Насколько я понимаю я ожидал бы видеть часовое окно предупреждений, потому что C является экземпляром C & B & A.Я неправ? Или я просто использую неправильный метод для проверки? Или имеет copyPrototype измотанный оператор instanceof?
Спасибо как всегда за то, что заняли время для чтения этого!
Shaw.
Хорошо, я нашел решение, которое сохраняет функцию instanceof рабочей, а также позволяет мне передавать параметры конструктора через цепочку наследования. Решение подробно описано здесь; https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Details_of_the_Object_Model - структура моего класса теперь выглядит так;
function A(p) {
this.Position = p || new Vector2d(0,0);
}
function B(p) {
this.base = A;
this.base(p);
}
B.prototype = new A;
function C(p) {
this.base = B;
this.base(p);
}
C.prototype = new B;
if(C instanceof A)
alert (' it worked!! '); // you now see this alert box!
Спасибо CMS за то, что объяснил мне, почему это не работает!!!
Вы можете проверить полный проект (ну, более старую сборку, которая на момент написания статьи еще не видела этот новый OO-метод, введенный полностью) на http://8weekgame.shawson.co.uk/ - просто проверьте мои последние сообщения.
Проблема в том, что функция copyPrototype
копирует только свойства из прототипа конструктора в другой, например, в конце, интенциональная [[Prototype]]
ссылка C. prototype
просто указывает на Object.prototype
.
Цепочка прототипов instC
и прототипов конструктора выглядит так:
[[Prototype]] A.prototype -------------->|-------------------| | | B.prototype -------------->| Object.prototype | ---> null | | C.prototype -------------->|-------------------| ^ | instC
Оператор instanceof
обходит цепочку прототипов, ваш объект instC
, как видите, будет иметь в своей цепочке прототипов только C.prototype
и Object.prototype
.
Вы можете добиться желаемого, установив прототипы конструкторов как экземпляры объектов их "родительских" конструкторов, например:
function A() {
this.Name = 'Class A'
}
A.prototype.PrintName = function () {
alert(this.Name);
}
function B() {
//..
}
B.prototype = new A();
B.prototype.constructor = B; // fix constructor property
function C() {
//..
}
C.prototype = new B();
C.prototype.constructor = C; // fix constructor property
var instC = new C();
if (instC instanceof A)
alert('horray!');
Теперь цепочка прототипов объекта instC
выглядит так:
--------------- --------------- --------------- instC --> | C.prototype | -----> | B.prototype | -----> | A.prototype | --------------- --------------- --------------- | V -------------------- | Object.prototype | -------------------- | V null
Рекомендуемая статья: