Хотя JavaScript является объектно-ориентированным языком, его механизм наследования отличался от других традиционных объектно-ориентированных языков с момента его создания. Это механизм наследования на основе прототипа. Однако в соответствии с этим механизмом все еще существуют некоторые различные методы реализации для наследования.
Метод 1: Классическое наследование
Так называемое наследство класса относится к имитации метода наследования традиционных объектно-ориентированных языков. И наследство, и унаследованные стороны - «классы». Код заключается в следующем:
Сначала определите родительский класс (или Superclass):
Функция человека (имя) {this.name = name; } Person.prototype.getName = function () {return this.name; };Атрибуты материнского класса определены в конструкторе, что может гарантировать, что атрибут имени подкласса наследует, он не разделяет этот атрибут с ним, но принадлежит подклассу отдельно. Метод getName установлен на прототипе, чтобы позволить нескольким экземплярам подкласса унаследовать его, чтобы поделиться этим телом метода, чтобы память была сохранена (для нескольких случаев каждый раз, когда выходит экземпляр нового пространства, он гарантирует, что метод GetName в этих случаях относится к тому же пространству памяти, а не к независимому пространству).
Определите метод наследования расширяться следующим образом:
функция Extend (subclass, superclass) {var f = function () {}; F.prototype = superclass.prototype; subclass.prototype = new f (); subclass.prototype.constructor = subclass; subclass.superclass = superclass.prototype; if (superclass.prototype.constructor == object.prototype.constructor) {superclass.prototype.constructor = superclass; }}В этом методе сначала создайте новый класс F, пусть его прототип будет прототипом родительского класса, и пусть прототип подкласса точки будет в экземпляр класса F, тем самым достигая цели унаследования родительского класса. В то же время, поскольку прототип подкласса модифицируется, атрибут конструктора модифицированного прототипа указывает на подкласс, так что он имеет функцию конструктора, и в то же время подкласс может установить атрибут SuperClass. Подкласс может вызвать родительский класс через это свойство, установив таким образом отношения между подклассом и родительским классом.
Определите автора подкласса, чтобы унаследовать родительского класса, следующим образом:
Автор функции (name, books) {author.superclass.constructor.call (это, имя); this.book = книги; } extend (автор, человек); Author.prototype.getbooks = function () {return this.book; }Здесь конструктор родительского класса вызывается через его атрибут Superclass в конструкторе подкласса. В то же время метод вызова используется для преобразования этого указателя вызова метода, так что автор подкласса также имеет (наследует) свойства родительского класса, а подкласс также имеет свою собственную книгу атрибутов. Следовательно, книги параметров присваиваются книге атрибутов в конструкторе для достижения цели строительства. Используйте функцию Extend, чтобы унаследовать свойства и методы на прототипе личности родительского класса (на самом деле, только методы наследуют, потому что мы просто установили методы к прототипу ранее, и свойства определяются в конструкторе). В то же время у автора есть свой собственный метод GetBooks, устанавливая его на соответствующий прототип, достигая цели дальнейшего развития себя на основе наследования.
Этот метод наследования, очевидно, является типом наследством, аналогичным традиционному объектно-ориентированному языку. Преимущество заключается в том, что программисты легко привыкли к традиционной объектно-ориентированной концепции. Недостатком является то, что процесс является относительно громоздким, а потребление памяти немного больше, потому что подкласс также имеет свой собственный конструктор и прототип, а атрибуты подкласса и родительский класс полностью изолированы. Даже если они имеют одинаковое значение, они не могут разделить одну и ту же память.
Метод 2: Прототип наследование
Во -первых, определить родительский класс. Здесь мы не будем намеренно подражать использованию конструкторов для его определения, но напрямую определяем объект в форме литералов объекта, который является родительским классом
var person = {name: 'имя по умолчанию', getName: function () {return this.name; }};Как и первый метод, у объекта есть имя свойства и метод GetName.
Затем определите метод клонирования для реализации наследования подкласса для родительского класса следующим образом:
Функция клона (obj) {function f () {} f.prototype = obj; вернуть новый f (); }Метод клонирования создает новый объект, указывает прототип объекта в родительский класс, то есть параметр obj и одновременно возвращает объект.
Наконец, подкласс наследует родительский класс через функцию клонирования следующим образом:
var автор = клон (человек); Автор.book = ['javaScript']; Author.showbook = function () {return this.book; }Здесь определяется подкласс, и родительский класс унаследован благодаря функции клона, и книга атрибутов расширяется, и выставка метода расширяется. Здесь подкласс также имеет имя атрибута, но он такой же, как и имя имени родительского класса, поэтому оно не переопределено. Если он отличается, вы можете использовать его.
Author.name = 'Новое имя'; Перезаписать это свойство, чтобы получить новое значение атрибута имени подкласса.
Этот прототип наследование проще и естественнее, чем наследование класса. В то же время, если атрибуты подкласса и значения атрибутов родительского класса одинаковы и могут быть изменены, то они фактически имеют одно и то же пространство памяти. Например, атрибут названия выше трудно понять для программистов, которые привыкли к традиционным объектно-ориентированным программам. Если они должны быть выбраны, этот метод, несомненно, лучше.
Поскольку JavaScript использует подход, основанный на прототипах, для реализации наследования, а прототип каждого объекта может указывать только на экземпляр конкретного класса (не для нескольких случаев), как реализовать множественное наследство (то есть пусть класс есть методы и атрибуты нескольких классов одновременно и не определяет эти методы и атрибуты сами)?
В шаблоне дизайна JavaScript дается класс Mixin:
Во -первых, определите допинг класс, чтобы сохранить некоторые часто используемые методы и атрибуты. Эти методы и атрибуты могут быть добавлены в любой другой класс посредством расширения, так что добавленный класс имеет определенные методы и атрибуты класса. Если несколько классов допинга определяются и добавляются в класс одновременно, то класс косвенно реализует «множественное наследование». Основываясь на этой идее, реализация следующая:
Определение класса доминантного элемента:
var mixin = function () {}; Mixin.prototype = {serialize: function () {var output = []; для (ключ в этом) {output.push (key+":"+this [key]); } return output.join (','); }}Класс допинга имеет метод сериализации, используемый для самого прохождения, вывода своих собственных атрибутов и значений атрибутов и возвращает их в виде строк, разделенных запятыми.
Определите метод расширения, чтобы сделать класс, иметь атрибуты или методы многогруппового класса после расширения следующим образом:
Функция увеличения (deceiveClass, withclass) {if (аргументы [2])) {for (var i = 2, len = arguments.length; i <len; i ++) {eceivingclass.prototype [arguments [i]] = guideclass.prototype [аргументы [i]]; }} else {for (methodname in givesclass.prototype) {if (! deceiveClass.prototype [methodname]) {receivingclass.prototype [methodname] = givingclass.prototype [methodname]; }}}}Этот метод имеет два параметра по умолчанию. Первый параметр принимает расширенный класс, второй параметр - это легированный класс (используемый для расширения других классов), и могут быть и другие параметры. Если это больше двух параметров, последующими параметрами являются имена методов или атрибутов, которые используются для обозначения того, что расширенный класс хочет унаследовать указанные атрибуты или методы легированного класса. В противном случае все атрибуты и методы легированного класса унаследованы по умолчанию. В этой функции первая ветвь используется для наследования указанных атрибутов и методов, а ветвь Else - это тот случай, когда все атрибуты и методы наследуются по умолчанию. Суть этого метода состоит в том, чтобы расширить (добавить) свойства и методы на прототипе класса легирования элемента на прототип расширенного класса, так что он обладает свойствами и методами класса легирования элемента.
Наконец, используйте метод расширения для достижения множественного наследования
дополнение (автор, миксин); var Author = новый автор ('JS', ['javaScript Design Patterns']); Alert (Author.Serialize ());Вот класс автора. Этот класс наследует от родительского класса человека, а также обладает методами и свойствами метаболизированного класса Mixin. Если вы хотите, вы можете определить N Метаболизированные классы для расширения класса. Он также может наследовать свойства и методы других метаболизированных классов, которые вы определяете, так что реализовано множественное наследство. Наконец, результат операции метода сериализации автора заключается в следующем:
Вы обнаружите, что в этом классе есть как свойства, так и методы класса человека, класса автора и класса Mixin. Свойства и методы человека и микшина получаются посредством «наследования». На самом деле, это осознает множественное наследство.