Работа с объектами в Javascript просмотров: 2192
Работа с объектами в Javascript
Работа с объектами
JavaScript основан на простой объектной парадигме. Объект это - набор свойств, свойство - ассоциация между именем и значением. Значение свойства может быть функцией, когда свойство объявлено как метод. В дополнение к объектам, которые предопределены в браузере, Вы так же можете создавать свои собственные объекты.
Краткий обзор объектов
Объекты в JavaScript так же как и во многих других языках программирования, можно сравнить с предметами из реальной жизни. Понять термин «объект» в JavaScript можно с помощью сравнения с материальными объектами.
В JavaScript объект это самостоятельная структура со свойствами и типом. Давайте равним его с чашкой: чашка - объект со свойствами. Чашка обладает такими свойствами как: цвет, дизайн, вес, материал и т.д. У объектов в JavaScript тоже могут быть свойства, которые определяют их характеристики.
Объекты и их свойства
У объектов в языке JavaScript есть свойства. Свойство объекта задаётся как переменная, которая присоединена к объекту. Объектные свойства это почти тоже самое, что и переменные JavaScript, за исключением того, что они присоединены к объектам. Свойства объекта определяют его характеристики . Вы получаете доступ к свойствам объекта с помощью записи через точку:
objectName.propertyName
Как и все переменные в языке JavaScript, имя объекта и имя его свойства чувствительны к регистру. Можно задать свойство, присвоив ему значение. Для примера создадим объект, с именем myCar и зададим ему свойства: make, model, и year.
var myCar = new Object();
myCar.make = "Ford";
myCar.model = "Mustang";
myCar.year = 1969;
К свойствам объектов JavaScript можно также получить доступ используя квадратные скобки . Объекты иногда называют ассоциативными массивами, так как каждое свойство связано со строчным значением, которое может использоваться, чтобы получить доступ к объекту. Так, например, можно получить доступ к свойствам объекта myCar следующим образом:
myCar["make"] = "Ford";
myCar["model"] = "Mustang";
myCar["year"] = 1969;
Имя свойства внутри объекта может быть любой допустимой в Javascript строкой
или чем-либо, что может быть преобразовано в строку, включая пустую строку. Однако, к любому имени свойства, которое в Javascript не является допустимым идентификатором (например, имя свойства, в котором есть пробел или дефис, или которое начинается с цифры) можно получить доступ только используя квадратные скобки. Этот метод так же применим , когда имена свойства должны быть динамически определены (когда имя свойства не определяется до времени выполнения). Примеры :
var myObj = new Object(),
str = "myString",
rand = Math.random(),
obj = new Object();
myObj.type = "Точечный синтаксис";
myObj["date created"] = "Строка с пробелом";
myObj[str] = "Строковое значение";
myObj[rand] = "Случайное число";
myObj[obj] = "Объект";
myObj[""] = "Пустая строка";
console.log(myObj);
Также можно получить доступ к свойствам при использовании строкового значения, которое сохранено в переменной:
var propertyName = "make";
myCar[propertyName] = "Ford";
propertyName = "model";
myCar[propertyName] = "Mustang";
Вы так же можете использовать квадратные скобки вместе с for...in чтобы перебрать все свойства объекта. Чтобы пояснять, как это работает, следующая функция выводит на экран свойства объекта, если вы передаете объект и имя объекта в качестве параметров функции:
function showProps(obj, objName) {
var result = "";
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
result += objName + "." + i + " = " + obj[i] + "
";
}
}
return result;
}
Таким образом функцияl showProps(myCar, "myCar") вернёт :
myCar.make = Ford
myCar.model = Mustang
myCar.year = 1969
Всё вокруг – объекты
В JavaScript почти все является объектами. Все типы примитивных данных, кроме null и undefined обрабатываются как объекты. Они могут быть присвоенными свойствами (присвоенные свойства некоторых типов не являются устойчивыми), и у них есть все характеристики объектов.
Перечисление всех свойств объекта
Начиная с ECMAScript 5, есть три способа перечислить свойства объекта:
- for…in циклы:
Этот метод перебирает все счетные свойства объекта и его цепочки прототипов - Object.keys (o)
Этот метод возвращает массив со всем собственным (не в цепочке прототипов) имена счетных свойств ("ключей ") объекта(о). - Object.getOwnPropertyNames (o)
Этот метод возвращает массив, содержащий имена всех собственных свойств (счетныx или нет) объекта(о).
ДО ECMAScript 5, не было простого способа перечислить все свойства объекта. Однако, это может быть достигнуто с помощью следующих функций:
function listAllProperties(o){
var objectToInspect;
var result = [];
for(objectToInspect = o; objectToInspect !== null; objectToInspect = Object.getPrototypeOf(objectToInspect)){
result = result.concat(Object.getOwnPropertyNames(objectToInspect));
}
return result;
}
Это может быть нужно, чтобы получить доступ к "спрятанным" свойствм (свойства в цепи прототипа, которые не доступны через объект, потому что у другого свойства есть то же самое имя ранее в цепи прототипа). Перечисление доступных свойств может быть сделано посредством удаления дублей в массиве.
Создание новых объектов
В JavaScript есть много предопределенных объектов. Кроме того, можно создавать свои собственные объекты. В JavaScript 1.2 и позже, можно создать объект, используя объектный инициализатор. Либо, можно сначала создать функцию конструктора и затем инстанцировать объект, используя ту функцию и оператор new.
Использование объектных инициализаторов
В дополнение к созданию объектов, используя функцию конструктора, можно создать объекты, используя объектный инициализатор. Использование объектных инициализаторов иногда упоминается как создание объектов с помощью литеральной нотации. "Объектный инициализатор" соответствует терминологии, которая используется в C++.
Синтаксис для объекта, с использованием объектного инициализатора:
var obj = { property_1: value_1, // property_# может быть идентификатором...
2: value_2, // или числом...
// ...,
"property n": value_n }; // или строкой
где obj это имя нового объекта, каждый property_i это идентификатор (имя, число, или строка),и каждый value_i это выражение, значение которого присваивается property_i. Объявление имени obj и присваивание не всегда обязательно; если вам не нужно обращаться к этому объекту в другом месте, лучше не объявлять его в качестве переменной . (Может понадобится записать объектный литерал в круглых скобках , если объект появляется там где ожидается оператор , чтобы не перепутать литерал с оператором блока.)
Если объект создается объектным инициализатором в высокоуровневом сценарии, JavaScript интерпретирует объект каждый раз, когда объект оценивает выражение, содержащее объектный литерал. Кроме того, инициализатор, используемый в функции, создается каждый раз, когда функция вызывается.
Следующий оператор создает объект и присваивает его переменной x если и только если выражение cond истина:
if (cond) var x = {hi: "there"};
Следующий пример создает myHonda с тремя свойствами. Заметьте, что свойство engine является также объектом со своими собственными свойствами.
var myHonda = {color: "red", wheels: 4, engine: {cylinders: 4, size: 2.2}};
Можно также использовать объектные инициализаторы, чтобы создать массивы. См.литералы массива.
В JavaScript 1.1 и ранее, нет возможности использовать объектные инициализаторы. Можно создать объекты используя функцию конструктора или используя функцию, предоставленнуюдругим с этой целью другим объектом. См. Использование функции конструктора.
Использование функции конструктора
Так же вы можете создать объект следующими способами:
- Определите тип объекта используя функцию конструктора.Среди программистов принято писать название со строчной буквы.
- Создайте экземпляр объекта с помощью функции new.
Чтобы задать объектный тип , создайте функцию которая определит его имя, свойства, и методы. К примеру Вы хотите создать объектный тип для автомобилей. Вы хотите, чтобы этот тип объектов был назван car, и Вы хотите, чтобы у него были свойства: make, model, и year. Чтобы сделать это, создайте следующую функцию:
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
Заметьте, что использование this присваивает значения свойствам объекта, основанным на значениях, которые пользователь передаст функции.
Теперь вы можете создать объект mycar следующим образом:
var mycar = new Car("Eagle", "Talon TSi", 1993);
Этот оператор создает mycar и присваивает его указанные значения его свойствам. Затем значению mycar.make присваивается строка "Eagle", mycar.year присваивается число 1993 и так далее.
Можно создать любое количество объектов car с помощью вызова функции new..
Например:
var kenscar = new Car("Nissan", "300ZX", 1992);
var vpgscar = new Car("Mazda", "Miata", 1990);
У объекта может быть свойство, которое само является другим объектом. Например, Вы определяете объект person следующим образом:
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
и затем создаёте два новых объекта person следующим образом:
var rand = new Person("Rand McKinnon", 33, "M");
var 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;
}
Чтобы создать два новых объекта, использйте следующее:
var car1 = new Car("Eagle", "Talon TSi", 1993, rand);
var car2 = new Car("Nissan", "300ZX", 1992, ken);
Заметьте, что вместо того, чтобы передать строку или целочисленное значение, создавая новые объекты, вышеупомянутые операторы передают объекты rand и ken как параметры владельцев. Затем, если Вы хотите узнать имя владельца car2, можно получить доступ к следующему свойству:
car2.owner.name
Всегда можно добавить свойство к ранее определенному объекту. Например, оператор
car1.color = "black";
добавляет свойство color в car1, и присваивает ему значение " black ". Однако, это не влияет ни на какие другие объекты. Чтобы добавить новое свойство ко всем объектам того же самого типа, необходимо добавить свойство к определению объектного типа car.
Использование метода Object.create
Объект можно создать используя метод Object.create . Этот метод может быть очень полезным, потому что он позволяет выбрать прототип объекта для объекта, который Вы хотите создать, без необходимости определять функцию конструктора. Для более подробной информации о методе и как его использовать см.Object.create method.
// свойства Animal и инкапсуляция метода
var Animal = {
type: "Invertebrates", // Значение свойств типа по умолчанию
displayType : function(){ // Метод, который выведет на экран тип Animal
console.log(this.type);
}
}
//Создание нового типа animal который называется animal1
var animal1 = Object.create(Animal);
animal1.displayType(); // Вывод:Invertebrates
// Создание новый типа animal который называется Fishes
var fish = Object.create(Animal);
fish.type = "Fishes";
fish.displayType(); // Вывод:Fishes
Наследование
Все объекты в JavaScript наследуются по крайней мере от одного другого объекта. Объект, от которого ведётся наследование называется прототип(prototype), и унаследованные свойства могут быть найдены в объекте конструктора prototype.
Индексация объектных свойств
В 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.
Определение свойств для объектного типа
Можно добавить свойство к ранее определенному объектному типу при использовании свойства prototype. Так определяется свойство, которое совместно используется всеми объектами указанного типа, а не только одним экземпляром объекта. Следующий код добавляет свойство color ко всем объектным типам car, и затем присваивает значение свойству color объекта car1.
Car.prototype.color = null;
car1.color = "black";
Так же для получения дополнительной информации прочитайте prototype property объекта Function в JavaScript Reference .
Определение методов
Метод это функция, связанная с объектом, или, проще говоря, метод является свойством объекта, которое является функцией. Методы определяются так же как и обычные функции, за исключением того, что они должны быть присвоены как свойство объекта. Примеры:
objectName.methodname = function_name;
var myObj = {
myMethod: function(params) {
// ...что-то делает
}
};
В данном примере objectName это существующий объект, 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();
cаr2.displayCar();
Использование this для ссылок на объект
В JavaScript существует специальное ключевое слово, this, которое можно использовать внутри метода, чтобы обратиться к текущему объекту. Скажем, вы вызываете функцию validate которая проверяет свойство объекта value принимая значения объект и высокиенизкие значения:
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 объединён со свойством form , он может обратиться к родительской форме текущего объекта. В следующем примере форма myForm содержит объект Text и кнопку. Когда пользователь нажимает кнопку, значение объекта Text устанавливается в имя формы. Обработчик событий кнопки Onclick использует this.form, чтобы обратиться к родительской форме,myForm.
<form name="myForm">
<p><label>Form name:<input type="text" name="text1" value="Beluga"></label>
<p><input name="button1" type="button" value="Show Form Name"
onclick="this.form.text1.value = this.form.name">
</p>
</form>
Определение методов get и set
Метод get является методом, который получает значение определенного свойства. Метод set является методом, который устанавливает значение определенного свойства. Можно определить методы get и set на любом предопределенном базовом объектe или объекте созданном пользователем, который поддерживает добавление новых свойств. Для методов getter и setter используется объектный литеральный синтаксис.
Начиная с JavaScript 1.8.1, Устанавливая свойства в объекте и выстраивая инициализаторы.методы set больше не вызывают
Данный сеанс иллюстрирует, как методы get и set работают на созданном пользователем объекте(o). JS-shell это приложение, которое позволяет разработчикам тестировать код JavaScript в пакетном или в интерактивном режиме. В Firefox, JS shell запускается при нажатии клавиш Ctrl+Shift+K.
js> var 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
Свойства объекта(o):
- .a — число
- o.b — метод get, который возвращает o.a+1
- o.c — метод set, который устанавливает значение o.a к половине значения, установленного в o.c
Следует заметить, что имена функций методов get и set, которые были определены с использованием литеральной нотации "[gs]et property()"не являются именами методов get непосредственно, даже при том, что синтаксис [gs]et propertyName(){ } может ввести в заблуждение. Чтобы назвать функцию в методе get или методе set, используя "[gs]et property()" syntax, определите явно именованную функцию, программно использующую Object.defineProperty (или Object.prototype.__defineGetter__ ).
Этот сеанс JS shell иллюстрирует, как методы get и методы set могут расширить прототип Date, чтобы добавить свойство year ко всем экземплярам предопределенного класса Date. В нём использованы существующие в классе Date методы getFullYear и setFullYear, чтобы поддерживать в свойствах year метод get метод set.
Эти операторы определяют метода get и метод set для свойства year:
js> var d = Date.prototype;
js> Object.defineProperty(d, "year", {
get: function() {return this.getFullYear() },
set: function(y) { this.setFullYear(y) }
});
Эти операторы используют метод get и метод set в объекте 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
Устаревший синтаксис
В прошлом JavaScript, поддерживал несколько других синтаксисов для определения методов get и set. Ни один из этих синтаксисов не поддерживался другими механизмами, и в недавних версиях JavaScript больше не поддерживается.
Резюме
В принципе методы get и set могут быть также:
- назначениы с помощью инициализаторов объекта,
- добавленны позже к любому объекту, используя метод добавления метода get или метод добавления метода set.
При определении методов get и set, используя объектные инициализаторы все, что нужно сделать - это снабдить префиксом «get» метод get, и «set» метод set. Конечно, метод get не должен идать параметр, в то время как метод set ожидает один параметр (новое значение, чтобы его установить). Например:
var o = {
a: 7,
get b() { return this.a + 1; },
set c(x) { this.a = x / 2; }
};
Методы get и set могут также быть добавлены к объекту в любое время после создания, с помощью метода Object.defineProperties . Первый параметр этого метода это объект, в котором Вы хотите определить метод get или метод set. Второй параметр это объект, имена свойств которого являются именами метода get или метода set, значения свойств которого являются объектами , определяющими функции метода set или get. Вот пример, который определяет методы get и метод set, которые были показаны в предыдущем примере:
var o = { a:0 }
Object.defineProperties(o, {
"b": { get: function () { return this.a + 1; } },
"c": { set: function (x) { this.a = x / 2; } }
});
o.c = 10 // Выполняет метод set, который присваивает 10 / 2 свойству a
console.log(o.b) // Выполняет метод get, который возвращает a + 1 или 6
Какую из двух форм выбрать зависит от Вашего стиля программирования и поставленной задачи . Если Вы сразу обращаетесь к объектному инициализатору, определяя прототип, то Вы, вероятно, выберете первую форму. Эта форма является более компактной и естественной. Однако, если Вам нужно добавить методы get и set позже, вследствии того,что Вы не написали прототип или определенный объект — тогда, вторая форма является единственной возможной формой. Вторая форма, вероятно, лучше всего представляет динамический характер JavaScript — но это может сделать код трудным для чтения и понимания
См. также
Удаление свойств
Можно удалить неунаследованное свойство используя оператор delete. Данный код показывает, как удалить свойство.
//Создаем новый объект, myobj, с двумя свойствами, a и b.
var myobj = new Object;
myobj.a = 5;
myobj.b = 12;
//Удаляем свойство а, оставляя myobj только с свойством b.
delete myobj.a;
console.log ("a" in myobj) // выводит "false"
Можно использовать delete удалить глобальную переменную если ключевое слово var не использовалось, чтобы объявить переменную:
g = 17;
delete g;
Сравнение Объектов
В JavaScript объекты являются ссылочным типом. Сравнение двух объектов, которые ссылаются на тот же самый объект, возвратит true. Сравнение двух объектов, у которых есть те же самые методы и свойства, возвратит false.
// fruit ссылается на объект
var fruit = {name: "apple"};
// fruitbear ссылается на объект
var fruitbear = {name: "apple"};
fruit == fruitbear // возвратиться false
fruit === fruitbear // возвратиться false
Заметка:"===" используется для сравнения данных как по значению, так и по типу1 === "1" // return false and 1 == "1" // returntrue
// fruit ссылается на объект
var fruit = {name: "apple"};
// fruitbear ссылается на объект
var fruitbear = fruit; // ссылаем fruit на объект на fruitbear
// здесь fruit и fruitbear указывают на один и тот же объект,вызывая объект fruit
fruit == fruitbear // возвратиться true
// здесь fruit и fruitbear указывают на один и тот же объект,вызывая объект fruit
fruit === fruitbear // возвратиться true
Загружено переводчиком: Сучков Пётр Викторович Биржа переводов 01
Язык оригинала: английский Источник: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects