【JavaScript高階】7、函式高階(作用域與作用鏈)
阿新 • • 發佈:2019-01-01
一、作用域
1. 理解 * 就是一塊"地盤", 一個程式碼段所在的區域 * 它是靜態的(相對於上下文物件), 在編寫程式碼時就確定了 2. 分類 * 全域性作用域 * 函式作用域 * 沒有塊作用域(ES6有了) 3. 作用 * 隔離變數,不同作用域下同名變數不會有衝突
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>01_作用域</title> </head> <body> <script type="text/javascript"> /* //沒塊作用域 if(true) { var c = 3 } console.log(c)*/ var a = 10, b = 20 function fn(x) { var a = 100, c = 300; console.log('fn()', a, b, c, x) // fn() 100 20 300 10 function bar(x) { var a = 1000, d = 400 console.log('bar()', a, b, c, d, x) } bar(100) // bar() 1000 20 300 400 100 bar(200) // bar() 1000 20 300 400 200 } fn(10) </script> </body> </html>
二、作用域與執行上下文
1. 區別1 * 全域性作用域之外,每個函式都會建立自己的作用域,作用域在函式定義時就已經確定了。而不是在函式呼叫時 * 全域性執行上下文是在全域性作用域確定之後, js程式碼馬上執行之前建立 * 函式執行上下文是在呼叫函式時, 函式體程式碼執行之前建立 2. 區別2 * 作用域是靜態的, 只要函式定義好了就一直存在, 且不會再變化 * 執行上下文是動態的, 呼叫函式時建立, 函式呼叫結束時就會自動釋放 3. 聯絡 * 執行上下文(物件)是從屬於所在的作用域 * 全域性執行上下文==>全域性作用域 * 函式執行上下文==>對應的函式使用域
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>02_作用域與執行上下文</title> </head> <body> <script type="text/javascript"> var a = 10, b = 20 function fn(x) { var a = 100, c = 300; console.log('fn()', a, b, c, x) // fn() 100 20 300 10 function bar(x) { var a = 1000, d = 400 console.log('bar()', a, b, c, d, x) } bar(100) // bar() 1000 20 300 400 100 bar(200) // bar() 1000 20 300 400 200 } fn(10) </script> </body> </html>
三、作用域鏈
1. 理解 * 多個上下級關係的作用域形成的鏈, 它的方向是從下向上的(從內到外) * 查詢變數時就是沿著作用域鏈來查詢的 2. 查詢一個變數的查詢規則 * 在當前作用域下的執行上下文中查詢對應的屬性, 如果有直接返回, 否則進入2 * 在上一級作用域的執行上下文中查詢對應的屬性, 如果有直接返回, 否則進入3 * 再次執行2的相同操作, 直到全域性作用域, 如果還找不到就丟擲找不到的異常
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>03_作用域鏈</title>
</head>
<body>
<script type="text/javascript">
var a = 1
function fn1() {
var b = 2
function fn2() {
var c = 3
console.log(c) // 3
console.log(b) // 2
console.log(a) // 1
console.log(d) // 報錯
}
fn2()
}
fn1()
</script>
</body>
</html>
四、作用域—面試題
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>04_作用域_面試題</title>
</head>
<body>
<script type="text/javascript">
var x = 10;
function fn() {
console.log(x);
}
function show(f) {
var x = 20;
f();
}
show(fn); // 10 此處15行相當於呼叫fn()函式,然後列印x,在fn()作用域內找不到,往上一級作用域找是全域性變數x=10
</script>
</body>
</html>
五、作用域—面試題2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>04_作用域_面試題2</title>
</head>
<body>
<script type="text/javascript">
var fn = function () {
console.log(fn)
}
fn()
/*輸出:
ƒ () {
console.log(fn)
}
*/
var obj = {
fn2: function () {
//console.log(fn2) // 此處會報錯,變數fn2在函式內部找不到再往上也找不到,上面的fn2實際上是obj物件的屬性即obj.fn2(或this.fn2)
console.log(obj.fn2)
}
}
obj.fn2()
</script>
</body>
</html>