javascript-прототип наследования и свойства объекта - PullRequest
6 голосов
/ 04 января 2012

Я пытаюсь применить прототипное наследование к функции в Javascript.Это все довольно просто и даже описано в лемме javascript Википедии .Это работает, если мои свойства - простые типы javascript:

function Person() {
    this.age = 0;
    this.location = {
        x: 0,
        y: 0,
        absolute: false
    };
};

function Employee() {};

Employee.prototype = new Person();
Employee.prototype.celebrate = function () {
    this.age++;
}

var pete = new Employee();
pete.age = 5;
pete.celebrate();
var bob = new Employee();
bob.celebrate();
console.log("bob is " + bob.age + " pete is " + pete.age);

При Employee.prototype = new Person(); все свойства Person и (прототип) методы наследуются Employee, что является фундаментальным для наследования.

Thisработает как положено: bob is 1 pete is 6

Теперь я начинаю играть с положением Пита (после празднования)

pete.celebrate();
pete.location.absolute=true;

Отображение bob.location.absolute показывает: true, чтопротиворечит интуитивно (я не трогал местоположение Боба, поэтому я ожидаю, что его начальное значение будет объявлено в Person) и разрушит мое решение.

В моем первоначальном понимании это должно было быть ложным.Я понимаю, что мне, вероятно, следует клонировать объект местоположения от первоначального персонажа, но я не уверен, где и как это сделать.А если есть, может быть, лучшие методы наследования?

Ответы [ 3 ]

3 голосов
/ 04 января 2012

Не запускать конструктор Person при наследовании, Employee не должен даже есть .location, потому что это не в Person.prototype.

function createObject( fn ){
    function f(){}
    f.prototype = fn.prototype;
    return new f;
}

Тогда:

Employee.prototype = createObject( Person );

Это будет наследоваться правильно без побочных эффектов (работает конструктор).

Вы бы запускали родительский конструктор только в дочернем конструкторе:

function Employee() {
Person.apply( this, arguments );
}
3 голосов
/ 04 января 2012

Когда вы создаете экземпляр нового сотрудника, все свойства Person копируются.Поскольку это мелкая копия, Пит и Боб имеют один и тот же объект местоположения.Для вашей проблемы, кажется, не очень хорошее решение.Вы можете использовать фреймворк или взломать, как это:

function Employee() { Person.apply(this); };

Это вызывает конструктор Person в контексте этого объекта.

MDC имеет больше информации об этом:1006 *https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply

0 голосов
/ 04 января 2012

Я столкнулся с подобной проблемой. В итоге я использовал отдельный конструктор для внутреннего объекта.

function engine(cc, fuel) {
       this.cc = cc; 
       this.fuel = fuel
}

function car(type, model, cc, fuel) {
       this.type = type; 
       this.model = model;
       this.engine = new engine(cc, fuel);
}


var mycar = new car("sedan", "toyota corolla", 1500, "gas");
console.log(mycar.type);
//sedan
console.log(mycar.engine.cc);
//1500

Если бы у меня были какие-либо методы на прототипах конструкторов 'engine' или 'car', они все равно были бы доступны. Однако я не выводю класс «автомобиль» из класса «двигатель» в смысле ООП. Мне не нужно было «Двигатель» используется в качестве компонента «автомобиля».

Между тем, для наследования я предпочитаю использовать новые методы, включенные в ECMAScript 5, что означает использование Object.create, Object.defineProperties и т. Д. Они поддерживаются даже в IE9. До этого я использовал тот же метод apply (), предложенный Костой.

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