Wiki-учебник по веб-технологиям: JavaScript/СозданиеНовыхОбъектов ...

Главная | |

Создание новых объектов

Оглавление документа

В JavaScript есть несколько предопределённых объектов. Кроме того, вы можете создать ваши собственные объекты. В JavaScript 1.2 и позднее вы можете создать объект, используя инициализатор объекта. Альтернативно, вы можете сначала создать конструктор функции, а затем – инстанциировать объект (создать экземпляр), используя эту функцию и оператор new.

1. Использование инициализаторов объектов


Помимо создания объектов с использованием конструктора функции, вы можете создать объекты, используя инициализаторы объектов. Использование инициализаторов иногда называется созданием объектов в литеральной нотации. «Инициализатор Объекта» следует терминологии C++.

Синтаксис объекта, использующего инициализатор, таков:

объектаИмя = {свойство1:значение1, свойство2:значение2,..., свойствоN:значениеN}

где объектаИмя это имя нового объекта, каждое свойствоI является идентификатором (именем, числом или строковым литералом), а каждое значениеI является выражением, значение которого присваивается свойствуI.

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

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

Следующий оператор создаёт объект и присваивает его переменной x, если, и только если, выражение cond будет true:

if (cond) x = {hi:"there"}


Следующий пример создаёт myHonda с тремя свойствами. Обратите внимание, что свойство engine также является объектом со своими собственными свойствами.

myHonda = {color:"red",wheels:4,engine:{cylinders:4,size:2.2}}


Вы можете также использовать инициализаторы объектов для создания массивов.

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

2. Использование конструктора функции


Альтернативно вы можете создать объект в два этапа:

1. Определить тип объекта, написав конструктор функции.

2. Создав экземпляр объекта с помощью оператора new.

Чтобы определить тип объекта, создайте функцию для типа объекта, которая специфицирует его имя, свойства и методы. Например, предположим, вы хотите создать тип объекта для автомобилей и назвать его car, и чтобы он имел свойства make, model, year и color. Для этого нужно написать такую функцию:

function car(make, model, year) {
   this.make = make;
   this.model = model;
   this.year = year;
}


Обратите внимание на использование this для присвоения значений свойствам объекта на базе значений, передаваемых в эту функцию.

Теперь можно создать объект с названием mycar:

mycar = new car("Eagle", "Talon TSi", 1993);


Этот оператор создаёт объект mycar и присваивает его свойствам специфицированные значения. Теперь значением свойства mycar.make является строка “Eagle”, значением свойства mycar.year – целое число 1993 и так далее.

Можно создать любое количество объектов car с помощью оператора new. Например,

kenscar = new car("Nissan", "300ZX", 1992);
vpgscar = new car("Mazda", "Miata", 1990);


Объект может иметь свойство, которое само является объектом. Например, предположим, вы определяете объект person:

function person(name, age, sex) {
   this.name = name
   this.age = age
   this.sex = sex
}


и затем инстанциируете два новых объекта person:

rand = new person("Rand McKinnon", 33, "M");
ken = new person("Ken Jones", 39, "M");


Затем вы можете переписать определение car, чтобы включить свойство owner, принимаемое объектом person:

function car(make, model, year, owner) {
   this.make = make;
   this.model = model;
   this.year = year;
   this.owner = owner
}


Для создания новых экземпляров вы теперь используете:

car1 = new car("Eagle", "Talon TSi", 1993, rand);
car2 = new car("Nissan", "300ZX", 1992, ken);


Заметьте, что теперь, вместо передачи литеральной строки или целочисленного значения при создании новых объектов, вышеприведённые операторы передают rand и ken как аргументы свойства owner. Теперь, чтобы определить имя владельца машины car2, вы осуществляете доступ к свойству:

car2.owner.name


Заметьте, что таким образом вы всегда добавляете свойство к ранее определённому объекту. Например, оператор

car1.color = "black"


добавляет свойство color объекту car1 и присваивает ему значение “black”. Однако это не влияет на другие объекты. Чтобы добавить новое свойство ко всем объектам того же типа, вы должны добавить свойство в определение типа объекта car.

3. Индексирование свойств объекта


В JavaScript 1.0 вы можете ссылаться на свойства объектов по имени свойства или по порядковому индексу. В JavaScript 1.1 и позднее, однако, если вы первоначально определили свойство по имени, вы всегда обязаны будете обращаться к нему по имени, и, если вы первоначально определили свойство по индексу, вы всегда обязаны будете обращаться к нему по его индексу.

Это применимо при создании объекта и его свойств с помощью конструктора функции, как в примере с типом объекта Car, и если вы определяете отдельные свойства явным образом (например, myCar.color = “red”). Так, если вы определили свойства объекта по индексу, как, например, myCar[5] = “25 mpg”, вы можете затем обращаться к этому свойству только как myCar[5].

