вопрос множественного наследования - PullRequest
2 голосов
/ 01 сентября 2011

Я возился с цепочкой прототипов и заметил кое-что, что я не могу объяснить.Я все еще учусь всему этому, так что, вероятно, я допустил ошибку.Я пытаюсь сделать несколько мульти-наследования, как и многие другие.Я заметил, что объект-прототип очень похож на хэш / словарь, подумал я, почему бы не использовать что-то вроде underscore.extend для объединения нескольких объектов-прототипов в один.

function A(){this.value="A";};
A.prototype.funcA = function (){console.log(this.value);}
function B(){this.value="B";};
B.prototype.funcB = function (){console.log(this.value);}

function C(){
  // fix constructor
  this.constructor = C;
  // 'inherit' properties
  A.call(this);
  B.call(this);
};
// gobble up the prototype chains of A and B
C.prototype = new underscore.extend(A.prototype,B.prototype);
C.prototype.funcC = function (){console.log(this.value);}
var c = new C();

> c instanceof C
true
> c instanceof A
true
> c instanceof B
false

Я очень удивлен, когда понял все здесь.Может кто-нибудь объяснить, что здесь происходит?

ОБНОВЛЕНИЕ Я удалил метод расширения подчеркивания из кода, как это было предложено, и это работает намного лучше.спасибо!

function extend(destination, source) {
  for (var property in source) {
    if (source.hasOwnProperty(property)) {
      destination[property] = source[property];
    }
  }
  return destination;
};

function A(){this.value="A";};
A.prototype.funcA = function (){console.log(this.value);}
function B(){this.value="B";};
B.prototype.funcB = function (){console.log(this.value);}

function C(){
  this.constructor = C;
  A.call(this);
  B.call(this);
};
var destination = {};
destination = extend(destination,A.prototype);
destination = extend(destination,B.prototype);
C.prototype = destination;
C.prototype.funcC = function (){console.log(this.value);}
var c = new C();
> c
{ constructor: [Function: C], value: 'B' }
> c instanceof A
false
> c instanceof B
false
> c instanceof C
true

1 Ответ

2 голосов
/ 01 сентября 2011

В JavaScript нет множественного наследования, потому что один объект может иметь только один прототип. Для доказательства достаточно увидеть метод ECMAScript 5 Object.getPrototypeOf, который, конечно, возвращает только одно значение. Для более старых переводчиков вы можете попробовать __proto__ свойство (нестандартное) просто obj.constructor.prototype.

Пример, который вы сделали, дает вам возможность иметь все возможности из двух разных прототипов, однако это тормозит цепочку прототипов - вот почему оператор instanceof возвращает false для A и B. На самом деле прототипы A или B это не прототипы вашего объекта, а их смесь, которую вы создали с помощью функции extend. Имя функции очень вводит в заблуждение (однако такое имя используется некоторыми из фреймворков и библиотек) - потому что мы не расширяем какой-либо объект (в смысле объектно-ориентированного программирования) - мы строим смесь двух объектов - что является совершенно другим дизайном шаблон.

Отказ от темы - если вы экспериментируете с объектами и наследованием прототипов - попробуйте поиграть с методом Object.create (из ECMAScript 5). Это очень полезно в этом случае.

...