Читаем Основы программирования на JavaScript полностью

function Cat(name){ this.name = name; this.species = 'Cat'; this.talk = function(){ alert('Meow!'); } this.callOver = function(){ alert(this.name+' ignores you'); }, this.pet = function(){ alert('Purr!'); } } var felix = new Cat('Felix'); var sam = new Cat('Sam'); var patty = new Cat('Patty'); felix.pet(); // выводит 'Purr!' sam.callOver(); // выводит 'Sam ignores you'. Просто, как кот! alert(patty.species); // выводит 'Cat'

В этом примере создана одна функция Cat, а затем создаются три новых кота с помощью этой функции: Felix, Sam и Patty. Каждый из этих котов имеет одинаковые функции: talk, callOver и pet, и каждая из них имеет свойство species, заданное как 'cat'. И подобно всем котам, они в равной степени своенравны.

Обычно говорят, что felix, sam и patty являются экземплярами одного объекта: Cat. Код самой функции Cat называется конструктором. Мы передаем ей переменную name и используем ее для задания this.name. К сожалению, при объявлении каждой функции Cat в конструкторе в действительности создается новая копия каждой функции всякий раз при создании нового Cat. Так как функции talk, callOver и pet являются идентичными, то нам в действительности требуется только одна копия каждой функции. Здесь на помощь приходит прототипирование.

Можно переписать функцию Cat таким образом, чтобы каждая функция объявлялась только один раз:

function Cat(name){ this.name = name; } Cat.prototype.species = 'Cat'; Cat.prototype.talk = function(){ alert('Meow!'); }; Cat.prototype.callOver = function(){ alert(this.name+' ignores you'); }; Cat.prototype.pet = function(){ alert('Purr!'); };

Синтаксис этого метода немного отличается от предыдущего. Вместо объявления всех свойств и методов внутри функции Cat, они теперь объявляются с помощью Cat.prototype. Это может показаться более сложным, но предлагает много преимуществ. Предположим, например, что надо добавить новую функцию sleep для каждого имеющегося cat. Это можно сделать двумя способами. Первый: можно добавить функцию sleep в felix, sam и patty. Это, однако, не только трудоемко, но также и неэффективно. Если бы имелось 500 cat, то потребовалось бы сначала отследить всех этих 500 котов, а затем добавить функцию каждому cat.

Однако с помощью прототипов можно добавить функцию sleep всем cat одновременно:

Cat.prototype.sleep = function(){ alert(this.name+' falls asleep'); };

Этот способ не только быстрее, но к тому же нам больше не требуется отслеживать каждого cat, чтобы добавить функцию sleep.

Существует более быстрый способ добавления прототипов. С помощью объектного литерала можно одновременно задать любое количество прототипов свойств или методов.

function Cat(name){ this.name = name; } Cat.prototype = { species: 'Cat', talk: function(){ alert('Meow!'); }, callOver: function(){ alert(this.name+' ignores you'); }, pet: function(){ alert('Pet!'); } }

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

Object.prototype.method = function(){ ... }.

Если попробовать теперь добавить в cat метод sleep с помощью этого метода:

Cat.prototype = { sleep: function(){ alert(this.name+' falls asleep'); } }

то предыдущие прототипы, species, talk, callOver и pet, будут все удалены. Единственным имеющимся прототипом для cat будет sleep.

Прототипы можно также использовать для расширения встроенных объектов JavaScript. Можно реализовать, например, функцию String.prototype.reverse, которая будет возвращать любую созданную строку в обратном порядке:

Перейти на страницу:

Похожие книги