LINUX.ORG.RU

Вопрос по объектам в JavaScript

 ,


0

1

К примеру создали объект с такими свойствами:

var object = {
    p0: 0,
    p1: 1,
    p2: 2,
    p3: 3,
    p4: 4,
    p5: 5
}
Считается(?), что в JavaScript мы не можем обращаться к свойству объекта по его индексу, как это можно делать с обычным массивом, потому, что порядок следования свойств кешируется, как это угодно JS и не наше это дело, знать как чередуются индексы:
document.write("object[1]: " + object[1]);
выведет, что свойство object под индексом [1] равно «undefined»: object[1]: undefined .

Но почему тогда для for ... in эти индексы доступны и они соответсвуют порядку их прописывания?

for (property in object) {
    document.write(property + ": " + object[property] + "<br />");
}
получаем как и ожидается, как-будто это индексы массива:
p0: 0
p1: 1
p2: 2
p3: 3
p4: 4
p5: 5
Почему, когда мы пишем в определенном порядке массив и объект, то индексы доступны для массивов, но не объектов, хотя for ... in перебирает их именно в том же порядке, как если бы мы перебирали массив?


Кто-то очень сильно путает индексы и значения в словарике.

bj ()
Ответ на: комментарий от kiotoze

Ты обращаешься по свойству, а мой вопрос заключается в том, почему нельзя обращаться по индексу, если они (свойства объекта) чередуются в том же порядке, что и при создании объекта, как если бы мы создавали массив [0, 1, 2, 3, 4, 5].

slon ()
Ответ на: комментарий от bj

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

slon ()
Ответ на: комментарий от slon

может потому что что там организовано все списком?

// не знаю как на самом деле. просто предположение.

anonymous ()
Ответ на: комментарий от slon

ведь for ... in их перебирает именно в том же порядке

Нет не именно. Это неопределенное поведение.

bj ()

ты опять выходишь на связь

umren ★★★★★ ()
Ответ на: комментарий от slon

for … in перебирает не индексы, а имена свойств объекта.

Обращаться к значениям свойств можно как obj['name'], либо obj.name.

При попытке обратиться к свойству объекта, передав в качестве имени что-то помимо строки, происходит вызов метода .toString().

tensai_cirno ★★★★★ ()
Ответ на: комментарий от bj

неопределенное поведение.

Не подскажешь, в каких случаях for ... in обработает (например выведет в браузер через document.write) свойства не в том порядке, в котором они указаны при создании объекта или текущем содержимом объекта при его обработке?

slon ()
Ответ на: комментарий от tensai_cirno

for … in перебирает не индексы, а имена свойств объекта.

да, но он (если я не ошибаюсь, просто не видел другого поведения) перебирает их в том же порядке, как-будто это индексы массива.

Если это не так, то см. выше вопрос.

slon ()
Ответ на: комментарий от slon

у меня вот при таком вот

                    var object = {
                        p0: 0,
                        p1: 1,
                        test: "oops",
                        p2: 2,
                        p3: 3,
                        p4: 4,
                        p5: 5
                    }
выдает
0
1
2
3
4
5
oops

ossa ()
Ответ на: комментарий от slon

да, но он (если я не ошибаюсь, просто не видел другого поведения) перебирает их в том же порядке, как-будто это индексы массива.

Не обязан.

Нет, конечно если взять объект, инициировать сразу с тремя свойствами p0, p1, p2, то возможно оно и будет так. А если это будет на протяжении жизни приложения, в котором будет несколько десятков тысяч свойств?

tensai_cirno ★★★★★ ()
Ответ на: комментарий от ossa

Странно, а у меня chromium-42.0.2311.60 и firefox-36.0.1 выдают в том же, что и при создании:

p0: 0
p1: 1
test: oops
p2: 2
p3: 3
p4: 4
p5: 5

slon ()
Ответ на: комментарий от slon

Читай: http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.4

The mechanics and order of enumerating the properties (step 6.a in the first algorithm, step 7.a in the second) is not specified. Properties of the object being enumerated may be deleted during enumeration. If a property that has not yet been visited during enumeration is deleted, then it will not be visited. If new properties are added to the object being enumerated during enumeration, the newly added properties are not guaranteed to be visited in the active enumeration. A property name must not be visited more than once in any enumeration.

tensai_cirno ★★★★★ ()
Ответ на: комментарий от slon

Повторяю ещё раз, они могут идти абсолютно в любом порядке.

tensai_cirno ★★★★★ ()
Ответ на: комментарий от tensai_cirno

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

slon ()
Ответ на: комментарий от tensai_cirno

Ясно, ну окей тогда. Сейчас попробую с реально большими объектами и при динамичном их создании в несколько стадий.

Тогда вопрос закрываю, раз так.

slon ()
Ответ на: комментарий от slon

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

Я не знаю, что ты хочешь сделать, но вероятно для этого стоит воспользоваться массивами.

tensai_cirno ★★★★★ ()

почитай про атрибут enumerable свойства объекта, это как раз то :)

var a = { 
         x: 1,
         z: "foo"
}
Object.defineProperty(a, "x", {
        enumerable: false
})
for ( key in a ) { 
        console.log(a[key]) //foo
} 
console.log(a["x"],a["z"]) //1, foo

invokercd ★★★★ ()

эти индексы доступны и они соответсвуют порядку их прописывания?

У тебя там доступны не «эти» индексы. В конструкции for in переменная указывает не на порядковый номер, а на имя свойства.

theKingOfJava ()
Ответ на: комментарий от makoven

И что же тебя напугало? o[«foo»]=«bar» не пугает случайно? В выражении o[1] единица — это строковое значение, это просто сахар. Тебя должно пугать не это, а то что ты язык не понимаешь, а пытаешься о нем рассуждать.

theKingOfJava ()
Ответ на: комментарий от theKingOfJava

Не пугает, а путает. А то, что паралельно пишу в lua:

#:~ lua
Lua 5.2.4  Copyright (C) 1994-2015 Lua.org, PUC-Rio
> o = {}
> o[1] = "1"
> = o[1]
1
> = o['1']
nil

makoven ★★★★★ ()
Ответ на: комментарий от makoven

Сейчас в JS тоже появилась аналогичная возможность — появилась структура Map, в которой в качестве ключей можно использовать любые типы объектов, не только строки. Только нахрен это нужно, я хз, пока не понял.

theKingOfJava ()
Ответ на: комментарий от theKingOfJava

Только нахрен это нужно, я хз, пока не понял.

Наверное как-то так:

//Было:
if(it_obsessed[cats[666].id]) kill(cats[666])
//Стало
if(it_obsessed[cats[666]]) kill(cats[666])

Еще для нормальных enum-ов, c помошью появившегося Symbol. Енумы через строки плохой тон

makoven ★★★★★ ()
Последнее исправление: makoven (всего исправлений: 1)
Ответ на: комментарий от slon

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

loz ★★★★★ ()

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

Aswed ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.