Исключением из этого правила являются объекты, отражённые из HTML, такие как массивы форм. Вы всегда обращаетесь к этим объектам по порядковому номеру (зависящим от местонахождения объекта в документе) или по их именам (если они определены). Например, если второй тэг <FORM> в документе имеет в атрибуте NAME значение “myForm”, вы можете ссылаться на форму document.forms[1], или document.forms["myForm”] или document.myForm.

4. Определение свойств для типа объекта


Вы можете добавлять свойство к ранее определённому типу объекта через использование свойства prototype. Так определяется свойство, которое совместно используется всеми объектами специфицированного типа, а не только одним данным экземпляром этого объекта. Следующий код добавляет свойство color ко всем объекта типа car, а затем присваивает значение свойству color объекта car1.

Car.prototype.color=null;
car1.color="black";


5. Определение методов


Метод это функция, ассоциированная с объектом. Метод определяется так же, как стандартная функция. Затем используется следующий синтаксис для ассоциирования функции с уже существующим объектом:

object.methodname = function_name

где object это существующий объект, methodname это имя определяемого вами метода, а function_name имя функции.

Вы затем вызываете метод в контексте объекта:

object.methodname(params);


Вы можете также определить методы для типа объекта, включив определение метода в конструктор функции. Можно определить функцию, которая форматирует и отображает свойства ранее определённых car-объектов; например,

function displayCar() {
   var result = "A Beautiful " + this.year + " " + this.make
      + " " + this.model;
   pretty_print(result);
}

где pretty_print это функция для отображения горизонтальной линии и строки. Обратите внимание на использование this для ссылки на объект, которому принадлежат методы.

Можно сделать эту функцию методом в car, добавив оператор:

this.displayCar = displayCar;


к определению объекта. Так полное определение car будет выглядеть теперь:

function car(make, model, year, owner) {
   this.make = make;
   this.model = model;
   this.year = year;
   this.owner = owner;
   this.displayCar = displayCar;
}


Теперь вы можете вызвать метод displayCar в каждом экземпляре:

car1.displayCar()
car2.displayCar()


Это даст результат, показанный на рисунке.



6. Использование слова this для ссылок на объекте


JavaScript имеет специальное ключевое слово this, которое может использоваться внутри метода для ссылки на текущий объект. Например, если у вас имеется функция validate, проверяющая значение свойства объекта и значения high и low:

function validate(obj, lowval, hival) {
   if ((obj.value < lowval) || (obj.value > hival))
      alert("Invalid Value!")
}

то вы можете вызвать validate в обработчике события onChange любого элемента формы, используя thisдля передачи обработчику элемента формы, как в этом примере:

<INPUT TYPE="text" NAME="age" SIZE=3
   onChange="validate(this, 18, 99)">


В общем, this ссылается в методе на вызывающий объект.

В сочетании со свойством формы, this может обращаться к родительской форме текущего объекта. В следующем примере форма myForm содержит Text-объект и кнопку. Если пользователь щёлкает на кнопке, значением Text-объекта становится имя формы. Обработчик нажатия кнопки onClick использует this.form для ссылки на родительскую форму, myForm.

<FORM NAME="myForm">
Form name:<INPUT TYPE="text" NAME="text1" VALUE="Beluga">
<P>
<INPUT NAME="button1" TYPE="button" VALUE="Show Form Name"
   onClick="this.form.text1.value=this.form.name">
</FORM>



7. Определение Getter'ов и Setter'ов


Getter это метод, получающий значение отдельного свойства. Setter это метод, устанавливающий значение отдельного свойства. Вы можете определить getter и setter в любом предопределённом объекте ядра или в пользовательском объекте, поддерживающем добавление новых свойств. Синтаксис определения getter и setter использует синтаксис литерала объекта.

Следующая сессия JS-оболочки иллюстрирует, как getter и setter могут работать для определённого пользователем объекта o. JS-оболочка является приложением, позволяющим разработчикам тестировать код JavaScript в пакетном режиме или интерактивно.

Свойствами объекта о являются:


js> o = new Object;
      [object Object]
      js> o = {a:7, get b() {return this.a+1; }, set c(x) {this.a = x/2}};
      [object Object]
      js> o.a
      7
      js> o.b
      8
      js> o.c = 50
      js> o.a
      25
      js>

Эта сессия JavaScript иллюстрирует то, как getter и setter могут расширять прототип Date, добавляя свойство year ко всем экземплярам предопределённого класса Date. Она использует существующие методы getFullYear и setFullYear класса Date для поддержки getter и setter свойства year.

Эти операторы определяют getter и setter для свойства year:

js> var d = Date.prototype;
js> d.year getter= function() { return this.getFullYear(); };
 
js> d.year setter= function(y) { return this.setFullYear(y); };


Следующие операторы используют getter и setter в Date-объекте:

js> var now = new Date;
js> print(now.year);
2000
js> now.year=2001;
987617605170
js> print(now);
Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001


8. Удаление свойств


Вы можете удалить свойство оператором delete. Этот код показывает, как удалить свойство.

//Создаётся новое свойство myobj с двумя свойствами a и b.
myobj = new Object;
myobj.a=5;
myobj.b=12;
//Удаляется свойство a, и в myobj остаётся только свойство b.
delete myobj.a;


Можно также использовать delete для удаления глобальной переменной, если ключевое слово var не было использовано при объявлении этой переменной:

g = 17;
delete g;