Объекты JavaScript

Материал из support.qbpro.ru

Объекты.

первоисточник понимания http://karaboz.ru/?p=5


var <имя_объекта> = new <Тип_объекта> ('Привет мир');

Это типичный пример. Ключевые слова:

var - создает локальную переменную, не принадлежащую объекту window
new - создает новую область видимости, отличную от области видимости window.

Пример создания объектов разных типов:

Явное создание
Неявное создание
Число
var num = new Number(12345.6789); var num = 12345.6789;
Булево значение
var c = new Boolean(true); var bul = true;
Функция
var fun = new Function('x', 'var p = x'); var fun = function(x){var p = x}
Массив
var arr = new Array('a', 'b', 'c'); var arr = ['a', 'b', 'c'];
Объект
var obj = new Object(); var obj = {};

Ограничения Следующий код показывает равенство двух переменных (объектов класса String):

var str1 = 'karaboz';
var str2 = new String('karaboz');
alert(str1 == str2); // выводит true

при попытке определить новый пользовательский метод для str1 мы получим ошибку:

str1.tell = function(){	alert(this);}
str1.tell(); // выводит ошибку 'str1.tell is not a function'

При этом, для str2 все сработает, как мы и ожидаем:

str2.tell = function(){	alert(this);}
str2.tell(); // выводит 'karaboz'

Это ограничение, наложенное JavaScript на переменные (объекты), созданные через строковые, числовые и булевы литералы, тем не менее, не распространяется на объекты, созданные через литералы функции, массива или объекта. Т.е. переменным (объектам), содержащим в себе функцию, или массив, или объект можно напрямую присваивать пользовательские свойства и методы:

var s = 'futurico'; // создаем новое свойство s объекта window (window.s)
var f = function(){ // создаем новый метод f объекта window (window.f)
alert(this == window); // выводит true
alert(this.s); // выводит 'futurico'
}
f(); // вызываем метод f объекта window (window.f())
f.s = 'karaboz'; // создаем новое свойство s объекта window.f (window.f.s)
f.m = function(){ // создаем новый метод m объекта window.f (window.f.m)
alert(this == f); // выводит true
alert(this.s); // выводит 'karaboz'
}
f.m(); // вызываем метод m объекта window.f (window.f.m())

Здесь мы наглядно убеждаемся, что функция f, созданная как метод глобального объекта window, сама оказывается объектом, у которого могут быть свои собственные свойства и методы!

Это ограничение, наложенное JavaScript на переменные (объекты), созданные через строковые, числовые и булевы литералы, тем не менее, не распространяется на объекты, созданные через литералы функции, массива или объекта. Т.е. переменным (объектам), содержащим в себе функцию, или массив, или объект можно напрямую присваивать пользовательские свойства и методы:

var s = 'futurico'; // создаем новое свойство s объекта window (window.s)
var f = function(){ // создаем новый метод f объекта window (window.f) 
alert(this == window); // выводит true
alert(this.s); // выводит 'futurico'
}
f(); // вызываем метод f объекта window (window.f())
f.s = 'karaboz'; // создаем новое свойство s объекта window.f (window.f.s)
f.m = function(){ // создаем новый метод m объекта window.f (window.f.m)
alert(this == f); // выводит true 
alert(this.s); // выводит 'karaboz'
}
f.m(); // вызываем метод m объекта window.f (window.f.m())

Здесь мы наглядно убеждаемся, что функция f, созданная как метод глобального объекта window, сама оказывается объектом, у которого могут быть свои собственные свойства и методы!

Вывод

Для того, что бы объект вел себя предсказуемо (это исключает долгую логическую отладку) объекты НАДО СОЗДАВАТЬ ТОЛЬКО ЯВНЫМ СПОСОБОМ

оригинал http://habrahabr.ru/post/17613/


JavaScript предоставляет разработчикам возможность создавать объекты и работать с ними. Для этого существуют следующие приёмы: Оператор new Литеральная нотация Конструкторы объектов Ассоциативные массивы


Оператор new

Это, наверное, самый легкий способ создания объекта. Вы просто создаете имя объекта и приравниваете его к новому объекту Javascript.

//Создаем наш объект
var MyObject = new Object();
//Переменные
MyObject.id = 5; //Число
MyObject.name = "Sample"; //Строка
//Функции
MyObject.getName = function()
{
    return this.name;
} 

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

//Используем наш объект
alert(MyObject.getName());

