关于javascript BOM问题的一个小问题 [英] Just a small problem regarding javascript BOM question

查看:46
本文介绍了关于javascript BOM问题的一个小问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题是这样的:

创建包含许多链接的页面.然后编写在窗口onload事件上触发的代码,显示页面上每个链接的href.

这是我的解决方法

 < html>< body language ="Javascript" onload ="displayLink()">< a href ="http://www.google.com/">第一个链接</a>< a href ="http://www.yahoo.com/">第二链接</a>< a href ="http://www.msn.com/">第三链接</a>< script type ="text/javascript" language ="Javascript">函数displayLink(){for(var i = 0; document.links [i]; i ++){警报(document.links [i] .href);}}</script></body></html> 

这是书中提供的答案

 < html>< head>< script language ="JavaScript" type ="text/javascript">函数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">链接0</A>< A href ="link1.htm">链接2</A>< A href ="link2.htm">链接2</A></body></html> 

在进入有关如何检查用户浏览器版本或模型的JavaScript教程之前,我使用了与示例相同的方法,方法是访问 links的 length 属性数组作为循环,但是在阅读了本教程之后,我发现我也可以使用这种替代方法,即使用仅在 document.links [i] 返回有效值,那么我的代码是否使用有效方法编写?如果不是,则有关如何编写更好代码的任何注释?如果我写错了,请纠正我,我听到了一些人们说:好的代码并不仅仅根据其是否有效来评估,而是在速度,理解代码的能力上,并且可能使其他人容易理解代码."是真的吗?

解决方案

通常,在遍历数组时,您要像本书的解决方案一样使用其 length 属性.您的解决方案在这种特殊情况下也应该很好,但是它有一个缺点:数组中的条目为 0 null完全有效 undefined false ,它们都是"falsey"值,因此 document.links [i] 可能为false即使您不在数组的末尾.

示例:

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

这将提醒 3 2 1 ,但是会停止.比较:

  var索引,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(a中的索引).通常,不要用它来遍历数组索引,它是基于对 for..in 的作用的误解.(有关此内容的更多信息.)

