在JavaScript中,用var
申明的變量實際上是有作用域的。
如果一個變量在函數體內部申明,則該變量的作用域爲整個函數體,在函數體外不可引用該變量
如果兩個不同的函數各自申明瞭同一個變量,那麼該變量只在各自的函數體內起作用。換句話說,不同函數內部的同名變量互相獨立,互不影響
由於JavaScript的函數可以嵌套,此時,內部函數可以訪問外部函數定義的變量,反過來則不行
JavaScript的函數在查找變量時從自身函數定義開始,從“內”向“外”查找。如果內部函數定義了與外部函數重名的變量,則內部函數的變量將“屏蔽”外部函數的變量
變量提升
JavaScript的函數定義有個特點,它會先掃描整個函數體的語句,把所有申明的變量“提升”到函數頂部
所以建議在函數內部首先申明所有變量,再進行調用
全局作用域
不在任何函數內定義的變量就具有全局作用域。實際上,JavaScript默認有一個全局對象window
,全局作用域的變量實際上被綁定到window
的一個屬性
JavaScript只有一個全局作用域window,任何變量,如果沒有在當前函數作用域找到,就會繼續往上查找,如果最後在全局作用域中也沒有找到,就會報ReferenceError錯誤
JavaScript語法解析的問題,會報SyntaxError錯誤
如果在函數體外部定義了一個變量var a;然後又在函數體內部定義了一個變量var a;就會調用函數體內部的變量a,這時候如果函數體內部的變量沒有賦值的話就會返回undefined
名字空間
全局變量會綁定到window
上,不同的JavaScript文件如果使用了相同的全局變量,或者定義了相同名字的頂層函數,都會造成命名衝突,並且很難被發現。
減少衝突的一個方法是把自己的所有變量和函數全部綁定到一個全局變量中。例如:
// 唯一的全局變量MYAPP:
var MYAPP = {};
// 其他變量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;
// 其他函數:
MYAPP.foo = function () {
return 'foo';
};
把自己的代碼全部放入唯一的名字空間MYAPP
中,會大大減少全局變量衝突的可能。
許多著名的JavaScript庫都是這麼幹的:jQuery,YUI,underscore等等。
塊級作用域
在jsp中的變量是函數級別的,因此在for循環,if()條件中定義的var i 都是局部變量不屬於塊級變量,因此如果要用解決一些傳值的問題可以用let i 代替var i或者也可以用const i;或者用閉包來解決;
this
在一個方法內部,this是一個特殊變量,它始終指向當前對象