Javascript.RU

Объекты Javascript в примерах

Объекты (они же - ассоциативные массивы, хэши) и работа с ними в 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 object

Как и в других языках, у объектов 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() // Я - безымянный
}

Запустить this1()

Более подробно о том, как работает 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)) {
    //...
}

Автор: klubben (не зарегистрирован), дата: 7 июня, 2008 - 13:10
#permalink

А почему ничего не сказано про прототипы (aka классы)?

function a () { // объявляем класс

}

// добавляем метод для прототипа
a.prototype.b = function () {
alert ('test');
}

// создаем объект
var a = new a();


Автор: klubben (не зарегистрирован), дата: 7 июня, 2008 - 13:13
#permalink

Извиняюсь, сам дурак


Автор: anima (не зарегистрирован), дата: 19 июня, 2008 - 14:51
#permalink

Хорошие статьи. Коротко, самое важное, без утаревших приемов, и всякой лабуды. Но я, собственно, по поводу Доступ к объекту из метода.
Раньше, было не нужно, а сейчас потребовалось, из повешанного на объект метода, получить ссылку не на объект его вызвавший, а на объект, на котором висит сам метод. Вроде вот он рядом :-), а как достать? Понимаю, что можно использовать прототип, но это нарушит всю задуманную задачу. Перекопал сегодня пол Интернета, но как то не смог ни чего найти. Такое чувство, что есть какая то простейшая возможность, но я её упустил.
Сам метод генерится динамически, и я, в принципе, могу жестко забить ссылку на объект, но это вроде не этично. :-)


Автор: vasa_c, дата: 21 июня, 2008 - 20:59
#permalink

Что есть "объект, на котором висит сам метод"?


Автор: anima (не зарегистрирован), дата: 20 июля, 2008 - 12:03
#permalink

Что есть "объект, на котором висит сам метод"?

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

Например, есть элемент div c id="div", вешаем метод таким образом:

document.getElementById('div').metod = function() { alert('Ok!'); };

потом назначаем этот метод обработчиком события click.

document.get.ElementsByTagName('body')[0].onclick = document.getElementById('div').metod;

Так "не принято", но мне нужно именно так.

И теперь, нужно из самого метода получить ссылку на DIV, на котором он висит.


Автор: Гость (не зарегистрирован), дата: 31 июля, 2008 - 23:38
#permalink
document.get.ElementsByTagName('body')[0].onclick = function()
{
    document.getElementById('div').metod;
}

Автор: Илья Кантор, дата: 19 августа, 2008 - 13:34
#permalink

В тему: в javascript, в отличие от C/Java/... методы НЕ висят на объектах. Контекст вызова метода целиком зависит от того, как его вызвали.

Вот


Автор: Гость (не зарегистрирован), дата: 30 июня, 2008 - 12:21
#permalink

как можно исползоват функции php в javascript


Автор: Гость (не зарегистрирован), дата: 6 июля, 2008 - 22:00
#permalink

РНР это серверные скрипты... JavaScript это клиентская часть. Можно вызвать через AJAX сам РНР скрипт и результат его работы получить через XML (или в HTML на худой конец). А дальше делай с этими данными все что нужно.


Автор: Руслан Зетов (не зарегистрирован), дата: 29 августа, 2010 - 14:36
#permalink

Думаю гораздо удобней будет получить результат ввиде JSON строки.


Автор: Bratok (не зарегистрирован), дата: 15 августа, 2008 - 19:08
#permalink

А можно ли изменит порядок свойств объекта? Можно ли с объектом работать как с массивом т.е. использовать теже методы предусмотренные для объект Array?


Автор: Bratok (не зарегистрирован), дата: 17 августа, 2008 - 09:01
#permalink

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


Автор: Гость (не зарегистрирован), дата: 18 августа, 2008 - 19:41
#permalink

интересная статья. Много полезного узнал. Но вот интересно как можно вызывать метод объекта через setTimeout? Странно, вызов происходит, только метод не может получить доступ к свойствам объекта.


Автор: Илья Кантор, дата: 18 августа, 2008 - 23:33
#permalink

В примере ниже вызван метод объекта "metod" с правильным this

....
var self = this
setTimeout(function() { self.method() }, 1000)
...

То есть, правильный указатель this передается через замыкание. Очень распространенный трюк.


Автор: Алексей_Р (не зарегистрирован), дата: 2 марта, 2009 - 02:20
#permalink

Почему, когда я пытаюсь объявить объект Google maps в глобале,
ничего не происходит?

var map = new google.maps.Map2(document.getElementById("map"));
 function mapsLoaded() {
  map.setCenter(new google.maps.LatLng(37.4419, -122.1419), 13); //Не работает
}

Автор: kefi, дата: 14 марта, 2009 - 03:57
#permalink

Если Array является объектом (встроенным) со свойствами constructor,length,prototype,concat,join etc..., то почему я не могу перечислить его свойства путем :

for (var key in Array) {  alert(key+':'+ Array.prototype.hasOwnProperty(key)+'&')  }

или

for (var key in Array) {  alert(key+':'+ Array.hasOwnProperty(key)+'&')  }

?


Автор: Zeroglif, дата: 15 марта, 2009 - 00:51
#permalink

Array - это один объект (конструктор/функция), а Array.prototype - это другой объект, у каждого свои свойства, которые могут иметь атрибут DontEnum, что исключает их перечисление.


