Объекты JavaScript: различия между версиями
imported>Supportadmin |
imported>Supportadmin |
||
(не показаны 3 промежуточные версии этого же участника) | |||
Строка 308: | Строка 308: | ||
func() | func() | ||
alert(func.called) // 2 | 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 можно почитать в этой [http://javascript.ru/tutorial/object/thiskeyword статье]. | |||
== Перебор свойств объекта == | |||
Для перебора всех свойств объекта используется специальный вид конструкции 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)) { | |||
//... | |||
} |
Текущая версия от 12:47, 4 августа 2013
Объекты.
первоисточник понимания 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)) { //... }