Чтение онлайн

на главную - закладки

Жанры

Основы программирования на JavaScript

Кан Марк

Шрифт:

var myArray = [1, 2, 3];

for(n in myArray) alert(n); // выводит 0, 1 и 2 - индексы массива.

Array.prototype.something = function{ };

for(n in myArray) alert(n); // выводит 'something', 0, 1 и 2.

Как можно видеть, здесь выполнено прототипирование Array и добавлена функция something. Однако теперь эта функция something видна как элемент массива, результат, который определенно не ожидался и не требовался. То же самое происходит с объектами и объектными литералами, если выполнить прототипирование Object. Если можно быть абсолютно уверенным, что цикл for-in никогда не будет использоваться и никакой другой разработчик не будет использовать этот код JavaScript, то можно применять прототипирование для Array или Object, но надо помнить о связанных с этим проблемах. Однако существуют другие методы для достижения тех же результатов. Например, для расширения Array можно задействовать следующий метод без прототипирования:

Array.find = function(ary, element){

for(var i=0; i<ary.length; i++){

if(ary[i] == element){

return i;

}

}

return -1;

}

alert(Array.find(['a', 'b', 'c', 'd', 'e'], 'b')); // выводит 1

Как можно видеть, теперь необходимо печатать Array.find(ary, e) вместо ary.find(e), что пришлось бы делать, если прототипировать объект Array, но стоит напечатать эти несколько дополнительных символов, чтобы избежать потери существующей функциональности JavaScript.

Способ определения переменных в объекте определяет, какие методы этого объекта можно использовать для доступа к этим переменным. В JavaScript при работе с объектно-ориентированным кодом используется пять уровней методов и свойств.

1 Скрытая (Private) - объявляется с помощью var variableName или function functionName внутри объекта. Могут быть доступны только другим скрытым или привилегированным функциям.

2 Открытая (Public) - объявляется с помощью this.variableName внутри объекта. Может изменяться любой функцией или методом.

3 Привилегированная (Privileged) - объявляется с помощью this.functionName = function{ ... } внутри объекта. Доступна для любой функции или метода и может обращаться или изменять любую скрытую переменную.

4 Прототипированная (Prototype) - объявляется с помощью Class.prototype.variableName или Class.prototype.functionName. Объявленные таким образом функции будут иметь доступ к любой открытой или прототипированной функции. Попытки изменить созданную таким образом переменную будут вместо этого создавать новую открытую переменную на объекте, а прототипированная переменная будет недоступна.

5 Статическая (Static) - объявляется с помощью Class.variableName или Class.functionName. Может изменяться любой функцией или методом. Такой метод используется редко.

Чтобы понять различия между уровнями, давайте рассмотрим пример:

function Cat(name, color){

/*

Конструктор: при создании объекта выполняется любой находящийся здесь код

*/

Cat.cats++;

/* Скрытые переменные и функции доступны только скрытым или привилегированным

функциям. Отметим, что 'name' и 'color', переданные в Class, уже являются

скрытыми переменными.

*/

var age = 0;

var legs = 4;

function growOlder{

age++;

}

/*

Открытые переменные доступны открыто или скрыто

*/

this.weight = 1;

this.length = 5;

/*

Привилегированные функции доступны открыто или скрыто.

Могут обращаться к скрытым переменным.

Невозможно изменить, можно только заменить открытой версией

*/

this.age = function{

if(age==0) this.length+=20;

growOlder;

this.weight++;

}

}

/*

Прототипированные функции доступны открыто

*/

Cat.prototype = {

talk: function{ alert('Meow!'); },

callOver: function{ alert(this.name+' ignores you'); },

pet: function{ alert('Pet!'); }

}

/*

Прототипированные переменные доступны открыто.

Нельзя перезаписать, только заменить открытой версией

*/

Cat.prototype.species = 'Cat';

/*

Статические переменные и функции доступны открыто

*/

Cat.cats = 0;

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

Лекция 9. Наследование и замыкание

Метод наследования. Полезные (и опасные) свойства замыкания.

В восьмой лекции были рассмотрены основы объектно-ориентированного программирования в JavaScript. В данной лекции эта тема будет продолжена рассмотрением методов наследования, а также полезных (и опасных) свойств замыкания.

В предыдущей лекции была создана функция 'Cat' :

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!'); }

}

Теперь можно создать любое количество котов, но как быть, если мы захотим создать объект другого типа, например, собаку? В этом случае понадобится создать совершенно новую функцию, со своими собственными прототипами. Если два объекта используют одни и те же функции (например, можно было бы добавить функции sleep (спать), eat (есть), и play (играть)), то в результате мы бы имели чрезмерное дублирование кода. Решением является концепция наследования.

Поделиться:
Популярные книги

Белые погоны

Лисина Александра
3. Гибрид
Фантастика:
фэнтези
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Белые погоны

Оживший камень

Кас Маркус
1. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Оживший камень

Воин-Врач

Дмитриев Олег
1. Воин-Врач
Фантастика:
попаданцы
альтернативная история
историческое фэнтези
6.00
рейтинг книги
Воин-Врач

Несгибаемый граф. Тетралогия

Яманов Александр
Нет пророка в своем отечестве
Фантастика:
альтернативная история
фэнтези
5.00
рейтинг книги
Несгибаемый граф. Тетралогия

Газлайтер. Том 29

Володин Григорий Григорьевич
29. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Газлайтер. Том 29

Сильнейший Столп Империи. Книга 1

Ермоленков Алексей
1. Сильнейший Столп Империи
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Сильнейший Столп Империи. Книга 1

Промышленникъ

Кулаков Алексей Иванович
3. Александр Агренев
Приключения:
исторические приключения
9.13
рейтинг книги
Промышленникъ

Дитя прибоя

Трофимов Ерофей
Дитя прибоя
Фантастика:
боевая фантастика
попаданцы
фэнтези
5.00
рейтинг книги
Дитя прибоя

Сопротивление

Осадчук Алексей Витальевич
11. Последняя жизнь
Фантастика:
аниме
фэнтези
попаданцы
7.33
рейтинг книги
Сопротивление

Камень. Книга 4

Минин Станислав
4. Камень
Фантастика:
боевая фантастика
7.77
рейтинг книги
Камень. Книга 4

Пески веков (сборник)

Уиндем Джон Паркс Лукас Бейнон Харрис
1970. Зарубежная фантастика
Фантастика:
научная фантастика
5.00
рейтинг книги
Пески веков (сборник)

Газлайтер. Том 21

Володин Григорий Григорьевич
21. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Газлайтер. Том 21

Цивилизация статуса (сборник)

Шекли Роберт
Сборники Роберта Шекли
Фантастика:
фэнтези
8.22
рейтинг книги
Цивилизация статуса (сборник)

Черный Маг Императора 20

Герда Александр
20. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 20