Литеральная нотация

Литеральная нотация является несколько непривычным способом определения новых объектов, но достаточно легким для понимания. Литеральная нотация работает с версии Javascript 1.3.

//Создаем наш объект с использованием литеральной нотации
MyObject = {
   id : 1,
   name : "Sample",
   boolval : true,
   getName : function()
   {
       return this.name;
   }
} 

Как видите, это довольно просто.


Объект = {
идентификатор : значение,
...
} 

И пример использования:

alert(MyObject.getName());

Конструкторы объектов

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

function MyObject(id, name)
 {

 } 

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

var MyFirstObjectInstance = new MyObject(5,"Sample");
 var MySecondObjectInstace = new MyObject(12,"Othe Sample"); 

Таким образом мы создали различные экземпляры объекта. Теперь мы можем работать отдельно с каждым экземпляром объекта MyObject, не боясь того, что, изменяя свойства одного экземпляра, мы затронем свойства другого экземпляра.

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


function MyObject(id, name)
{
    //Значения переданные пользователем
    this._id = id;
    this._name = name;
    //Значение по умолчанию
    this.defaultvalue = "MyDefaultValue"; 
} 


Аналогичным образом мы можем создавать и функции.


function MyObject(id,name)
{
    this._id = id;
    this._name = name;
    this.defaultvalue = "MyDefaultValue"; 
    
    //Получение текущего значения
    this.getDefaultValue = function()
    {
        return this.defaultvalue;
    }
    
    //Установка нового значения
    this.setDefaultValue = function(newvalue)
    {
        this.defaultvalue = newvalue;
    }
    
    //Произвольная функция
    this.sum = function(a, b)
    {
        return (a+b);
    }
}

Ассоциативные массивы

Подобный метод будет полезен упорядочивания большого числа однотипных объектов.


var MyObject = new Number();
MyObject["id"] = 5;
MyObject["name"] = "SampleName"; 


Для обхода таких объектов можно использовать такой цикл:


for (MyElement in MyObject)
{
   //Код обхода
   //В MyElement - идентификатор записи
   //В MyObject[MyElement] - содержание записи
}


Свойства объекта

первоисточник для понимания http://javascript.ru/tutorial/object/intro

Пусть существует такой объект:

var stroka = new Object('Привет мир');


Добавим свойство объекту:

stroka.property ="Новое свойство объекта"

Удаление метода

delete

Методы объекта

Пусть существует такой объект:

var stroka = new String ('Привет мир');

Добавим этому объекту метод:

stroka.tell = function(){alert(this)};        //область видимости this указывает на объект, которому принадлежит данный метод

Вызовем этот метод:

stroka.tell();   //выведет  Привет мир

Волшебная переменная arguments

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

Следующий пример выведет реально переданные три аргумента, несмотря на то, что в функции их всего два.


function func(a,b) {
  alert(arguments[0])
  alert(arguments[1])
  alert(arguments[2])
}
func(1,2,3)

Кроме цифровых индексов, у arguments есть свойство length, такое же как у массива.

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

Пример: сумма аргументов

function sum() {
  var s = 0
  for(var i=0; i<arguments.length; i++) s += arguments[i]
  return s
}

Несмотря на доступ по индексу и наличие свойства length, arguments не является массивом, т.е не принадлежит типу Array.

Поэтому для arguments нельзя напрямую вызвать методы этого класса:

arguments.pop() // ошибка !

Можно, однако, вызвать методы Array через apply/call:

var args = Array.prototype.slice.call(arguments)

Ссылка на функцию arguments.callee

Кроме аргументов, arguments содержит ссылку на выполняющуюся функцию.

Ее можно использовать для задания и чтения статических свойств.

В следующем примере для этого используется статическое свойство called.

Пример: подсчет количества выполнений

function func() {
   arguments.callee.called++
}
func.called = 0;
func()
func()
alert(func.called) // 2

оригинал:http://javascript.ru/tutorial/object/intro


Объекты (они же - ассоциативные массивы, хэши) и работа с ними в Javascript - реализованы не так, как в большинстве языков. С этим связано много ошибок и непоняток.

В этой статье описаны базовые свойства объектов javascript, создание и изменение, перечисление свойств и т.п.

Объект в javascript представляет собой обычный ассоциативный массив или, иначе говоря, "хэш". Он хранит любые соответствия "ключ => значение" и имеет несколько стандартных методов.