Автор: kefi, дата: 15 марта, 2009 - 12:56
#permalink

Хорошо, поправлюсь :

Вначале наведенные ответом вопросы : а как понять(узнать), какие атрибуты установлены у данного свойства ? И как вообще установить эти атрибуты ?

И собственно сам вопрос :
Если Array является объектом (встроенным) со свойствами constructor,length,prototype,concat,join etc..., то почему я получаю эти свойства у его прототипа, а не у него самого :

alert(Array.prototype.hasOwnProperty("join") ) // -1
 alert(Array.hasOwnProperty("join"))                //  0

Тем более, что сказано в документации :
Этот метод не проверяет наличие свойства по цепочке прототипов; указанным свойством должен обладать именно сам объект. А пример выше показывает, что именно сам объект не обладает свойством, а обладает, наоборот, - прототип.
Короче , путаница получается - распутайте, плз.

Еще пример для размышления :

alert(Object.hasOwnProperty("prototype")) // -1
 alert(Object.prototype.hasOwnProperty("prototype")) // 0

Автор: Гость (не зарегистрирован), дата: 28 декабря, 2015 - 07:08
#permalink

wadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadad


Автор: Илья Кантор, дата: 15 марта, 2009 - 15:50
#permalink

Обратитесь к стандарту: http://javascript.ru/ecma/part12#a-12.6.4.

Там описано, как работает цикл for .. in. Обратите внимание на шаг 5.

Перечисляются только те свойства, у которых нет атрибута DontEnum.

Большинство свойств у родных объектов яваскрипт имеют DontEnum, и поэтому не будут перечисляться в цикле for..in.

Атрибут DontEnum не проверяется при прямом обращении, поэтому Array.prototype.join выдаст, что метод все-таки есть.


Автор: kefi, дата: 15 марта, 2009 - 20:11
#permalink

[quote]Атрибут DontEnum[/quote] Да про него уже скзали выше. Интересуют ответы на "наведенные вопросы" см выше по поводу аттрибутов ?!

А ответ на этот вопрос тоже должен быть не такой, как я понял , а такой :

alert(Array.hasOwnProperty("join"))  //  false

, потому , что Array здесь ошибочно употреблен в качестве объекта типа Array, в то время , как в такой нотации он является объектом типа Function, т.к. возвращает ссылку на конструктор Array.

alert(Array.prototype.hasOwnProperty("join") ) // true

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

Кстати, для

var a = new Array(); alert(a.hasOwnProperty("join")) // =false

потому, что объект a действительно не имеет собственного Own свойства "join" , оно для этого объекта берется из его прототипа (на прототип объекта a указывает свойство prototype его конструктора Array.prototype),


Автор: Илья Кантор, дата: 15 марта, 2009 - 20:23
#permalink

У класса Array есть свой, "статический", метод join:

Array.join([1,2,3],"-")

Автор: Леонид Евстигнеев, дата: 31 мая, 2009 - 19:43
#permalink

И в чём принципиальная разница между a и b в следующем коде.

var a = new Object();
function myFunc(){};
var b = new MyFunc();

Я так понимаю ссылкой prototype (или [[prototype]]) и как следствие набором свойств и методов. Или ещё чем...? И можно ли сказать, что b создается как и а, но после создания b вызывается ещё и MyFunc() (с this указывающем на b)


Автор: Гость (не зарегистрирован), дата: 4 июля, 2009 - 15:09
#permalink

Как я полагаю, Вы сами ответили на свой вопрос. Мне кажется, что все именно так.


Автор: dido (не зарегистрирован), дата: 20 декабря, 2009 - 14:56
#permalink

Very good post, thanks a lot.


Автор: sarlv (не зарегистрирован), дата: 17 января, 2010 - 03:38
#permalink

Подскажите пожалуйста!!!
Есть такой когд (смотреть ниже), где нужно передать id в функцию clickFunction().
В результате получаю null. Пробовал ввести id напрямую, т. е. "list", браузер не выводит вообще ничего.

<html>
<head>
    <script type="text/javascript">
    function clickFunction(elemId){ 
        
        alert(elemId);
    }
    
    var getId = document.getElementById("list");
    var altF = new clickFunction(getId);
       
    </script>
    <title></title>
</head>
<body>
    
    <ul id="list">
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
    </ul>
</body>
</html>

P.S.: заранее приношу ивинения, если пишу не туда.
Я "чайник"


Автор: Гость (не зарегистрирован), дата: 30 января, 2010 - 11:33
#permalink

<html>
<head>
<title></title>
</head>
<body>
<ul id="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</body>
</html>

<script type="text/javascript">
var getId = document.getElementById("list");
function clickFunction(elemId){
alert(elemId.id);
}
var altF = new clickFunction(getId);
</script>


Автор: sarlv (не зарегистрирован), дата: 17 января, 2010 - 04:02
#permalink

Прошу прощения, читать так:
alert(elemId.nodeName);


Автор: Гость (не зарегистрирован), дата: 30 января, 2010 - 11:22
#permalink
  • Item 1
  • Item 2
  • Item 3

var getId = document.getElementById("list");
function clickFunction(elemId){
alert(elemId.id);
}
var altF = new clickFunction(getId);


Автор: YISHIMITSY, дата: 28 марта, 2010 - 14:46
#permalink

Автор: PieceOfMeat (не зарегистрирован), дата: 29 марта, 2010 - 17:12
#permalink

