變量
在開發過程中,雖然我們有時候聲明變量並注意加var 和不加var的區別,代碼也能正常實現功能,但是兩者還是有區別的:
- 在函數體中,加var,變量是局部變量,作用域是所在的函數作用域;不加var則是全局變量,作用域是全局作用域
- 在全局作用域中,兩者都一樣
- 加var會進行變量提升
- 瀏覽器執行的時候,在全局作用域中,兩者都會將聲明的變量掛載到window對象中
function test() {
c = 3
}
a = 1
var b = 2
console.log(a, window.a) // 1 1
console.log(b, window.b) // 2 2
console.log(c) // 報錯:c is not defined
console.log(window.c) // undefined
test()
console.log(c, window.c) // 3 3
// 加var進行變量提升
console.log(a) // undefined
console.log(b) // 報錯:b is not defined
var a = 1
b = 2
console.log(a) // 1
console.log(b) // 2
函數
講這個之前,先說一個概念:匿名函數,顧名思義匿名函數指的是沒有名字的函數。
匿名函數可以被當成變量一樣使用,可以用來賦值,作爲對象的屬性,作爲回掉函數等等;它也可以進行自調用:
// 使用!開頭
!function(){
console.log('ni hao');
}
// 能夠將匿名函數與調用的()爲一個整體,官方推薦使用
(function(){
console.log('hello');
}());
函數有兩種聲明方式(還有一種Function構造函數的方式,這裏就不展開了):
-
函數表達式(Function Expression):即將匿名函數賦值給一個變量。
-
函數聲明(Function Declaration):是一種獨立的結構,它會聲明一個具名函數,必須以function開頭。且函數聲明會進行函數提升,使它能在其所在作用域的任意位置被調用。後面的代碼可以將此函數通過函數名賦值給變量或者對象屬性。
如果在聲明函數的過程中使用了var,那麼肯定是函數表達式的聲明方式;如果沒有使用var,則可能是函數聲明,也有可能是函數表達式聲明
- 同樣是表達式聲明方式,加var和不加var與聲明變量的區別一樣
- 函數聲明方式會將函數體提升到所在作用域的最前面
// 帶var
var b = function() {
console.log(2)
}
b() // 2
// 不帶var
a = function(){
console.log(1)
}
function c() {
console.log(3)
}
a() // 1
c() // 3
// 函數提升:log(3)的函數被提到最前,被之後的Log(1)給覆蓋
var a = function(){
console.log(1)
}
function a() {
console.log(3)
}
a() // 1
函數提升和變量提升,那麼誰提的更前以前呢,我的理解是變量提升提更前一點,看如下代碼:
a() // 3
function a() {
console.log(3)
}
a() // 3
var a = function(){
console.log(1)
}
a() // 1
以上代碼相當於:
var a
function a() {
console.log(3)
}
a() // 3
a() // 3
a = function(){
console.log(1)
}
a() //1