Объяснение наследования JavaScript было согласовано, но оно было отложено. Без лишних слов, просто доберитесь до сути.
Поскольку вы хотите понять наследование, это доказывает, что у вас уже есть определенное понимание объектно-ориентированного JavaScript. Если вы ничего не понимаете, вы можете ссылаться на основное объяснение объектно-ориентированного JS, заводского режима, режима конструктора, режима прототипа, смешанного режима, динамического режима прототипа ». Далее, давайте поговорим о наследии JavaScript в целом с помощью этих методов.
Прототип цепочка
Самый простой способ реализовать наследование в JavaScript - использовать прототип цепочку и указать прототип типа ребенка на экземпляр родительского типа, то есть «subtype.prototype = new Parent Type ();». Метод реализации выглядит следующим образом:
// Создать функцию конструктора supertype () {this.name = ['wuyuchang', 'jack', 'tim']; this.property = true;} // добавить метод supertype.prototype.getsuerpervalue = function () {return this.property;} // Создать функцию конструктора subtype () {this.test = ['h1', 'h2', 'h3', 'h4']; this.subproperty = false;} // Шаги ключей для реализации наследования, прототип подтипа указывает на экземпляр подтипа родительского типа. Это должно быть после реализации наследования, в противном случае указатель будет указан на экземпляр родительского типа, а метод пуст. Subtype.prototype.getsubvalue = function () {return this.subproperty;}/* Ниже приведен пример тестового кода*/var exancement1 = new subtype (); antain1.name.push ('wyc'); instance1.test.push ('h5'); alert (exance1. // trueAlert (exance1.getSubvalue ()); // FALSEALERT (instance1.name); // Вуючанг, Джек, Тим, Викалерт (ancess1.test); // H1, H2, H3, H4, h5var ancement2 = new subtype (); alert (antaintion2.name); // Вуючанг, Джек, Тим, Викалерт (exance2.test); // H1, H2, H3, H4Вы можете видеть, что приведенный выше код представляет собой простое наследование, реализованное через цепочку прототипа, но в примере тестового кода все еще есть некоторые проблемы. Я полагаю, что после прочтения моего сообщения в блоге «Основное объяснение объектно-ориентированного JS, заводского режима, режима конструктора, режима прототипа, смешанного режима, динамического режима прототипа», я должен знать, что первая проблема с кодом прототипа цепи состоит Ссылка на значение типа будет передаваться всеми экземплярами . Exaction1.name.push ('wyc'); из приведенного выше кода может доказать существование этой проблемы. Вторая проблема с цепочкой прототипа заключается в том, что при создании экземпляра подтипа параметры не могут быть переданы в конструктор супертипа . Поэтому в реальном развитии мы редко используем прототипные цепи.
Заимствовать конструктор
Чтобы решить две проблемы в цепочке прототипов, разработчики начали использовать методику, называемую конструкторами заимствования для решения проблем в цепочке прототипа. Идея реализации этой технологии также довольно проста. Вам нужно только вызвать конструктор родительского типа в конструкторе подтипа. Не забывайте, что функции - это просто объекты, которые выполняют код в определенной среде, поэтому конструкторы могут быть выполнены с помощью метода Apply () или call () . Код заключается в следующем:
// Создать функцию конструктора Supertype (name) {this.name = name; this.color = ['pink', 'желтый']; this.property = true; this.testfun = function () {alert ('http://tools.vevb.com/'); }} // Добавить метод supertype.prototype.getSuerperValue = function () {return this.property;} // Создать функцию конструктора (имя) {supertype.call (this, name); this.test = ['H1', 'H2', 'H3', 'H4']; this.subproperty = false;} // Добавить метод в подтип здесь. Обязательно реализуйте наследование, в противном случае указатель будет указан на экземпляр родительского типа, и метод является пустым подтипом.prototype.getsubvalue = function () {return this.subproperty;}/* следующий пример тестового кода*/var exancem1 = новый подтип (['wuyuchang', 'jack', ' 'Nick']); exaction1.name.push ('hello'); exaction1.test.push ('h5'); antain1.color.push ('blue'); exaction1.testfun (); // http://tools.vevb.com/alert(instance1.name); // Wuyuchang, Jack, Nick, Hello // alert (exaction1.getsuerpervalue ()); // Ошибка Alert (ancess1.test); // H1, H2, H3, H4, H5 Alert (Encaven1.getSubvalue ()); // False Alert (ancome1.color); // розовый, желтый, бродягенный экземпляр2 = новый подтип ('wyc'); antain2.testfun (); // http://tools.vevb.com/alert(instance2.name); // wyc // alert (exance2.getSuerperValue ()); // оповещение об ошибках (ancess2.test); // H1, H2, H3, H4ALERT (ancess2.getSubvalue ()); // falseAlert (exaction2.color); // розовый, желтыйВы можете видеть, что в приведенном выше коде конструктор подтипа подтипа в приведенном выше коде, наследование атрибута реализуется путем вызова родительского типа «supertype.call (это, имя)». Вы также можете передавать параметры родительскому типу при создании подтипа, но появится новая проблема. Вы можете видеть, что я определил метод в конструкторе родительского типа: testfun, и метод в прототипе родительского типа: gesupervalue. Однако после экземпляра подтипа все еще невозможно вызвать метод, определяемый в прототипе родительского типа , и может вызвать только метод конструктора в родительском типе: testfun. Это то же самое, что использование только режима конструктора в создании объектов, так что функция не имеет возможности повторного использования. Принимая во внимание эти проблемы, методы заимствования конструкторов редко используются отдельно.
Комбинация наследования (прототип цепочка + конструктор заимствования)
Как следует из названия, комбинированное наследование представляет собой шаблон, состоящий из преимуществ комбинирования использования прототипов цепочек и конструкторов заимствования. Реализация также очень проста. Поскольку это комбинация, конечно, она объединяет преимущества обеих сторон, а именно метод наследования цепи прототипа, и конструктор наследует атрибуты . Конкретный код реализуется следующим образом:
// Создать функцию конструктора Supertype (name) {this.name = name; this.color = ['pink', 'желтый']; this.property = true; this.testfun = function () {alert ('http://tools.vevb.com/'); }} // Добавить метод supertype.prototype.getSuerperValue = function () {return this.property;} // Создать функцию конструктора (имя) {supertype.call (this, name); this.test = ['H1', 'H2', 'H3', 'H4']; this.subproperty = false;} subtype.prototype = new Supertype (); // Добавить метод в подтип здесь. Это должно быть после наследства, в противном случае указатель будет указан на экземпляр родительского типа, а метод является пустым подтипом.prototype.getsubvalue = function () {return this.subproperty;}/* Пример тестового кода*/var ancement1 = новый подтип (['wuyuchan 'Nick']); exaction1.name.push ('hello'); exaction1.test.push ('h5'); antain1.color.push ('blue'); exaction1.testfun (); // http://tools.vevb.com/alert(instance1.name); // Wuyuchang, Jack, Nick, HelloAlert (Encason1.getSuerperValue ()); // trueAlert (ancome1.test); // H1, H2, H3, H4, H5 Alert (Encaven1.getSubvalue ()); // False Alert (ancome1.color); // розовый, желтый, бродягенный экземпляр2 = новый подтип ('wyc'); antain2.testfun (); // http://tools.vevb.com/alert(instance2.name); // wyc alert (exaction2.getSuerperValue ()); // trueAlert (ancess2.test); // H1, H2, H3, H4ALERT (ancess2.getSubvalue ()); // falseAlert (exaction2.color); // розовый, желтыйПриведенный выше код наследует свойства родительского типа через supertype.call (это, имя); и наследует методы родительского типа через подтип.prototype = new Supertype ();. Приведенный выше код удобно решает проблемы, с которыми сталкиваются прототипные цепочки и конструкторы заимствования, и стал наиболее часто используемым методом наследования экземпляра в JavaScript. Тем не менее, смешанный режим не без недостатков. Можно видеть, что в приведенном выше коде атрибуты родительского типа фактически были унаследованы при наследстве метода. Однако в настоящее время тип ссылки используется. Следовательно, конструктор родительского типа вызывается в конструкторе типа ребенка после подтипа, тем самым наследуя атрибуты родительского типа, чтобы перезаписать унаследованные атрибуты в прототипе. Очевидно, нет необходимости вызывать конструктор дважды, но есть ли способ решить его? При решении этой проблемы сначала посмотрите на следующие два режима.
Прототип наследование
Метод реализации прототипа наследования отличается от метода обычного наследования. Прототип наследование не использует конструктор в строгом смысле, а вместо этого использует прототип для создания новых объектов на основе существующих объектов, и в результате нет необходимости создавать пользовательские типы. Конкретный код заключается в следующем:
функция объекта (O) {function f () {} f.prototype = o; вернуть новое f ();}Пример кода:
/* Прототип наследование*/функция объекта (o) {function f () {} f.prototype = o; вернуть новое f ();} var person = {name: 'wuyuchang', друзья: ['wyc', 'nicholas', 'tim']} var oreperson = object (человек); sitherperson.name = 'greg'; sitherperson.friends.push ('bob'); var oreverperson2 = object (человек); sitherperson2.name = 'jack'; ishonperson2.friends.push ('rose'); alert (person.friends); // WYC, Николас, Тим, Боб, РоузПаразитическое наследование
/* Паразитное наследование*/функция Createanother (Original) {var clone = object (Original); clone.sayhi = function () {alert ('hi'); } return Clone;}Пример использования:
/* Прототип наследование*/функция объекта (o) {function f () {} f.prototype = o; вернуть новое f ();} /* Паразитическое наследование* /function createanother (Original) {var clone = object (Original); clone.sayhi = function () {alert ('hi'); } return Clone;} var person = {name: 'wuyuchang', друзья: ['wyc', 'nicholas', 'rose']} var oreverperson = createanother (человек); sitherperson.sayhi ();Паразитарная комбинация наследования
Ранее я упоминал о недостатках реализации наследства комбинированной паттерны в JavaScript. Теперь давайте решим его недостатки. Идея реализации состоит в том, чтобы унаследовать атрибуты для конструкторов, а метод наследования смешанной формы цепочки прототипа не нуждается в создании создания конструктора родительского типа при наследстве метода. Код заключается в следующем:
функция объекта (O) {function f () {} f.prototype = o; вернуть новое f ();}/* Паразитарная комбинация наследование*/Функция inheritPrototype (subtype, supertype) {var prototype = object (supertype.prototype); prototype.constructor = subtype; subtype.prototype = prototype;}При его использовании вам нужно только заменить строку кода «subtype.prototype = new Supertype ();»; в комбинированном режиме с inheritprototype (подтип, супертип);. Эффективность паразитического комбинаторного наследования отражается в том, что оно называет конструктор родительского типа только один раз, избегая создания ненужных или избыточных свойств. В то же время цепочка прототипа может оставаться неизменной, поэтому экземпляр и iSprototypeof () также можно использовать нормально. Это также самый идеальный метод наследования в настоящее время, и в настоящее время он трансформируется в эту модель. (Юи также использует этот режим.)
Этот пост в блоге относится к «JavaScript Advanced Programming 3 -е издание». Код переписан и более конкретный, и прокомментирован, чтобы облегчить понимание каждого. Если у вас есть уникальное понимание наследства JS, не будьте скупы. Ответьте на свое мнение для вашего ссылки!