![](/img/trans.png)
[英]Why if('k' in 42); throw exception while for('k' in 42); does not, in javascript?
[英]Why does JavaScript not throw an exception for this code sample?
我希望人们能原谅我一个相当基本的JavaScript问题(对我而言,这通常不是“主要”语言)。 我正在查看W3Schools的JavaScript教程进行审查; 他们关于数组的课程具有以下警告和代码示例:
警告:添加具有高索引的元素会在数组中创建未定义的“孔”:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits[6] = "Lemon"; // adds a new element (Lemon) to fruits
这将导致索引4和5包含undefined
。
此外,我可以做类似alert(fruits[20]);
(这使我弹出一个窗口,说“未定义”)无一例外。
在大多数对键入更为严格的语言中,尝试执行这些操作之一将导致运行时异常。 我确实意识到我们这里没有一个人在JavaScript设计委员会中(据我所知),但是没有人知道为什么允许这些(例如,为什么他们不抛出运行时异常或类似的东西)?
我可以理解做诸如fruits[4] = "Lemon"
(因为它本质上是追加到数组中),但是有没有合理的理由去做诸如fruits[6] = "Lemon"
类的事情呢?
似乎也像在做alert(fruits[20]);
几乎总是会指出一个错误-实际上,我想不出任何合法的用例。 这个对吗?
从这个问题的答案中我的理解是,JavaScript数组“实际上更像是将属性用作索引的自定义对象”,而不是Java或C#中的数组。 答案之一也指出
Javascript数组不是真正的数组,例如C / C ++或其他语言。 因此,它们没有那么高效,但是可以说它们更易于使用并且不会超出范围。
这些说法正确吗? 这是JavaScript中这种行为的原因吗?
JavaScript不会将访问不存在的数组元素和对象属性视为错误。 当代码尝试进行这些访问时,它仅返回undefined
。
一些常见的习语利用了这一点。 你可以写:
var fruit20 = fruits[20] || defaultFruit;
由于undefined
为falsey,因此它不存在时将返回defaultFruit
。 这比以下简单:
var fruit20 = '20' in fruits ? fruits[20] : defaultFruit;
通常,您会从尝试使用结果值的代码中得到一个错误。 例如,如果您这样做:
var firstLetter = fruits[20].substr(0, 1);
由于尝试访问undefined
的substr
属性,它会发出异常信号,因为undefined
没有任何属性。
在C或具有“真”数组(即,连续内存中的指针序列)的另一种语言中,越界写操作可能会破坏正在运行的程序甚至另一个进程。
JavaScript的Array
可以动态调整大小,因此没有非法访问或损坏的风险。
通常,JavaScript仅在没有其他选择时才会抛出运行时异常。 在这种情况下,还有一种选择-动态调整数组的大小-因此它更喜欢抛出。
我看到您说的不是您的主要语言...所以我将与c ++进行比较
在c ++中,您声明了一部分内存: int a[50];
//系统为我们重新解析了50 * sizeof(int)的一部分,我们可以在其中执行所需的操作。 a是第一个int的指针
例如: cout<<a[20]
; //将返回存在的内存中的变量,它是我们的内存部分,即使我们没有提早设置它也是如此。 cout<<a[51]
//错误...为什么?...,因为该程序将尝试访问我们没有访问权限(或操作系统未授予权限)的地址;
在js中,您可以执行以下操作:console.dir(fruits); ...您会在其中看到很多功能,...甚至您在水果中没有说过的“ length”属性也可以用来设置length属性吗?... js中的基本数组是c ++中的一个类
在c ++中,当您引用数组时,您引用的是指针A的内存+数组类型的大小:
示例: cout<<*A
; //与cout<<A[0];
or cout<<*(A+0);
cout<<*(A+5)
; //与cout<<A[5];
A [5] = *(A + 5)= *(5 + A)= 5 [A]
所以
for(int i=0; i<n; i++)
cout<<i[A];
//与cout<<A[i]
..疯了吧?
在回答您的问题时,首先进行演示:
var a = []; console.log( "initial length is: " + a.length); a[1.5] = 1.5 console.log( "a[1.5] is " + a[1.5] + ", length is " + a.length); a["foo"] = "bar"; console.log( "a.foo is " + a.foo + ", length is " + a.length); a[-1] = -1; console.log( "a[-1] is " + a[-1] + ", length is " + a.length); a[10] = "item 10"; console.log( "a[10] is " + a[10] + ", length is " + a.length); a[20] = "item 20"; console.log( 'a[ 20 ] is ' + a[ 20 ] + ", length is " + a.length); console.log( 'a["20"] is ' + a["20"] + ", length is " + a.length); console.log( 'a["0x14"] is ' + a["0x14"]); console.log( "a.hasOwnProperty( 20) " + a.hasOwnProperty( 20)); console.log( "a[ 15] " + a[ 15]); console.log( "a.hasOwnProperty( 15) " + a.hasOwnProperty( 15)); a[15] = undefined; console.log( "a[ 15] " + a[ 15]); console.log( "a.hasOwnProperty( 15) " + a.hasOwnProperty( 15));
Array
构造函数构造,并从Array.prototype
继承方法。 a[20]
引用为a["20"]
。 您不能引用与a["0x14"]
相同的元素,因为属性字符串名称“ 0x14”不存在。 undefined
值。 尝试查找不存在的元素时,返回undefined
。 (这与查找不存在的对象属性时的行为相同。) undefined
是原始值,因此可以将数组元素设置为undefined
。 现在该元素存在,而不是找不到。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.