Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Использование for in (https://javascript.ru/forum/misc/51040-ispolzovanie.html)

terminator-101 22.10.2014 04:12

Использование for in
 
Считается, что for in медленный. Это действительно так, но я ща подумал, он сука, медленный не столько сам по себе, сколько из-за этого:

proto={a: 1, b: 2, c: 3, d: 4, e: 5}
ob=Object.create(proto)
ob.foo=10
ob.bar=20
ob.baz=30

monkeyFu=function(){
   for(var i in this){
      if(this.hasOwnProperty(i)){
          console.log("Monkey do stuff with "+ this[i])
      }
      console.log("Monkey usage: "+this[i])
   }
}

normalFu=function(){
   for(var i in this){
      if(!(this.hasOwnProperty(i))) break
      console.log("Right usage: "+this[i])
   }
}

monkeyFu.call(ob)
normalFu.call(ob)

//  Monkey do stuff with 10
//  Monkey usage: 10
//  Monkey do stuff with 20
//  Monkey usage: 20
//  Monkey do stuff with 30
//  Monkey usage: 30
//  Monkey usage: 1
//  Monkey usage: 2
//  Monkey usage: 3
//  Monkey usage: 4
//  Monkey usage: 5
//  Right usage: 10
//  Right usage: 20
//  Right usage: 30

Именно так его обычно пользуют. А цепочка прототипов может ведь состоять и из тыщи объектов. Соответственно, если нужны только свойства самого объекта, без прототипов, использование по типу monkeyFu просто недопустимо. Это серьезный косяк.

skrudjmakdak 22.10.2014 08:28

Цитата:

Сообщение от terminator-101 (Сообщение 336843)
А цепочка прототипов может ведь состоять и из тыщи объектов.

теоретически да. а по факту к сожалению мне не удавалось видеть объект унаследованный из 1000 и более объектов. может более опытные программисты видели))

tsigel 22.10.2014 10:15

skrudjmakdak,
Имеется в виду что в прототипе могут лежать тысячи свойств и при этом не обязательно иметь цепоочку в 1000 наследований. Достаточно 2 наследования по 500 свойств.

Вообще есть метод Object.getOwnPropertyNames, если забить на старые браузеры. Если совсем заморачиваться можно сделать чтобы каждый объект хранил в себе массив своих ключей, но проще не использовать for in там где нужна скорость.

terminator-101 22.10.2014 10:30

tsigel,
Достаточно делать

if(!(this.hasOwnProperty(i))) break

вместо

if(this.hasOwnProperty(i)){...

И все будет норм. Я об этом

tsigel 22.10.2014 10:47

terminator-101,
Возможны косяки в старых браузерах, хотя не проверял.

danik.js 22.10.2014 10:51

Цитата:

Сообщение от tsigel
Object.getOwnPropertyNames

Есть ES5 Object.keys, есть es5-shim, так что не обязательно забивать. Кстати в чем разница между этими методами?

terminator-101, а почему ты игнорируешь свойства из прототипа?

terminator-101 22.10.2014 10:55

Цитата:

Сообщение от danik.js
а почему ты игнорируешь свойства из прототипа?

Потому что если мы используем hasOwnProperty предполагается, что нам прототипы не нужны. Поэтому лучше выйти, чтобы не тратить время на бесполезный перебор. А если нужны, то тогда конечно не нужно. Я про случай, когда не нужны.

danik.js 22.10.2014 11:26

terminator-101, а что говорит ECMA спецификация о порядке обхода свойств?

terminator-101 22.10.2014 11:35

Цитата:

Сообщение от danik.js
говорит ECMA спецификация о порядке обхода свойств?

Не знаю, но из примера видно, что обход идет от начала, от объекта.

Octane 22.10.2014 12:13

Цитата:

Сообщение от danik.js
Кстати в чем разница между этими методами?

getOwnPropertyNames возвращает все свойства, в том числе enumerable:false

kostyanet 22.10.2014 15:52

Цитата:

Сообщение от terminator-101
Достаточно делать

if(!(this.hasOwnProperty(i))) break

В смысле не продлевать? А кто продлевает если нет смысла?

terminator-101 22.10.2014 16:25

Цитата:

Сообщение от kostyanet
А кто продлевает если нет смысла?

Да сколько кода я не наблюдал, я вообще брейк никогда не видел. Похоже разрабы вообще не понимают обычно процесс итерации.

kostyanet 22.10.2014 16:40

Есть такое дело, break и continue неведомы многим, а некоторыми даже порицаются, я уж не говорю о таком кощунстве как return из тела цикла, как из тела кусок вырываешь понимаешь.

Erolast 22.10.2014 16:48

Цитата:

Сообщение от terminator-101 (Сообщение 336843)
Считается, что for in медленный. Это действительно так, но я ща подумал, он сука, медленный не столько сам по себе, сколько из-за этого:

//говнокод

Именно так его обычно пользуют. А цепочка прототипов может ведь состоять и из тыщи объектов. Соответственно, если нужны только свойства самого объекта, без прототипов, использование по типу monkeyFu просто недопустимо. Это серьезный косяк.

Охренеть сенсация.

terminator-101 22.10.2014 16:48

Цитата:

Сообщение от kostyanet
Есть такое дело, break и continue неведомы многим, а некоторыми даже порицаются, я уж не говорю о таком кощунстве как return из тела цикла, как из тела кусок вырываешь понимаешь.

Да, это все херовое влияние двух дурачков -- Дейкстры и Вирта

kostyanet 22.10.2014 18:00

Цитата:

Сообщение от Erolast
Охренеть сенсация.

Тут сам постановка интереса: это сколько надо написать чтобы задуматься о быстроте форичей?

Насколько я вижу этот сайт целиком на js работает и вроде не тормозит. Может мало форичей, то есть форинов?

terminator-101 23.10.2014 10:56

Цитата:

Сообщение от kostyanet
о быстроте форичей?

Кстати, если уж зашел разговор о быстроте форичей, то тут при помоши нелокальных выходов тоже можно выжать немало, +еще кое-какие плюшки.
arr=[1, 2, 3, 4, 5]

throw_=function(wanted, x){if(x===wanted) throw x}
return_=function(wanted, x){if(x===wanted) return x}

main=function(wanted, f, comment){
try{
arr.forEach(function(x){console.log(comment+": "+x); f(wanted, x)})
}catch(ret){return ret}
}

console.log("from throw_ call: "+main(3, throw_, "throw"))
console.log("from return_ call: "+main(3, return_, "return"))

kobezzza 27.10.2014 09:59

ECMAScript говорит
Цитата:

Механизм и порядок перечисления свойств (шаг 6.a в первом алгоритме и шаг 7.a во втором алгоритме) не указан. Свойства перечисляемого объекта могут быть удалены во время перечисления. Если свойство, ещё не посещённое при перечислении, удаляется, то оно не будет посещено. Если во время перечисления к объекту добавляются новые свойства, их посещение в процессе текущего перечисления не гарантируется. Одно имя свойства нельзя посетить более одного раза во время перечисления.
Поэтому уповать на последовательность свойств нельзя.


Часовой пояс GMT +3, время: 09:53.