2010-05-23 3 views
1

Вопрос заключается в следующем:Просто небольшая проблема относительно Javascript BOM вопрос

Создать страницу с числом звеньев. Затем напишите код, который запускается в событии onload окна, отображая href каждой из ссылок на странице.

И это мое решение

<html> 
<body language="Javascript" onload="displayLink()"> 
<a href="http://www.google.com/">First link</a> 
<a href="http://www.yahoo.com/">Second link</a> 
<a href="http://www.msn.com/">Third link</a> 

<script type="text/javascript" language="Javascript"> 
function displayLink() 
{ 
for(var i = 0;document.links[i];i++) 
{ 
alert(document.links[i].href); 
} 
} 
</script> 

</body> 
</html> 

Это ответ предоставляется по книге

<html> 
<head> 
<script language=”JavaScript” type=”text/javascript”> 
function displayLinks() 
{ 
var linksCounter; 
for (linksCounter = 0; linksCounter < document.links.length; linksCounter++) 
{ 
    alert(document.links[linksCounter].href); 
} 
} 
</script> 
</head> 
<body onload=”displayLinks()”> 
<A href=”link0.htm” >Link 0</A> 
<A href=”link1.htm”>Link 2</A> 
<A href=”link2.htm”>Link 2</A> 
</body> 
</html> 

Перед тем, как попасть в яваскрипта учебник о том, как проверить версию браузера пользователя или модели, я использовал тот же метод, что и в примере, путем использования свойства length массива links для цикла, но после того, как я прочитал учебное пособие, я узнаю, что я также могу использовать эти альтернативные способы, используя метод, который условие теста будет проверять на true, только если document.links[i] вернет действительное значение, поэтому мой код написан с использованием действительного метод? Если это не так, любой комментарий относительно того, как писать лучший код? Исправьте меня, если я ошибаюсь, я слышал, что некоторые из людей говорят: «Хороший код не оценивает только, работает ли он или нет, но в условия скорости, способность понимать код и могли бы позволить другим легко понять код ». Это правда?

+0

Да, это правда. –

ответ

5

В общем, при переходе по массиву вы хотите использовать его свойство length в качестве решения книги. Ваше решение должно быть прекрасным в этой ситуации , в частности,, но оно имеет слабость: оно отлично подходит для записи в массиве 0, null, undefined или false, все из которых являются «ложными» значениями и поэтому document.links[i] может быть ложным, даже если вы не были в конце массива.

Пример:

var index, a; 
a = [3, 2, 1, 0, -1, -2]; 
for (index = 0; a[index]; ++index) { 
    alert(a[index]); 
} 

Это предупредит 3, 2 и 1, но затем останавливается. Сравните:

var index, a; 
a = [3, 2, 1, 0, -1, -2]; 
for (index = 0; index < a.length; ++index) { 
    alert(a[index]); 
} 

... который предупредит 3, 2, 1, 0, -1 и -2.

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

(Существует новый, новый способ циклического перехода через записи массива с новой спецификации 5-го издания: функция forEach. Вы даете ей функцию, и она вызывает ее для каждого элемент в массиве. Details in this other answer.. к сожалению, IE8 не поддерживает его, но это одна из вещей, которые могут быть «подкладками»   — поиска «ES5 прокладки» для нескольких вариантов.)

при изучении массивов, важно знать, что массивы Javascript сильно отличаются от массивов на большинстве других языков.Во-первых, они не являются (обязательно) массивами; на самом деле, это обычные объекты Javascript с добавлением нескольких специальных функций. Объекты Javascript - это карты свойств, они сопоставляют ключи со значениями. Например:

var obj = {foo: 1}; 

Это obj объект отображает ключ "foo" (строка) к значению 1. Вы можете получить доступ к этому свойству либо с использованием буквального имени в вашем коде, либо с помощью [] и строки. И, конечно, если вы делаете последнее, вы можете использовать любую строку (литерал или переменную или из выражения и т. Д.). Таким образом, все они имеют тот же результат:

x = obj.foo; 
x = obj["foo"]; 
name = "foo"; 
x = obj[name]; 
name = "o"; 
x = obj["f" + name + name]; 

... вы получаете идею; до тех пор, пока то, что вы используете в пределах [], оценивает строку, вы можете найти значение с помощью этого ключа. Но Javascript также делает неявное принуждение, так это работает:

var obj = {"1": "one"}; 
alert(obj[1]); // alerts "one" 

