![](/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.