JS prototype возвращает код прототипа - PullRequest
2 голосов
/ 25 января 2011
Array.prototype.last = function() { if(this.length !=0) return this[this.length-1]; }
myarray = new Array(1,2,3);
  for(var i in myarray){
  alert(i+'='+myarray[i]);
}

Когда вышеуказанный код выполняется, он корректно предупреждает каждый цикл, но затем в конце появляется другое предупреждение с источником метода Array.prototype.last.

Это происходит всякий раз, когда я определяю какой-либо метод-прототип, и я просто не знаю почему!

Итак, я получаю оповещения для: 0 = 1,1 = 2,2 = 3, а затем один для:

last=function () {
  if (this.length != 0) {
    return this[this.length - 1];
  }
}

Ответы [ 3 ]

6 голосов
/ 25 января 2011

Это потому, что оператор for-in перечисляет свойства объекта, включая унаследованные.

Это одна из причин, по которой использование оператора for-in с массивами или массивоподобных объектов считается плохой практикой.

Другие причины включают то, что порядок перечисления не гарантируется спецификацией, это означает, что свойства индекса могут не посещаться в числовом порядке, например:

var a = [];
a[1] = 'b';
a[0] = 'a'

for (var prop in a) { console.log(i); }

Большинство браузеров обнаружат, что вы пытаетесь перебрать по массиву, и свойства будут посещаться в числовом порядке, но в IE свойства будут перечислены в порядке их создания, 1, а затем 0.

Также известно, что оператор for-in может быть медленнее, чем простой последовательный цикл, потому что, как вы теперь знаете, ему необходимо проанализировать всю цепочку прототипов объекта, чтобы перечислить унаследованные члены.

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

Смотри также:

0 голосов
/ 25 января 2011

Это потому, что last - это функция, которую myarray извлекает из свойств прототипа и индексируется.Чтобы избежать этого, вам нужно проверить hasOwnProperty, например:

for(var i in myarray)
{
  if(myarray.hasOwnProperty(i))
    alert(i+'='+myarray[i]); 
}
0 голосов
/ 25 января 2011

Вот почему вы никогда не используете for(idx in anArray){...} в javascript, цикл for ... in перебирает все свойства в object, а Array это просто object JS, вы добавили новое свойство ко всем экземплярам Array, чтобы оно отображалось как один из индексов в цикле for.

с массивами, как правило, вы должны сделать:

for(var i=0 ; i< anArray.length ; i++){
    //do stuff
}
...