Прошу прощения если не заметил, но по-моему у вас нигде не написано, что объекты в Javascript передаются и копируются по ссылке.

И было бы интересно увидеть функцию clone, которая делала бы копирование объектов по значению.


Автор: B@rmaley.e><e, дата: 30 марта, 2010 - 23:41
#permalink

function clone(obj){
var newObj = {}, i;
for(i in obj)
newObj[i] = obj[i];
return newObj;
}

TODO: Добавить рекурсивое клонирование


Автор: Илья Кантор, дата: 28 мая, 2010 - 17:49
#permalink

В этой функции есть ряд недостатков, аккуратнее с ней.


Автор: Евгений Z (не зарегистрирован), дата: 16 ноября, 2011 - 18:51
#permalink

Доброго времени суток. Хотел спросить совет знающих людей. Есть страничка с несколькими фреймами. Тянуть jQuery в каждый фрейм не хочется, т.к. это потянет за собой увеличение трафика. Хотелось узнать, можно ли каким-то образом подключить jQuery в главной страничке и использовать его в страничках-фреймах? Разумеется конструкция типа var $ = top.$; не прокатит т.к. передается ссылка на обьект а не он сам. Пробовал функции клонирования - аналогичная ситуация. Ни в первом ни во втором случаях из $ не видно локальных функций, которые описаны во фреймах, но jQuery работает (тот же ajax). Так вот вопрос, можно ли найти выход из данной ситуации? Ну очень не хочется в каждом фреймне тянуть jQuery (((


Автор: Гость (не зарегистрирован), дата: 28 мая, 2010 - 16:08
#permalink

Не перепутан ли в статье этот пример:

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

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

И хотел спросить. Так я обращаюсь к свойствам объекта из метода:

var obj = {
property : 0,
  a : 0,
  b : 0,
  c : 0
}
obj.method = function(n) {
  this.property = n * this.a + ( this.b + n ) / this.c;
}

Возможно ли обращение без this?


Автор: Илья Кантор, дата: 28 мая, 2010 - 17:49
#permalink

Обращение к свойствам объекта из метода без this невозможно.


Автор: Александр второй (не зарегистрирован), дата: 29 мая, 2010 - 18:53
#permalink

Не нашел на сайте, где можно посмотреть как можно сделать так чтобы при наведении мыши на страницу происходило какое-то действие. Подскажите.


Автор: Гостейко (не зарегистрирован), дата: 26 октября, 2010 - 15:05
#permalink

?


Автор: Гостейко (не зарегистрирован), дата: 26 октября, 2010 - 15:06
#permalink
<body onmouseover="someFunction()"> ?

Автор: гость (не зарегистрирован), дата: 21 июля, 2010 - 16:08
#permalink

Извиняюсь за глупый вопрос)

var o = {} //создали объект
o['test'] = 5 //добавили свойство
alert(o['test']) //выводит 5

Подскажите почему если вместо alert(o['test']) прописать alert(o.test) то будет выведено undefined. Ведь сказано что o - это объект, а test - его свойсто. Тоесть у него же есть свойство.


Автор: Гость (не зарегистрирован), дата: 22 августа, 2010 - 23:00
#permalink
[js]
[js]
[js]
[js]
[js]
[js]
[js]
[js]
[/js][/js][/js][/js][/js][/js][/js][/js]

Автор: mch (не зарегистрирован), дата: 23 августа, 2010 - 11:28
#permalink

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

var img = new Image ();
img.src = "a.jpg";

var o = { b1: img, b2: img, b3: img }


Автор: Гость (не зарегистрирован), дата: 24 августа, 2010 - 17:59
#permalink

в опере 9.6 баг нашел.
в мазиле и в ие можно так делать:

var a=new Array()
a['top']='dfgd.kfg'
a['bottom']='dfgkldfg'
a['dfgqwdf']='dfl.kgdfg'

а потом обращатся двумя способами:
var c=a.top // c='dfgd.kfg'
var c=a['top'] // c='dfgd.kfg'

так вот в опере работает только второй способ.


Автор: Гость, дата: 17 сентября, 2010 - 15:48
#permalink

Не поверите, беру первый ваш пример, вставляю в текст своей страницы и ничего не происходит. С этой страницы, кстати, работает.


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


Автор: Андрей99999999999 (не зарегистрирован), дата: 10 апреля, 2012 - 20:31
#permalink

Допиши ..., а между ними вставь код)


Автор: CraZZZy-GameRRR (не зарегистрирован), дата: 9 октября, 2010 - 19:53
#permalink

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


Автор: Гость (не зарегистрирован), дата: 10 октября, 2010 - 11:31
#permalink

Извините если глупость сморозил, я начинающий js-программист. Есть код:

function myobj() {
  // some code
}
myobj.prototype.f = function() { alert(a); }

/* 1 */
var obj = new myObj();
obj.a = 10;
obj.f();

/* 2 */
var obj = { a: 10 }
obj.f(); // !!!

Как мне сделать чтобы второй вариант работал как первый (извините, иначе сформулировать не смог :-) ) Тоесть чтобы во втором случае обьект создался как в первом, что ли


Автор: Гость (не зарегистрирован), дата: 10 октября, 2010 - 11:34
#permalink

Упс, опечатался. Должно быть так:

myobj.prototype.f = function() { alert(this.a); }

Автор: monolithed, дата: 11 декабря, 2010 - 21:43
#permalink

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

