Hoisting
先了解什么是Hoisting,也就是宣告提升。
此种行为现象主因,是由于js在初始编译阶段,先将变数&函式宣告式放入记忆体(此时无赋予值),而执行时可视为将变数与函式宣告式提升至作用域的最顶端。
範例:
b();console.log(a);var a = 'Hello World!';function b() { console.log('Called b!');}
可视为:
function b() { console.log('Called b!');};var a;b();console.log(a);a = 'Hello World!';
注意!
常见定义函式有两种
函式宣告式(function declaration)函式运算式(function expression)函式宣告式会整个提升,而函式运算式则只会提升等号左的变数,并不会提升等号右边的函式
Hoisting 这个观念主要是要了解 JavaScript 记忆体运作的观念,实作上也会避免在 function 前方直接呼叫函式,这样会降低对于程式码的可维护性。
函式宣告式 : 在函式前方直接调用方法可运行
function call() {
console.log(123)
}
函式运算式 : 在函式前方直接调用方法不可运行
var call = function () {
console.log(123)
}
範例:
console.log(callSomeone); // undefinedcallSomeone('杰伦哥'); // callSomeone is not a functionvar callSomeone = function (name) { console.log('打给 ' + name)}
Scope Chain
在 JS 中有称作 scope chain(範围链)的特性
JS在查找变数时 会循着範围链(Scope Chain)一层一层往外找
若函式内找不到 则往外找
範例:
var cat = "cat"function a(){ var cat = "kitty"; b()}function b(){ console.log(cat)}a() //cat// 因b()函式在全域作用域,故直接抓全域下的变数cat
var cat = "cat"function a(){ var cat = "kitty"; function b(){ console.log(cat) } b()}a() //kitty// 因b()函式在a()函式作用域里,故抓a()里的变数cat
陷阱题目
var cat = "cat"function a(){ cat = "kitty"; b()}function b(){ console.log(cat)}a() //kitty// 因a()函式内的cat变数无宣告,故汙染全域变数
var myVar = "outer";function func(){ console.log(myVar); // outer myVar = "inner";}func();console.log(myVar); // inner//在func()函数执行时,会先执行完console.log(myVar);后才汙染全域变数myVar