2013-06-26 23 views
49

我已閱讀,並通過我自己的經驗發現,JavaScript沒有塊範圍。假設這種語言的設計出於某種原因,那是什麼原因?爲什麼block範圍最初不是在JavaScript中實現的?

我環顧四周,在谷歌和這裏,但我已經找到了帖子剛重申,JS具有的功能範圍,而不是阻止範圍,沒有說明原因。我很想知道爲什麼事實如此。

+4

JavaScript中的函數式編程風格並不鼓勵它我認爲再加上JS是一個衝動的概念,但'let'即將在ES6中出現,因此我們將在不久的將來擁有塊範圍。 Firefox已經支持'let'。 – elclanrs

+0

創作者的選擇? [Block statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Statements?redirectlocale=zh-CN&redirectslug=JavaScript%2FGuide%2FStatements#Block_Statement),[解決方法](http ://zef.me/2843/javascript-the-scope-pitfall),[未來](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Block_scoping ) – mplungjan

+0

@mplungjan我很樂意聽到有人從創作者處獲得信息。我希望這不僅僅是設計中的疏忽,而且還有一些原因是由於JavaScript的設計和/或限制造成的。這些鏈接很方便,非常感謝。 – mricci

回答

94

轉換我的評論回答的創造者的

選擇:我啾啾布倫丹並得到了following answer

@mplungjan 10 days did not leave time for block scope. Also many "scripting languages" of that mid-90s era had few scopes & grew more later.


也就是說,這裏有一些相關的要點:

Important: JavaScript does not have block scope. Variables introduced within a block are scoped to the containing function or script, and the effects of setting them persist beyond the block itself. In other words, block statements do not introduce a scope. Although "standalone" blocks are valid syntax, you do not want to use standalone blocks in JavaScript, because they don't do what you think they do, if you think they do anything like such blocks in C or Java.

we can artificially introduce scopes by creating new functions and immediately invoking them

let聲明的變量是葫蘆編輯到封閉塊的開始處。因此,在分配其值之前引用let聲明的變量將引發ReferenceError。

在同一個塊範圍相同的變量的重新說明提出一個SyntaxError。

+39

+1直接從Brendan Eich得到答案:-) – Sc0ttyD

0

原因是多方面的,但有些我想到是在使用對象文本(這有時看起來像塊)分析/調試代碼,以幫助,並簡化局部變量的垃圾收集。

我希望承諾的支持(在這裏討論,例如,http://esdiscuss.org/notes/2012-07-25)證明是真實的,因爲使用變量如i是非常方便的,這些變量對於只有一個循環是局部的。

9

塊範圍並沒有,原因如下實施:

  1. 它使語言更容易實現。 JavaScript最初被設計爲編寫交互式Web應用程序的語言。因此它需要很小且易於實施。
  2. 塊範圍引入一個性能命中如JavaScript動態語言。這是因爲當你嘗試訪問某個不在當前範圍內的變量時,JavaScript首先檢查當前範圍,然後檢查父範圍等,直到它找到變量或達到結尾。因此,引入塊範圍會使循環中的變量訪問和嵌套循環非常緩慢。
  3. 塊範圍的缺乏使寫程序變得更容易。例如,假設你只想在某個條件爲真的情況下創建一個變量。您需要在JavaScript中執行的操作是在if語句中聲明並定義該變量。在像C這樣的語言中,您必須聲明if語句之外的變量,並在if語句中定義它。
  4. 缺少塊範圍允許聲明被提升。這在函數聲明的情況下特別有用。例如,看這個小提琴:http://jsfiddle.net/L6SgM/(但請注意,這個例子在Firefox中不起作用)。
  5. 由於JavaScript支持一流的函數表達式,所以我們不需要塊範圍。他們可以使用immediately invoked function expressions進行模擬。
+3

「塊範圍引入性能碰到像JavaScript這樣的動態語言。「 - 這是實現的屬性,而不是語言。也許它支持第一個JavaScript實現,但是在過去的十年中沒有任何引擎會遭受這種攻擊。 – Marijn

+0

@Marijn也許吧。 –

+0

#5)嚴格地說,我們不需要比我們首先需要使用JavaScript更多的塊範圍......謝天謝地,ECMA團隊似乎不同意通過通過'let'關鍵字添加對塊範圍的支持。簡單的語言結構總是受歡迎的。 –

8

截至2015年的新答案.ES6確實有關於let關鍵字的變量定義的塊範圍。

+1

不幸的是,一些用戶可能仍然生活在2010年,所以依靠全新的語言功能並不是最佳做法。 – riv

+1

@riv - Javascript不僅用於需要編碼到最小公分母的瀏覽器中。它可以用在像node.js這樣的環境中,你可以控制整個執行環境,現在可以使用'let'。或者,您可以使用其中一種轉換器讓您在ES6中編寫代碼,並且轉換器將其轉換爲ES5兼容代碼,以便在舊版瀏覽器中運行。 – jfriend00

+0

不是一個新的答案,導致Js通過** ES3的'try/catch'來阻止範圍** – Trung