Конструкция for..in
- единственный в javascript способ перебрать все свойства объекта.
var a = {
p1: 1,
p2: 2
}
for(var p in a) {
alert(p) // p1, затем p2
// к значению каждого свойства прибавить 1
a[p] = a[p] + 1
}
Большинство свойств встроенных объектов javascript перебираться в цикле for..in
не будут, так как помечены специальным внутренним флагом DontEnum
.
Этот флаг нельзя получить или поменять.
Пример: встроенное свойство toString
// объявим объект
var a = {
p1: 1
}
// у него есть свойство toString
alert(a.toString)
// унаследованное от Object.prototype
alert(a.toString === Object.prototype.toString) // true
for(p in a) {
// в этом цикле свойства toString не будет
alert("Property name:"+p+" value:"+a[p])
}
Порядок перечисления свойств не определен.
Поэтому, если во время итерации добавить свойство к объекту - цикл может по нему пройти позже или не пройти никогда, в зависимости от того, куда это новое свойство встанет во внутренней хэш-таблице интерпретатора javascript.
При удалении свойства во время итерации - если цикл по нему еще не прошел, то он не пройдет в дальнейшем.
Перебор свойств, кроме унаследованных
Для перебора всех свойств объекта, кроме унаследованных, используется конструкция for..in
с дополнительной проверкой.
for(var prop in object) {
// если свойство унаследовано - continue
if (!object.hasOwnProperty(prop)) continue
// работа с prop
...
}
В следующем примере свойство print
участвовало бы в цикле, если бы там не было проверки.
Пример: пербор без унаследованных свойств
Object.prototype.print = function() {
document.write(this)
}
var a = {
p1: 1,
p2: 2
}
for(var p in a) {
if (!a.hasOwnProperty(p)) continue
alert(p)
}
Не всегда легко обращаться к свойству в цикле for..in. Вот пример, где это не работает. Вопрос: почему?
Конкретизируйте проблему - что не работает? Возможно, свойство имеет флаг
DontEnum
?К "selectionStart" обратиться нельзя, т.к. el[prop] - вызывает ошибку
Если бы у свойства "selectionStart" было DontEnum, разве оно попало бы в for..in?
возможно, el[prop] просто не может быть приведено к строке?
В JS есть что-то, что нельзя привести к строке?
у input типа "radio" нет свойства selectionStart.
selectionStart есть, например, у типа "text".
Если заменить radio на text, то скрипт работает
Не работает рекурсия :
g.setHTML=function(dt,lev,p){
for (var i in dt){
var l=document.createElement("div");
l.className=g.struc['levelel'][lev]['funcstyle'];
p.appendChild(l);
var fn=_gr.elem[g.struc.levelel[lev].name].name;
var f=eval(fn+"(dt[i]['par'],g.struc.levelel[lev].funcstyle)");
l.appendChild(f.graph.body);
if (dt[i]['node']){g.setHTML(dt[i]['node'],lev+1,l);};
}
};
Проходит одну ветвь находя первые значения.
То есть такое ощущение,что передаваемая переменная dt является глобальной.
Как организовать рекурсию?(в php подобный код работает)
Мне кажется, причина в том, что через аргумент функции объекты передается не как новые объекты, а как указатели. Т.е. все рекурсивные вызовы будут указывать на один и тот же объект, переданный при вызове функции.
Где-то в теле надо через new создавать новый объект dt.
Здравствуйте, скажите, а можно ли перебирать свойства сразу 2-х объектов одним счетчиком?
Нет.
var x = {x: 1};
var y = {y: 2};
for(var i in x, y)
{
// что находится в i на первой итерации?
}
Здравствуйте, подскажите пожалуйста, как получить значение всех свойств age, не объявляя имена объектов в которых они находятся.
Может кому-то пригодиться
function userArray(arr) {
for (var item in arr) {
if (arr[item].name) {
console.log('name=' + arr[item].name + ' age=' + arr[item].age);
}
else {
userArray(arr[item]);
}
}
}
userArray(massiveA);
Подскажите, кто-нибудь, как будет вести себя метод, если объект будет пуст. Сразу пропуск к следующей команде? Или out of bounds?