1. 程式人生 > >07_javascript作用域與作用域鏈

07_javascript作用域與作用域鏈

作用域

理解
就是一塊"地盤", 一個程式碼段所在的區域
它是靜態的(相對於上下文物件), 在編寫程式碼時就確定了
分類
全域性作用域
函式作用域
沒有塊作用域(ES6有了)
作用

隔離變數,不同作用域下同名變數不會有衝突 在這裡插入圖片描述

//ES5 沒塊作用域
if(true) {
	var c = 3
}
console.log(c) //3

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)

作用域與執行上下文

區別1
全域性作用域之外,每個函式都會建立自己的作用域,作用域在函式定義時就已經確定了。
而不是在函式呼叫時

全域性執行上下文環境是在全域性作用域確定之後, js程式碼馬上執行之前建立

函式執行上下文環境是在呼叫函式時, 函式體程式碼執行之前建立
區別2
作用域是靜態的, 只要函式定義好了就一直存在, 且不會再變化

上下文環境是動態的, 呼叫函式時建立, 函式呼叫結束時上下文環境就會被釋放
聯絡
上下文環境(物件)是從屬於所在的作用域
全域性上下文環境==>全域性作用域
函式上下文環境==>對應的函式使用域

在這裡插入圖片描述

作用域鏈

理解

多個上下級關係的作用域形成的鏈, 它的方向是從下向上的(從內到外) 查詢變數時就是沿著作用域鏈來查詢的

查詢一個變數的查詢規則

在當前作用域下的執行上下文中查詢對應的屬性, 如果有直接返回, 否則進入2 在上一級作用域的執行上下文中查詢對應的屬性, 如果有直接返回, 否則進入3 再次執行2的相同操作, 直到全域性作用域, 如果還找不到就丟擲找不到的異常

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) //d is not defined
	}
	fn2()
}
fn1()

在這裡插入圖片描述

面試題

面試題1
var x = 10;
function fn() {
	console.log(x);
}
function show(f) {
	var x = 20;
	f();
}
show(fn); 


//10
面試題2
var fn = function () {
	console.log(fn)
}
fn()


/*
    ƒ () {
    	console.log(fn)
    }
* */

var obj = {
	fn2: function () {
		console.log(fn2)
	}
}
obj.fn2()
// Uncaught ReferenceError:
// fn2 is not defined at Object.fn2