Метод объекта в javascript - это просто функция, которая добавлена в ассоциативный массив. Далее - подробнее.

Создание и работа со свойствами

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

Следующие два варианта создания объекта эквивалентны:

var o = new Object()
var o = {}

Добавление свойств

Есть два синтаксиса добавления свойств в объект. Первый - точка, второй - квадратные скобки:

// эквивалентные записи
o.test = 5
o["test"] = 5

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

var name = 'test'
o[name] = 5

Здесь имя свойства "test" является ключом в ассоциативном массиве, по которому лежит значение 5.


Доступ к свойствам

Доступ к свойству осуществляется точно так же:

alert(o.test) 
alert(o['test'])

Если у объекта нет такого свойства, то результат будет 'undefined'

var o = {}
alert(o.nosuchkey)   // => undefined

Никакой ошибки при обращении по несуществующему свойству не будет, просто вернется специальное значение undefined.


Проверка глобальной переменной

В javascript нельзя проверить существование глобальной переменной простым if:

if (x) { ... }

Если x не определен, то конструкция if (x) вызовет ошибку javascript.

Распространенное решение - использовать typeof:

if (typeof x != 'undefined') { ... }  // или typeof(x)

Однако зная, что глобальная переменная в javascript - всего лишь свойство объекта window - мы можем записать проще:

if (window.x) { ... }   // правильный аналог if(x)
// или
if (window.x !== undefined) // аналог typeof x ..

Все свойства объектов - public, т.е при определении свойства никак нельзя ограничить доступ к свойству. В javascript есть специальные выверты для создания private свойств, связанные с замыканиями. Они рассмотрены вместе с наследованием объектов.


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

Удаляет свойство оператор delete:

o.test = 5
delete o.test
o['bla'] = true

Расширенное создание

Свойства можно указывать непосредственно при создании объекта, через список в фигурных скобках вида {..., ключ : значение, ...}:

var o = {
   test: 5, 
   bla: true
}

Методы объектов

Добавление метода

Как и в других языках, у объектов javascript есть методы.

Например, создадим объект rabbit с методом run

var rabbit = {}
rabbit.run = function(n) {
   alert("Пробежал "+n+" метров!")
}

Добавление метода в объект - просто присвоение функции function(n) { ... } свойству rabbit.run.

Теперь можно запускать

var rabbit = {}
rabbit.run = function(n) {
   alert("Пробежал "+n+" метров!")
}
rabbit.run(5)  // Пробежал 5 метров
rabbit.run(7)  // Пробежал 7 метров

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

Javascript - очень динамический язык, не правда ли?


Доступ к объекту из метода

Обычно хочется, чтобы метод не просто вызывался из объекта, но имел доступ к самому объекту, мог менять находящиеся в нем данные.

Для этого используется ключевое слово this:

for(var key in obj) {
… obj[key] …
}

В отличие от многих языков, this никак не привязано к объекту, а обозначает просто объект, вызвавший функцию. Например,

function this1() {

   var vasya = { name:'Вася' }
   var petya = { name:'Петя' }
   sayName  = function() {
       alert("Я - "+ (this.name ? this.name : 'безымянный') )
  }
   vasya.sayName = sayName
   // один и тот же метод в двух объектах
   petya.sayName = vasya.sayName
   // тут - this будет petya
   petya.sayName()  // Я - Петя
  // тут - this будет vasya
   vasya.sayName()  // Я - Вася
  // а тут - вызывается метод глобального объекта window, у которого нет имени
  sayName() // Я - безымянный
}

Более подробно о том, как работает this можно почитать в этой статье.


Перебор свойств объекта

Для перебора всех свойств объекта используется специальный вид конструкции for, for..in:


for(var key in object) {
 // key - название свойства
 // object[key] - значение свойства
 ...
}

Например,

var o = {a:5, b:true}
for (var key in o) {
   alert(key+':'+o[key])
}


Это уже выходит за рамки текущей статьи, но вообще - существует еще одна форма перебора свойств, которая более надежна, особенно если используется библиотека типа prototype.

for(prop in object) {
   if (!object.hasOwnProperty(prop)) continue
   //...
}

Эта форма отфильтровывает свойства, которые принадлежат не самому объекту, а его прототипу. Поэтому она работает, даже если в прототип Object добавлены новые свойства.

Более элегантный вариант записи:

for(prop in object) if (object.hasOwnProperty(prop)) {
   //...
}