Илья, это вводит в заблуждение некоторых пользователей, начиная с того что одни утверждают, что в JS объектов, заканчивая тем что есть только ассоциативные массивы, хэшы.
Предлагаю подкорректировать и сослаться/процитировать стандарт: http://javascript.ru/ecma/part4#a-4.2.1


Автор: Andrey1988 (не зарегистрирован), дата: 18 декабря, 2010 - 18:36
#permalink

Здравствуйте. У меня стоит задача получить доступ к переменным на странице, а точнее к переменным класса. Для этого я перебираю циклом for...in все свойства объекта window:

  1. var classA = function(){
  2. }
  3. var a = new classA();
  4. var b = new classA();
  5. var z = new Date();
  6. for (var k in window) {
  7. if (typeof (window[k]) == "object" && window[k] instanceof classA) {
  8. alert('Variable ' + k + ' is a classA');
  9. }
  10. }

В опере и хроме скрипт отрабатывает правильно, находит переменные a и b. Чего не скажешь про IE, который просто выдает ошибку в строке 9: "предполагается наличие объекта". Получается, что IE попросту не видит эти переменные в цикле. При этом мне нужно, чтобы скрипт работал именно под IE.
В чем может быть проблема?


Автор: Pruvet (не зарегистрирован), дата: 28 декабря, 2010 - 20:59
#permalink

Доступ к свойствам.
есть вот такой код:

profiler=function(_timeout)
{
	var timeout=_timeout
	var delay = 0
	var timer = new Date()
	this.min = timeout
	this.max = timeout
	var _profiler = function()
	{
		var _timer = new Date()
		delay=_timer-timer
		min = Math.min(min,delay)     //min - undefined
		max = Math.max(max,delay)  //max - undefined
		this.min = Math.min(min,delay)     //this = window
		this.max = Math.max(max,delay)  //this = window
		timer=_timer
		setTimeout(_profiler,timeout)
	}
	thisl.getDelay=function(){
		return delay
	}
	try{
		clearTimeot(this.timerID)
	}
	catch(e){
		this.timerID=setTimeout(_profiler,timeout)
	}
}
prof = new profiler(100)

При работе метода _profiler класса profiler по таймауту не могу получить доступ к свойствам min и max.
Доступ к delay получил через замыкание, при этом потерял доступ к delay из-вне класса _profiler. Для получения доступа на чтение добавил функцию getDelay.

Вопрос: как получить доступ к min и max из _profiler и из-вне класса profiler не создавая дополнительных методов для доступа к min и max?


Автор: Pruvet (не зарегистрирован), дата: 28 декабря, 2010 - 21:01
#permalink

опечатка:
вместо

thisl.getDelay

читать:

this.getDelay

Автор: star (не зарегистрирован), дата: 11 января, 2011 - 21:38
#permalink

Вот есть такой код:

var A = {'5':'1', '1':'2'};

for(var i in A) alert(i + ':'+ A[i]);

Все бы ничего, одно НО! гугл хром выводит алерты, отсортировав его по ключам (сначала 1:2, потом 5:1), хотя в мозилле и Ие так, как записаны....
как все таки в хроме обойти объект так, как он задан?

хотя такой код

var A = {'_5':'1', '_1':'2'};

выводит то что нужно, но насильно пихать, а потом срезать "лишние" символы не очень то и хочется


Автор: MODist, дата: 13 января, 2011 - 12:49
#permalink

Здравствуйте. Объясните разницу.

function people() {}

people.prototype.say= function() {
    return "hello";
}
console.log(people.say()); // TypeError: people.say is not a function

people.say = function() {
    return "hello";
};
console.log(people.say()); // hello

Почему в первом случае будет ошибка а во втором - нет? Какая разница если мы добавляем методы через prototype и через точку?


Автор: Гость (не зарегистрирован), дата: 15 января, 2011 - 12:43
#permalink

забыл про new?


Автор: frankbakulov, дата: 15 января, 2011 - 19:12
#permalink

Прошу прощения если не заметил, но по-моему у вас нигде не написано, что объекты в Javascript передаются и копируются по ссылке.

Вот это очень правильное замечание!

Только что на это наткнулся и испытал неприятное удивление - был уверен, что в js, как в нормальных языках, оператор "=" присваивает правую часть левой И БОЛЬШЕ НИЧЕГО.

Считаю, статья должна начинаться с этого.


Автор: ReptatmogeVog (не зарегистрирован), дата: 3 февраля, 2011 - 17:23
#permalink

да, что-то на подобии этого


Автор: Zeran (не зарегистрирован), дата: 16 марта, 2011 - 18:58
#permalink

Все никак не разберусь, как реализовано в jQuery такое:

$("myDiv").html()

Как сделать свои функцию в функции?


Автор: zeran (не зарегистрирован), дата: 17 марта, 2011 - 13:41
#permalink

Можно, конечно, сделать просто:

object.prototype.html = function() { return this.innerHTML };

