ООП Javascript и методы наследования - PullRequest
2 голосов
/ 11 августа 2011

Осенью я беру свой первый урок ООП (изучение Java), поэтому я читал об этом и немного знакомился с языком, чтобы познакомиться перед школой. Я очень рад изучать Java, но чувствую, что я больше «дома» с JavaScript. Я сделал несколько проектов с ним и работаю над переводом моего кода на новый, более профессиональный уровень (если вы хотите это сказать) с помощью ООП в JS.

В настоящее время я работаю над сценарием перетаскивания, и он в значительной степени связан с процедурным программированием. Поскольку этот проект свеж в моей памяти, я начинаю с этого проекта, чтобы начать переход к объектам. Что меня здесь сбивает с толку, так это идея иметь объект Drag. , .

function Drag() {
    /* Drag code goes here */
} // constructor

Я довольно хорошо отношусь к идее ООП, но это ставит меня в тупик. Во всех примерах, которые я прошел, объекты всегда были объектами. Это были животные или машины, или велосипед, и т. Д. Мне еще не приходилось сталкиваться с объектом поведения . Я просто не уверен, как это будет работать. , , Если у кого-нибудь из вас есть какие-либо советы по этому поводу, я буду признателен.

Теперь по наследству! Мне еще не приходилось использовать наследование, но тема меня интересует JavaScript, потому что очень много людей вложили в это свои 2 цента. Я думаю, что наиболее популярные способы, которые я видел, это 1011 * Джона Ресига и Дагласа Крокфорда наследования.

Я думаю, что это очень аккуратные обходные пути, но по какой-то причине мне не очень нравится, что они оба требуют назначения. Я думаю, я просто чувствую, что они не должны работать таким образом. Итак, просмотрев еще несколько примеров и метод Крокфорда, я придумал это (очень жаль, если кто-то еще уже есть, я просто не видел его):

Object.prototype.extend = function (Obj) {
    'use strict'; // for jslint

    this.prototype = new Obj();
    this.prototype.constructor = this;
    return this;
}

Вот пример его использования, я украл пример из здесь , затем немного его изменил:

Object.prototype.inObj = 1;

function A() {
    'use strict';
    this.inA = 2;
}

A.prototype.inAProto = 3;

function B() {
    'use strict';
    this.inB = 4;
}

/*** HERE IT IS ***/
B.extend(A);

B.prototype.inBProto = 5;

var w = new A();
var x = new B();

document.body.innerHTML = x.inObj + ', ' + x.inA + ', ' + x.inAProto + ', ' + x.inB + ', ' + x.inBProto; // 1, 2, 3, 4, 5
document.body.innerHTML += '<br />';
document.body.innerHTML += w instanceof A && w instanceof Object && x instanceof B && x instanceof A && x instanceof Object; // true

Для меня это выглядит и выглядит синтаксически хорошо, мне интересно, как опытные разработчики JS будут относиться к этому. Я проверил это, и я знаю, что вы можете поместить B.extend(A) перед определением для B, но вы не можете поместить его после B.prototype.inBProto, или список станет 1, 2, 3, 4, неопределенным, потому что в extend Метод, прототип B сбрасывается. Я работаю над этим, но чувствую, что B.extend(A) должен прийти сразу после определения Конструктора.

Что вы все думаете об этом? Заранее спасибо!

РЕДАКТИРОВАТЬ: Я разработал [неуклюжий] обходной путь, который в основном берет все свойства прототипа наследуемого объекта, а затем добавляет их обратно после очистки новым объектом:

Object.prototype.extend = function (Obj) {
    'use strict';
    var proto, p;

    proto = {};
    for (p in this.prototype) {
        if (this.prototype.hasOwnProperty(p)) {
            proto[p] = this.prototype[p];
        }
    }

    this.prototype = new Obj();
    this.prototype.constructor = this;

    for (p in proto) {
        if (proto.hasOwnProperty(p)) {
            this.prototype[p] = proto[p];
        }
    }

    return this;
};

Кто знает, возможно, вы не подумаете, что это так же неуклюже, как и я, но это работает, и я думаю, что это довольно круто! :D

1 Ответ

2 голосов
/ 11 августа 2011

Я согласен с Дэниелом, вы никогда не должны расширять базовое ядро ​​JS.

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

Я бы использовал другой подход. Вместо этого для расширения Object сделайте его функцией и используйте apply.

Сделан простой макет: http://jsfiddle.net/djEw8/

Читайте о заявке здесь: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/function/apply

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