(从第5版新规范开始,添加了另一种遍历数组项的新方法: forEach 函数.您给它提供一个函数,并针对每个元素调用该函数详细信息.可悲的是,IE8不支持它,但这是可以填充"的内容之一-搜索"es5 shim"以获得多个选项.)

在学习数组时,重要的是要知道Javascript数组与大多数其他语言中的数组有很大的不同.一方面,它们根本不是(不一定)数组.实际上,它们只是添加了一些特殊功能的普通Javascript对象.Javascript对象是属性映射,它们将键映射到值.例如:

  var obj = {foo:1}; 

obj 对象将键"foo" (字符串)映射到值 1 .您可以通过在代码中使用文字名称或使用 [] 和字符串来访问该属性.当然,如果要使用后者,则可以使用任何字符串(文字,变量或表达式等).因此,所有这些都具有相同的结果:

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

...你明白了;只要您在 [] 中使用的内容评估为字符串,就可以使用该键查找值.但是Javascript也可以执行隐式强制,因此可以正常工作:

  var obj = {"1":一个"};alert(obj [1]);//提醒一个" 

我已经将名为"1" 的属性映射到值"one" .但是然后我用数字而不是字符串用 obj [1] 查找它.没关系,解释器会为我将其转换为字符串,然后进行键查找.

所有这些与数组有什么关系?这:数组索引只是属性名称.Javascript数组是将键映射到值的普通对象,具有以下特殊功能:

  • 每当您设置一个其名称可以解释为数字的属性时,如果该数字大于数组中当前存在的最大索引,则 length 属性就会更改.所以:

      var a = ["zero"];警报(a.length);//警报1a [3] =三个";警报(a.length);//警告4,因为最大索引现在为3 

  • 每当您设置 length 时,如果某些属性的数字名称的值大于或等于新的长度,则会从对象中删除这些属性.

      var a = [零",一个",两个",三个"];警报(a [3]);//提醒三"a.length = 3;警报(a [3]);//警报未定义","3"属性已删除//仅保留"0","1"和"2"属性 

  • 它们具有从Array.prototype继承的函数的各种属性,例如 join splice .

就是这样.完全没有像C,C ++,Java或大多数其他语言中的数组一样.

由于数组只是具有几个额外功能的对象,因此,如果需要,您可以在数组上放置其他非数字属性:

  var a = [零",一个",两个"];a.foo ="bar";警报(a [1]);//警报一个",将1隐式强制为"1"alert(a ["1"]);//提醒一个"警报(a.foo);//提醒酒吧"alert(a ["foo"]);//提醒酒吧" 

这是 for..in 发生故障的地方:因为 for..in 不会 not 遍历数组索引,因此遍历属性名称:

  var a,名称;a = [1、2、3];a.foo ="bar";为(名称中的a){警报(名称);} 

此警报"1" "2" "3" "foo" ((无特定顺序).您会看到,如果您假设它只是对数组进行索引,那您将遇到麻烦了!您可以使用它来循环数组索引,但是它比它的价值还要复杂:

  for(a中的名称){如果(String(Number(name))=== name&& a.hasOwnProperty(name)){警报(名称);}} 

首先检查属性名称是否为数字,然后检查该属性是在 a 本身上定义的,而不是在Array.prototype上定义的(请记住,数组是从数组原型).(为公平起见,后面的检查可能并不那么重要;如果有人向Array原型添加以数字命名的属性,那么他们做的事情很糟糕(tm).)

The question is this:

Create a page with a number of links. Then write code that fires on the window onload event, displaying the href of each of the links on the page.

And this is my solution

<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>

This is the answer provided by the book

<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>

Before I get into the javascript tutorial on how to check user browser version or model,I was using the same method as the example,by acessing the length property of the links array for the loop,but after I read through the tutorial,I find out that I can also use this alternative ways,by using the method that the test condition will evalute to true only if the document.links[i] return a valid value,so does my code is written using the valid method??If it's not,any comment regarding how to write a better code??Correct me if I'm wrong,I heard some of the people say "a good code is not evaluate solely on whether it works or not,but in terms of speed,the ability to comprehend the code,and could posssibly let others to understand the code easily".Is is true??

解决方案

In general, when looping through an array, you want to use its length property as the book's solution did. Your solution should be just fine in this particular situation as well, but it has a weakness: It's perfectly valid for an entry in an array to be 0, null, undefined, or false, all of which are "falsey" values and so document.links[i] could be false even though you weren't at the end of the array.

Example:

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

That will alert 3, 2, and 1, but then stop. Compare to:

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

...which will alert 3, 2, 1, 0, -1, and -2.

You might see code that looks like this: for (index in a). In general don't use that to loop through array indexes, it's based on a misconception of what for..in does. (More on that below.)

(There is another, new way of looping through array entries has been added as of the new 5th edition specification: The forEach function. You give it a function, and it calls it for each element in the array. Details in this other answer.. Sadly, IE8 doesn't support it, but it's one of the things that can be "shimmed" — search for "es5 shim" for multiple options.)

When learning about arrays, it's important to know that Javascript arrays are very different from arrays in most other languages. For one thing, they're not (necessarily) arrays at all; in fact, they're just normal Javascript objects with a couple of special features added on. Javascript objects are property maps, they map keys to values. For instance:

var obj = {foo: 1};

That obj object maps the key "foo" (a string) to the value 1. You can access that property either by using a literal name in your code, or by using [] and a string. And of course, if you're doing the latter, you can use any string (literal or from a variable or from an expression, etc.). So all of these have the same result:

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

...you get the idea; as long as what you use within the [] evaluates to a string, you can look up the value using that key. But Javascript also does implicit coercion, so this works:

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

There I've mapped a property named "1" to the value "one". But then I look it up with obj[1], using a number rather than a string. That's okay, the interpreter will turn it into a string for me and then do the key lookup.

What does all of this have to do with arrays? This: Array indexes are just property names. A Javascript array is a normal object that maps keys to values, with these special features:

  • Whenever you set a property whose name can be interpreted as a number, if that number is greater than the current maximum index present in the array, the length property is changed. So:

    var a = ["zero"];
    alert(a.length); // alerts 1
    a[3] = "three";
    alert(a.length); // alerts 4, because the max index is now 3
    

  • Whenever you set length, if there are properties with numeric names that have a value greater than or equal to the new length, those properties are deleted from the object.

    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
    

  • They have various properties for functions they inherit from the Array.prototype, like join or splice.

That's it. Nothing at all like arrays in C, C++, Java, or most other languages.

Since arrays are just objects with a couple of extra features, you can put other, non-numeric properties on arrays if you want to:

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"

And this is where the for..in thing breaks down: Because for..in does not loop through array indexes, it loops through property names:

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

This alerts "1", "2", "3", and "foo" (in no particular order). You can see how if you'd assumed that it did just array indexes, you'd be in trouble! You can use it to loop array indexes, but it's more complicated than it's worth:

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

That first checks to see if the property name is a number, and then checks to see that the property is defined on a itself, not the Array.prototype (remember that arrays inherit properties from the Array prototype). (To be fair, this latter check is probably not all that important; if someone is adding numerically-named properties to the Array prototype, they're doing a very Bad Thing(tm).)

这篇关于关于javascript BOM问题的一个小问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