Там я сопоставляются свойство с именем "1" к значению "one". Но затем я просматриваю его с помощью obj[1], используя число, а не строку. Это нормально, интерпретатор превратит его в строку для меня, а затем выполнит поиск по ключевым словам.

Что все это связано с массивами? Это: Индексы массива - это просто имена собственности. Массив Javascript нормальный объект, который отображает ключи от значений, с этими особенностями:

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

    var a = ["zero"]; 
    alert(a.length); // alerts 1 
    a[3] = "three"; 
    alert(a.length); // alerts 4, because the max index is now 3 
    
  • Всякий раз, когда вы установите length, если есть свойства с числовыми именами, которые имеют значение, большее или равное новую длину, эти свойства удаляются из объекта.

    var a = ["zero", "one", "two", "three"]; 
    alert(a[3]); // alerts "three" 
    a.length = 3; 
    alert(a[3]); // alerts "undefined", the "3" property has been deleted 
          // only the "0", "1", and "2" properties remain 
    
  • Они имеют различные свойства функций, которые они наследуют от Array.prototype, как join или splice.

Всё. Ничто не похоже на массивы в C, C++, Java или большинстве других языков.

Поскольку массивы являются только объекты с несколькими дополнительными функциями, вы можете поставить другие, не-числовые свойства массивов, если вы хотите:

var a = ["zero", "one", "two"]; 
a.foo = "bar"; 
alert(a[1]);  // alerts "one", 1 is implicitly coerced to "1" 
alert(a["1"]); // alerts "one" 
alert(a.foo);  // alerts "bar" 
alert(a["foo"]); // alerts "bar" 

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

var a, name; 
a = [1, 2, 3]; 
a.foo = "bar"; 
for (name in a) { 
    alert(name); 
} 

Это предупреждает "1", "2", "3" и "foo" (в определенном порядке). Вы можете видеть, как, если бы вы предположили, что это просто индексы массивов, у вас будут проблемы!Вы можете использовать его для цикла индексов массива, но это сложнее, чем это стоит:

for (name in a) { 
    if (String(Number(name)) === name && a.hasOwnProperty(name)) { 
     alert(name); 
    } 
} 

что сначала проверяет, если имя свойства является числом, а затем проверяет, что свойство определяется на a, а не Array.prototype (помните, что массивы наследуют свойства от прототипа Array). (Чтобы быть справедливым, эта последняя проверка, вероятно, не так уж важна, если кто-то добавляет свойства с численным именем в прототип Array, они делают очень плохое поведение (tm).)

+1

+1 Я рассмотрел этот вопрос, но я бы предпочел бы получить этот ответ. Это одно из лучших объяснений, которые я когда-либо читал (более 15 лет). – GitaarLAB

0

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

Давайте посмотрим на некоторые различия и некоторые проблемы в вашем коде, и при условии ответа:

  • Вы пропускаете раздел в HTML-документе head. Требуется, чтобы документ был действительным HTML.

  • В прилагаемом ответе отсутствует тег title в head, что также необходимо.

  • Тег Javascript должен быть предпочтительно в разделе документа head. Он работает, чтобы иметь теги сценария в теле, но это нестандартно, поэтому его следует избегать, если для этого нет особых причин.

  • Теги сценария имеют атрибут language, который устарел на века, ему нужен только атрибут type.

  • Вы используете переменную i для циклизации, которая является хорошо известной конвенцией. Предоставление описательных имен для переменных является еще одним аспектом хорошего кодирования, но это не означает, что каждая переменная должна иметь длинные имена. Некоторые переменные, которые используются для легко узнаваемой цели, такие как счетчики циклов, могут иметь короткие имена.

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

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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
    <title>Links test</title> 

    <script type="text/javascript"> 

    function displayLink() { 
    for(var i = 0; i < document.links.length; i++) { 
     alert(document.links[i].href); 
    } 
    } 

    </script> 

</head> 
<body onload="displayLink();"> 

    <div> 
    <a href="http://www.google.com/">First link</a> 
    <a href="http://www.yahoo.com/">Second link</a> 
    <a href="http://www.msn.com/">Third link</a> 
    </div> 

</body> 
</html> 
+1

Спасибо за так много экспертов здесь !!!! Я не могу удержаться, чтобы сказать, что вы, ребята, очень страстные и полезные !!!! Я прочитаю комментарий и совет, которые даны позже, и принять твердое решение, по которому лучший ответ, хотя я думаю, что каждый дает ответ очень хорошо !!!! Снова спасибо – caramel1995

Смежные вопросы