Аргументы
Свойства общие для всего класса должны устанавливаться в прототипе класса. Но тогда зачем нужен тот кусок кода, который запускается, когда мы создаём экземпляр? В предыдущих иллюстрациях мы использовали этот блок для установления значений в экземплярах, но значения эти были постоянные, одни и те же для всех экземпляров. Но ведь если для всех экземпляров они одинаковы, то, скорее всего, они принадлежат классу, именно поэтому мы переместили свойство legs в прототип. Если бы всё, что мы могли делать с этим блоком кода, ограничивалось установлением постоянных значений, тогда его употребление было бы действительно весьма неэффективным и малоупотребимым. К счастью, как вам должно быть уже известно, можно передавать значения функциям (а значит и классам). Это нужно, чтобы иметь возможность вызывать класс каждый раз по-разному. Вызов классу приходит от будущего экземпляра, а значит, он сам знает, что ему нужно. Следующая иллюстрация может показаться похожей на стандартную функцию, но давайте рассмотрим её, как процесс создания объекта - безымянного контейнера, с прикреплёнными к нему свойствами впоследствии назначаемого другому свойству. Заметьте также, что этот новый объект унаследует свойства от прототипа класса.
Dog = function( age, hair ) { this.age = age; this.hair = hair; } Dog.prototype.legs = 4;
rover = new Dog( 6, "shaggy" ); fido = new Dog( 4, "puffy" ); yeller = new Dog( 12, "gray" );
Здесь есть несколько вещей достойных внимания. Во-первых, отметьте, что имена аргументов идентичны именам, назначаемым свойствам экземпляра (this.age = age). Возможно вы скажете, что дабы избежать конфликтов имён, было бы лучше использовать такие имена аргументов, как, например passedAge и passedHair. Однако, если получше разобраться, мы увидим, что это необязательно. this.age ссылается на свойство age в экземпляре. Тогда как само по себе age ссылается на свойство age в объекте активации (точнее в его части {...}). Мы знаем, что установление var age = 6 внутри этого блока кода перезапишет аргумент age, но не перезапишет this.age. Очень важно понимать и отличать эти именные пространства. Попробуйте теперь составить несколько своих примеров, если вам надоели мои.
Другой немаловажный и почти очевидный факт, это то, что аргументы назначаются только в соответствии с их расположением и ни с чем другим. Если мы передадим верхнему классу Dog два свойства: hair и age *именно в таком порядке*, то этот порядок не будет изменён, даже если ваш класс использует те же имена (age и hair). Аргумент age всегда получает первое переданное значение, аргумент hair, всегда второе. Вот пример, основанный на старом мультике (тут я, признаться, обязан кое-чем Джиму Юнгеру!)
marylin = new Date(36,22,35); bridgette = new Date(38,23,36); herman = new BlindDate(42,18,37);
но когда вы рассматриваете классы:
function Date( bust, waist, hips ) { this.bust = bust; this.waist = waist; this.hips = hips; }
пока что всё великолепно...
function BlindDate( age, IQ, shoeSize ) { // uh ohhh... this.age = age; this.IQ = IQ; this.shoeSize = shoeSize; }
... очевидно, что класс получает только значения и класс же решает, что эти значения означают, простите за каламбур (!).
Последнее, о чём стОит упомянуть - тот факт, что при передаче происходит сортировка "по значению". Таким образом, аргументы представляют только значение того, что было передано, а не изначальное имя или объект. Разумеется, если мы передаём объект, как значение, то изменения, произошедшие с ним, будут отражены в объекте. Суть в том, что только значения играют роль. Посмотрите на следующий (не вполне объектно-ориентированный) код:
function test(arg1, arg2) { arg1 = "changed"; arg2.prop2 = 6; } arg1 = "original"; arg2 = { prop1:5 } test( arg1, arg2 );
trace( arg1 ); // "original" - не изменился trace( arg2.prop1 +" & "+ arg2.prop2 ); // 5 & 6 - prop2 был добавлен к объекту
Функция получает только значение того, что передано, а не исходный объект. Это также относится и к классам и к методам (о последних мы скоро поговорим).
Итак, подводя итоги, можно сказать, что экземпляр, вызывающий класс должен проверить класс на предмет того, какие аргументы ему (классу) нужны и в каком порядке. При передаче аргументы сортируются в соответствии с их значением. Аргументов мы коснёмся более детально в дальнейшем, при рассмотрении массива аргументов.
<<
ООП во Flash 5 >>