например так. Но тогда это будет касаться всех объектов, что не очень удобно. ((


Автор: Гость (не зарегистрирован), дата: 29 марта, 2011 - 12:58
#permalink

Хочу "переименовать" id объекта через
document.getElementById( "sId").id = "sNewId";

Все работает, за исключением случая когда объект является активным объектом документа (т.е. имеет фокус). Другими словами переименование НЕ проходит с объектами, которые имеют во время выполнения скрипта фокус.

Как решить?


Автор: mrGreed, дата: 1 апреля, 2011 - 12:08
#permalink

проверять фокус - снимать фокус - менять айди - вешать фокус..?


Автор: mrGreed, дата: 1 апреля, 2011 - 12:06
#permalink

Дабавлю баянчик про хорошую статью .. Действительно - огромное спасибо автору(ам) за проект.
К делу. у Меня есть объект типа

{"<уникальный числовой код":["<значение1>","<значение2>",..],-||-,..}

проблема в том, что стандартным выводам

for(key in obj)

создаются DOM-узлы упорядоченные по числовому ключу соотвественно, а необходимо бы - по конкретному значению из списка.
Стоит сказать что JSON-строка из которой парсится obj упорядочина как раз таки по необходимому значению.
Есть идеи?


Автор: nexus (не зарегистрирован), дата: 19 мая, 2011 - 01:14
#permalink

Здравствуйте!

Никак не могу разобраться.
Вот есть у меня объект:

var defaults = {"size":"medium","title":"test"};
var json_elements= {};

Есть такая функция:

var item = 0;
function makeup(type){

        var obj =  defaults;
        obj.position = item;  
        obj.position = type;    
        json_elements[item] = obj;
        item++;

Почему если вызвать функцию makeup() несколько раз с разным значением переменной type, то объект json_elements будет содержать несколько одинаковых (последний добавленый) объектов?!

И как это побороть?! Спасибо!


Автор: zenitchik (не зарегистрирован), дата: 7 июля, 2011 - 16:10
#permalink
if (x) { ... }

Плохое решение.
x может быть равен 0, пустой строке, false в конце концов. В это случае проверка будет работать некорректно.
Надёжнее сравнивать с undefined


Автор: Гость (не зарегистрирован), дата: 15 августа, 2011 - 01:14
#permalink

Интересно сколько травы выкурили те кто придумали этот язык. Более не очевидного я в своей жизни не встречал. Ассемблер лично для меня намного проще.


Автор: B@rmaley.e><e, дата: 15 августа, 2011 - 19:49
#permalink

Brainfuck тоже прост. Вот только простота != выразительность.


Автор: Гость (не зарегистрирован), дата: 6 апреля, 2013 - 19:48
#permalink

полностью согласен!Асм легче


Автор: Gektar (не зарегистрирован), дата: 17 августа, 2011 - 00:10
#permalink

Ребятки спасибо что есть у Вас такие полезные сайты!!!!


Автор: Гость (не зарегистрирован), дата: 22 августа, 2011 - 23:29
#permalink

var Triangle;
(function () {
Triangle = function ( a, b, c ) {

this.sides = [ a, b, c ];

}

Triangle.prototype = new Shape();
Triangle.prototype.constructor = Triangle;
Triangle.prototype.getSquare = function () {
var p = this.getPerimeter()/2;
var S = Math.sqrt( p * ( p - this.sides[0] ) * ( p - this.sides[1] ) * ( p - this.sides[2] ) );
return Math.floor( S );
}
})();

var t = new Triangle ( 10, 15, 20 );

как мне получить имя класса из объекта t ???


Автор: Гость (не зарегистрирован), дата: 23 августа, 2011 - 12:47
#permalink

Поправте пример:

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

for(var key in obj) {

… obj[key] …

}


Автор: Dimka (не зарегистрирован), дата: 9 сентября, 2011 - 12:21
#permalink

Подскажите, пожалуйста, как посчитать количество ключей объекта?. В массивах можно посчитать размерность с помощью .length. В perl это можно сделать с помощью keys(). Можно ли это сделать без перебора ключей объекта (for ... in).


Автор: max0n, дата: 9 октября, 2014 - 18:54
#permalink

alert(Object.keys(o)); // o - объект, которого нужны свойства


Автор: iyntx, дата: 19 сентября, 2011 - 02:05
#permalink

Здесь так много написано и ни слова о том, что это такое и как это вообще может пригодиться...

Не могли бы дать несколько РАЗНЫХ примеров того что есть методы классы поля объекты наследования всякие public private prototype и прочие.
У нас же статья для того чтобы всем понятно было, а не только тем кто уже понял... Надеюсь на Ваше понимание...


Автор: Гость (не зарегистрирован), дата: 6 октября, 2011 - 14:22
#permalink

Как сделать так, чтобы при обращении к обьекту sum(4)(3) вывелась сумма 7


Автор: Questioner, дата: 1 ноября, 2011 - 17:14
#permalink

Как сделать приватное св-во? То есть которое можно получить из объекта, но не из вне объекта?


Автор: CE (не зарегистрирован), дата: 12 ноября, 2011 - 16:03
#permalink

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

Первое место (я где-то с десяток просмотрел до этого... наверное, не слишком удачно выбирал), где столь эссенциальная вещь прописана прямо и в самом начале.

Изучать я, соответственно, только-только начал, но вот когда видишь нечто вроде "ну вот, есть объекты, ну вот у них есть свои методы, алсо есть свойства" без дополнительных объяснений... Я уж грешным белом подумал, что это эдакие классы (с азартными играми и гулящими женщинами)

В общем - огромное спасибо. Один коротенький абзац, а столь радикально влияет на понимание сути. Впрочем, возможно, это применимо лишь ко мне - степень моей тупости британские ученые еще не вычислили, да.


Автор: Tipok, дата: 6 января, 2012 - 05:04
#permalink

Как это работает alert( ([][[]]+[])[+[]] ) и почему это буква "u" ???


Автор: Гость (не зарегистрирован), дата: 14 декабря, 2013 - 09:00
#permalink

Тут все просто, хоть и похоже на brain f#ck.
Отдельно стоящий оператор +[] - это 0

получается ([][[]]+[])[+[]] -> ([][[]]+[])[0]

([][[]]+[]) - это строка "undefined"

([][[]]+[])[0] -> "undefined"[0] -> "u"

Тут самое сложное понять как преобразуется значение undefined в строку "undifined"

[][[]] - значение undefined - тип undefined
([][[]]+[]) - значение "undefined" - тип "string"

Так можно много экпериментировать.
Например:
(+[][+[]]+[])[+[]+[]] = "N"

+[]+[] -> 0+0 -> 0
(+[][+[]]+[]) -> "NaN"

"NaN"[0] -> "N"

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


Автор: DennisKa (не зарегистрирован), дата: 19 января, 2012 - 14:31
#permalink

Одно непонятно: если создать к примеру 1000 объектов, как потом найти 50, 100, 300, и уничтожить их. Или найти объекты по какому либо идентификатору (свойству "ID") например?


Автор: Игорь Л (не зарегистрирован), дата: 6 февраля, 2012 - 17:51
#permalink

Подскажите, как из js получить доступ к объекту формы, выраженной там в виде массива? Например, есть форма:

<form method="post">
<label><input type="checkbox" name="idtyp[1]">typ 1</label>
<label><input type="checkbox" name="idtyp[2]">typ 2</label>
<label><input type="checkbox" name="idtyp[3]">typ 3</label>
</form>

В PHP POST вполне нормально воспринимает переданный параметр как массив:

$idtyp = $_POST['idtyp'];

А как прочитать в JS?


Автор: Игорь Л (не зарегистрирован), дата: 6 февраля, 2012 - 19:40
#permalink

Нашёл сам!

var a = document.getElementsByTagName('input');
	var notcheck = true;
	for (var i = 0; i < a.length; i++) {
		var nam = a[i].name;
		if (a[i].type == 'checkbox' && nam.substr(0,5)=="idtyp") {
			if(a[i].checked) {
				notcheck = false;
			}
		}
	}
	if(notcheck) {
		request = getData("var","obj_notyp","",sess,"");
		alert(request);
		return(false);
	}

Автор: alex385723 (не зарегистрирован), дата: 10 февраля, 2012 - 01:09
#permalink

Помогите решить следующую проблему!

Создал объект.
Пробегаю по массиву (не по объекту) циклом. Элементы массива содержат строку, которая обычно повторяется по много раз, иногда в массиве таких строк несколько разных.

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

Таким образом должна получится схема такого типа:

Объект {

Свойство1: [строка, объект],
Свойство2: [строка, объект],
Свойство2: [[строка, объект],[строка, объект]]
Свойство2: [[строка, объект],[строка, объект],[строка, объект]]
Свойство3: [строка, объект]
Свойство4: [строка, объект]
...

}

Так вот там где многомерный массив, последний его элемент-массив недоступен. т.е. alert(Объект[свойство2]) выводит все кроме последнего вложенного массива (2).


Автор: zhenya (не зарегистрирован), дата: 2 марта, 2012 - 13:50
#permalink

Помогите новичку разобраться с обьектами. Правильно ли писать так как описано ниже?

function Rectangle(w, h) {
		(!w) ? this.width = 0 : this.width = w;
		(!h) ? this.heigth = 0 : this.heigth = h;
	}
Rectangle.prototype.area = function() {
		if (this.width == 0 || this.heigth == 0)
			alert("error");
		else
			return this.width * this.heigth;
	}

Автор: Гость (не зарегистрирован), дата: 25 марта, 2012 - 06:42
#permalink

Здравствуйте! Подскажите, как мне прочесть i-ый элемент массива для дальнейшего использования методом innerHTML?

Это не работает:

var arrText = new Array('Строка1','Строка2', ... ,'СтрокаN');
document.getElementById('Alert').innerHTML = arrText[i];

В зависимости от значения "i" должен читаться соответствующий элемент массива "arrText".

Заранее спасибо!


Автор: Гость (не зарегистрирован), дата: 21 апреля, 2012 - 18:41
#permalink

попробуй

var arrText =['Строка1','Строка2', ... ,'СтрокаN'];
document.getElementById('Alert').innerHTML = arrText[i];

Автор: Гость (не зарегистрирован), дата: 25 марта, 2012 - 10:59
#permalink

Люди почему у меня не работает библиотека???
Файл wnd.js

//Window functions...
var wnd = {};
wnd.new = function(name,content,val1,val2,ico,tit){
var id = Math.floor(Math.random() * 100);
if(tit){
document.getElementById('wnd').innerHTML += "<div id="+id+" style=\"position:absolute;top:"+val1+"px;left:"+val2+"px;background-color:#ff6600;\"><fieldset><legend><img src='"+ico+"' title=\"Открыть/Закрыть кнопки\" height=20 width=20 onClick=\"if(document.getElementById('"+id+"b').style.display == 'none'){document.getElementById('"+id+"b').style.display = 'inline';}else{document.getElementById('"+id+"b').style.display = 'none';}\"><span id='"+id+"b' style=\"display:none;\"><span onClick=\"wnd.close("+id+")\" title=\"Закрыть\">(X)</span><span title=\"Свернуть\" onClick=\"wnd.fold("+id+",'"+ico+"','"+name+"')\">(_)</span><span onClick=\"wnd.repos('"+id+"');\" title=Переместить>(+)</span></span>"+name+"</legend>"+content+"</fieldset></div>";
return id;
}
else{
}
document.getElementById('wnd').innerHTML += "<div id="+id+" style=\"position:absolute;top:"+val1+"px;left:"+val2+"px;background-color:#ff6600;\">"+content+"</div>";
return id;
};
wnd.close = function(id){
document.getElementById(id).innerHTML = '';
};
wnd.closeall = function(){
document.getElementById('pmenu').innerHTML = '';
document.getElementById('wnd').innerHTML = '';
};
wnd.fold = function(id,ico,name){
document.getElementById(id).style.display = 'none';
document.getElementById('pmenu').innerHTML += "<span id='"+id+"f'> | <img src='"+ico+"' height=20 width=20 onClick=\"if(document.getElementById('"+id+"fm').style.display == 'none'){document.getElementById('"+id+"fm').style.display = 'inline'}else{document.getElementById('"+id+"fm').style.display = 'none'}\" title=\"Открыть/Закрыть кнопки\"><span id='"+id+"fm' style=\"display:none;\"><span onClick=\"wnd.close("+id+");document.getElementById('"+id+"f').innerHTML = '';\" title=\"Закрыть\">(X)</span> | <span onClick=\"document.getElementById("+id+").style.display = 'inline';document.getElementById('"+id+"f').innerHTML = '';\" title=\"Развернуть\">([])</span></span><span onClick=\"document.getElementById("+id+").style.display = 'inline';document.getElementById('"+id+"f').innerHTML = '';\">"+name+"</span></span>";
};
wnd.repos = function(id){
x = prompt('Введите координату X:',document.getElementById(id).style.left);
y = prompt('Введите координату Y:',document.getElementById(id).style.top);
document.getElementById(id).style.top = y;
document.getElementById(id).style.left = x;
};
}

Файл wnd.html

<html>
<head>
<title>Библиотека wnd.js</title>
<script src=wnd.js></script>
</head>
<body>
<div id=wnd style="position:absolute"></div>
<div id=pmenu></div>
<button onClick="wnd.new('Привет','Привет!',0,0,'',1);">Открыть окно</button>
</body>
</html>

Вообще ничего не понять(((


Автор: Гость (не зарегистрирован), дата: 21 апреля, 2012 - 18:43
#permalink
<html>
<head>
<title>Библиотека wnd.js</title>
<script src="wnd.js"></script>
</head>
<body>
<div id="wnd" style="position:absolute"></div>
<div id="pmenu"></div>
<button onClick="wnd.new('Привет','Привет!',0,0,'',1);">Открыть окно</button>
</body>
</html>

Автор: Гость (не зарегистрирован), дата: 21 апреля, 2012 - 18:35
#permalink

Библиотека wnd.js

Открыть окно


Автор: Гость (не зарегистрирован), дата: 25 мая, 2012 - 16:33
#permalink

Создать массив из M элементов. М вводят с клавиатуры с прорверкой (оно должно быть не менее 12). Заполнить числовыми значениями с клавиатуры. Вывести на экран. Вывести позицию первого из элементов, который имеет значение, превышающее 50.

Как выполнить?


Автор: maksimr, дата: 26 мая, 2012 - 18:03
#permalink

Возможно это решение подойдет.

(function() {
    var size = prompt('Пожалуйста введите размер массива'),
        findBigNumber = function(arr) {
            var i = 0,
            len = arr.length, result;

            for (; i < len; i++) {
                if (parseInt(prompt('Введите значение элемента ' + i),10) > 50) {
                    result = result || i;
                }
            }
            return result || 'К сожалению в последовательности нет элемета со значением превышающим 50';
        };

    size = parseInt(size, 10);
    if (isNaN(size) || size < 12) {
        return alert('Длина массива должна быть больше либо равна 12');
    }

    collection = new Array(size);
    alert(findBigNumber(collection));
}());

Автор: Гость (не зарегистрирован), дата: 1 июня, 2012 - 00:08
#permalink

Почему не срабатывает метод объекта?
например объект:

var object = {
 	show:function (obj)// считывает список сообщений
	{	
	  alert(obj.tagName);
	}
}

вызываем так:

<li  onClick="object.show(this)">first</li>

Если передавать в onClick функции то все нормально


Автор: Bandicoot, дата: 27 июля, 2012 - 14:20
#permalink

Давно хотел спросить, почему при переборе в цикле не работает получение значения свойства объекта по точке:

var obj = {foo: "bar", a: 42};
for (var prop in obj) {
  console.log(obj.prop);
}
// выведет undefined, в то время как obj[prop] корректно выведет значения

Автор: Дзен-трансгуманист, дата: 28 июля, 2012 - 01:44
#permalink

Laugh
Да потому что обращение к свойству напрямую через точку (obj.prop) равносильно скобочной записи со строковым литералом (obj["prop"]):

var obj = { foo: "bar", a: 42, prop: "я ничего не понимаю в операторах доступа" };
for (var prop in obj) {
  alert(obj.prop);
}

Отличие скобочного оператора в том, что он используется как ассоциативный ключ, и в нем практически нет ограничений на используемые символы.


Автор: chlp (не зарегистрирован), дата: 2 июля, 2015 - 17:30
#permalink

Выводит undefined, т.к. обращаясь к obj.prop, вы обращаетесь к obj['prop'].


Автор: Mefistofel (не зарегистрирован), дата: 10 ноября, 2012 - 21:24
#permalink

Объясните кто-нибудь, не понимаю для чего нужна эта строчка:
vasya.sayName = sayName

// один и тот же метод в двух объектах
petya.sayName = vasya.sayName

Не понимаю что вообще делается в этих строчках и для чего они необходимы?


Автор: Родион Николаевич Юрьев (не зарегистрирован), дата: 3 мая, 2013 - 12:22
#permalink

А что тут такого? Методов я не вижу, есть два объекта со свойствами.
Существует объект vasya. У него, возможно, существует свойство sayName (его можно создавать и динамически). Этому свойству присваивается значение sayName.
Теперь мы берём другой свойство другого объекта petya.sayName и присваиваем ему значение свойства vasya.sayName. Важно, что здесь присвоение осуществляется не по ссылке. То есть, если мы после этого изменим vasya.sayName, то petya.sayName - не изменится.


Автор: Родион Николаевич Юрьев (не зарегистрирован), дата: 3 мая, 2013 - 12:22
#permalink

А что тут такого? Методов я не вижу, есть два объекта со свойствами.
Существует объект vasya. У него, возможно, существует свойство sayName (его можно создавать и динамически). Этому свойству присваивается значение sayName.
Теперь мы берём другой свойство другого объекта petya.sayName и присваиваем ему значение свойства vasya.sayName. Важно, что здесь присвоение осуществляется не по ссылке. То есть, если мы после этого изменим vasya.sayName, то petya.sayName - не изменится.


Автор: Гость (не зарегистрирован), дата: 12 ноября, 2012 - 18:25
#permalink

В статье рассказывается про перебор ключа и значения объекта а как осуществить пребор если объект вида obj={a:5,b:{c:7},d:3};


Автор: Родион Николаевич Юрьев (не зарегистрирован), дата: 3 мая, 2013 - 12:24
#permalink

Это делается вложенными циклами, либо, если заведомо известно, что вложенный объект не нужно итерировать, то добавляем условную конструкцию и когда доходим до такого объекта, что-то там отдельно делаем и идём дальше по циклу.


Автор: Гость (не зарегистрирован), дата: 15 ноября, 2012 - 12:27
#permalink

Комментарий: *


Автор: BlaMe (не зарегистрирован), дата: 27 марта, 2013 - 12:36
#permalink

function replace_string(j1,j2,j3){
var f=0;
var it='';
it = it + j1;
f=it.indexOf(j2);
while (f!=-1){
f=it.indexOf(j2);
if (f>0){
it = it.substr(0,f) + j3 + it.substr(f+j2.length);
};
};
return it
};
old_str ="Федоров Федор Федорович";
new_str= replace_string(old_str,"е","Е");
alert(new_str);

парни как тут вывести дополнительную строку которая бы выводила количество алгоритмов совершенных в этой функции а именно замен букв с маленьких до больших)


Автор: Гость (не зарегистрирован), дата: 26 августа, 2013 - 18:35
#permalink

Скажите пожалуйста почему может в QML такая конструкция не возвращает true в условии? Этот вызов происходит в рекурсивной функции. Если производить доступ на одном уровне итерации, то все окей, а если на следующем, то пишет, что нет такого свойства. Хотя оно было добавлено на предыдущих итерациях.

var key = item.toString().match(/\((.*?)\)/)[1]
//console.log(key)
if (key in group) {
console.log("EXIST")
} else {
//console.log("ADD")
group[key] = 1
}


Автор: FANTOM22A, дата: 22 января, 2014 - 03:05
#permalink

var o = {a:5, b:true}
for (var key in o) {
alert(key+':'+o[key])// почему так +o.key вместо значения undefined выводят?
}


Автор: @@@D@@@, дата: 29 марта, 2014 - 19:03
#permalink

Подскажите пожалуйста, как для объекта String добавить метод isAlnum(), который возвращает true если строка состоит только из букв латинского алфавита или цифр, и false - в противном случае???


Автор: Stanly (не зарегистрирован), дата: 22 октября, 2014 - 14:55
#permalink

В разделе 'Добавление свойств'
в примере:
var name = 'test'
o[name] = 5
ошибка. Вместо o[name] нужно писать o['test'].


Автор: наташа.гость, дата: 16 декабря, 2015 - 14:27
#permalink

document.getElementById('output').innerHTML = 'x1 = '+print((-B+Math.sqrt(D))/A, 0)+'x2 = '+print((-B-Math.sqrt(D))/A, 0);
else
document.getElementById('output').innerHTML = 'x1 = '+print(-B/A,Math.sqrt(-D)/A)+'x2 = '+print(-B/A,-Math.sqrt(-D)/A);

почему значение х выводится через запятую?
как это объяснить??

например :
х1=(0.6,0.3)
х2=(-0.2,0.4)


Автор: Гость (не зарегистрирован), дата: 9 января, 2016 - 06:06
#permalink

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

// эквивалентные записи
var o = new Object()
var o = {}

Реально не эквивалентны:
var o = new Object() - если объект существовал ранее и у него были определены свойства, то эти свойства продолжают существовать.
var o = {} - здесь при создании объект пустой, без свойств.


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
1 + 8 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Реклама
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum