2015-11-22 117 views
14

我對JavaScript範圍的理解有一個相當的理解 - 語言具有函數級作用域,變量和函數聲明被提升到其包含範圍的頂部。不過,我不明白,爲什麼下面的代碼兩塊登錄不同的值:對JavaScript範圍的困惑

該記錄的值1到控制檯:

var a = 1; 
function b() { 
    a = 10; 
    return; 
    function a() {} 
} 
b(); 
console.log(a); 

而神祕,這會將10:

var a = 1; 
function b() { 
    a = 10; 
    return;   
} 
b(); 
console.log(a); 

那麼發動機罩下面發生了什麼?

+3

['use strict'](http://stackoverflow.com/questions/1335851/)將不允許像第一個例子那樣聲明一個函數,所以它可能是一個非常糟糕的想法開始。 – transistor09

+0

有趣,但它更像是一個設計問題。 –

回答

13

我找到的第一個例子更神祕......

在第二個例子,你不聲明一個變量a功能的內部。所以當你分配到a時,它的目標是外部的a。非常直接。

在第一個例子,你聲明一個變量a的功能裏面,但在一個不尋常的方式:通過聲明一個名爲a功能。所以分配到a將使用該本地「變量」。

兩件事情帶走這裏:

一)變量和函數聲明「懸掛」在其範圍的頂部。雖然function a(){}寫在接近尾聲,但保存它的變量a已經創建並且在範圍的頂部可見。 b)函數也可以作爲變量使用。你可以傳遞函數,你可以重新分配函數定義。它們與其他變量共享相同的命名空間。

1

您可以使用Visual-Studio進行編碼:

enter image description here

在打字稿,文件編程代碼將使你通過懸停變量看到變量類型。

enter image description here

它也將提醒你,當你嘗試將數字值10適用於變量「a」,這是第一個宣佈爲一個功能。 這就是我愛打字稿,你可以得到更多關於它的信息在這裏:http://www.typescriptlang.org/

+0

在變量賦值下是否有警告信息與紅線一起出現? – Thilo

+2

爲你打印圖像 – CupawnTae

+0

謝謝@CupawnTae – CoderPi

1

它,因爲當你使用一個聲明function它懸掛起來,變成了一個函數表達式,即var a = function() {};這是創建一個衝突的變量爲a

0

JavaScript是基於解釋器的。 Javascript {block}沒有範圍,但功能有。

在你的榜樣,

var a = 1; 
function b() { 
    a = 10; 
    return; 
    function a() {} 
} 
b(); 
console.log(a); 

第一,分配a是整數10,但最終重新分配你的a因爲這將是消失在範圍結束的功能。

在這段代碼,

var a = 1; 
function b() { 
    a = 10; 
    return; 
    function foo() {} 
} 
b(); 
console.log(a); 

a沒有更換,並返回給全球範圍內,它會記錄10