1. 解释 Scope ( Global scope / Function scope / Block scope )

2021.9.3更新: 调整了一些block scope的叙述。

Scope 的定义


scope 可以翻译成作用域,意即 variable能被调用的范围

→ 也就是说,如果一个variable不在当下执行的scope里,对当前的scope来说根本看不到variable这个东西,所以没办法调用。

(补充: 在JS里,所有的object和function也都是variable。)

而 scope 又分为

  1. Global scope
  2. function scope
  3. Block scope (ES6後新增)

1. Global Scope


只要一个variable宣告在所有的function之外,我们将variable称为 global variable(全域变数)。

被宣告为global variable就会拥有Global Scope。

这会造成整个script都是它的作用域! 而该页面的所有的funciton和script都可以调用它。

举例来说:

// a has Global Scope; All scripts can access it. 

let a = "apples"

console.log( "Winnie would eat " + a); 
// output: Winnie would eat apples.
// a has Global Scope; All functions can access it. 

let a = "apples"

function eat(){
    console.log( "Mary would eat " + a); 
}

eat();  // output: Mary would eat apples.

以上面的举例而言,因为a被宣告在eat()这个function外,所以不管在function里或整个script都可以有效的印出a。

2. Function Scope


在JS里,每一个function都会有一个Function Scope。

被定义在function内部的variable,便不能在function外被调用。

再看个例子:

// a isn't accessible (visible) from outside the function.

function f(){
    let a = "apple";
}

console.log( "Mary would eat " + a); 
// ReferenceError: a is not defined

a被宣告在f()里,因此想从f()外调用a就会出现ReferenceError,意思是对整个global来说a并不存在。

// a is accessible in the function

function f(){
    let a = "apple";
    console.log( "Mary would eat " + a); 
}

f();
// output: Mary would eat apple

a的scope就是function scope,而整个f()都是a可以被调用的范围(scope)。

那如果是更多分层的函式呢? 可以在延伸到下一个例子:

// a is accessible in the f2()

function f(){
    let a = "apple";
    
    function f2(){
        console.log( "Winnie wouldn't eat " + a); 
    }
    f2();
}
f();
// output: Winnie wouldn't eat apple

MDN的文件有提到: 如果有阶层关系,基本上子阶层会可以调用父级阶层里的变数。

讲白话是,像f2()是在f()里的函式,但因为整个f()都是a的scope,所以在f2()里调用a也会成功。

function f(){
    let a = "apple";
    
    function f2(){
        console.log( "Winnie wouldn't eat " + a); 
    }
}
f2(); // ReferenceError: f2 is not defined

最後是,因为function也是variable的一种,
这个例子的情况跟在f()外印出a是一样的,都会造成读不到f2

3. Block Scope


因为ES6新增了 letconst
这两个 keyword 能建立 Block Scope

letconst的宣告,只在{大括号}中有效,无法从{}外被调用。
(→ let, var, const都有global scope和function scope,但只有letconst有block scope)

{block scope}通常指两种情况:

  1. 在if statement里面
  2. 在for Loop里面
if(true){
    let a = "apple";
}
console.log(a);  // ReferenceError: a is not defined

var并没有Block Scope,所以就算被写在{大括号}里,也可以从{}外被调用。

if(true){
    var a = "apple";
}
console.log(a);  // output: apple 

另一种block scope的情况,还有在for loop里面:

for(let i=0; i<=10; i++){
    console.log(i); 
    // output: 0, 1, 2, ... 10
}

console.log("out of the loop: " + i); 
// ReferenceError: i is not defined

在(小括号)里宣告let i=0,只能在{大括号}里被调用。
出了{大括号}就会出错。

for(var i=0; i<=10; i++){
    console.log(i);
    // output: 0, 1, 2, ... 10
}

console.log("out of the loop: " + i);
// out of the function: 11

在(小括号)里宣告var i=0,在{大括号}外也可以成功被调用。

要注意这里的{大括号}跟 function(){}的大括号是不一样的,var定义在f(),如果从整个global调用,一样是function scope的概念,所以会出错。

function f(){
    var a = "apple";
    }
console.log(a);
// ReferenceError: a is not defined

---总结重点---

  • scope 可以翻译成作用域,意即 变数能被调用的范围

  • scope 又分为:

    1. Global scope : 变数在整个web page都可以被调用。
    2. Function scope : variable只能在Function内被调用。
      (在JS中,一个function会依照closure建立一个scope。)
    3. Block scope : let和const如果被宣告在{大括号}里,{}外就不能调用let和const。

参考资料

JavaScript Scope - w3schools
Scope - MDN

【如内文有误还请不吝指教>< 并感谢阅览至此的各位:D 】

---正文结束---


<<:  Day 2 Convolutional Neural Network(CNN)

>>:  NetSuite Glossary

DAY09随机森林演算法(回归方法)

昨天,我们已建立完随机森林,那今天,我打算使用回归方法去看他得出来结果,所以会跟基尼系数预测类别方法...

Day 29 - 浅谈测试 - 令人安心的保护网

前言 前两天我们讨论了 Clean Code 跟 The Clean Coder,这两本书都要提到一...

认识C# 的 IndexOf 与 LastIndexOf

今日之自学笔记 浅谈在C#中字串相关的查找方法有IndexOf、LastlndexOf IndexO...

第十天:安装 IntelliJ IDEA

在後续章节里,我们将使用 IntelliJ IDEA 示范如何编辑 Gradle 的 Build S...

[DAY 04] 阿桐意面

阿桐意面 地点:台南市盐水区信义路4-6号 时间:8:00~19:30 来盐水怎麽可能不吃意面呢~ ...