[譯]揭祕基本資料型別

thecodingape發表於2019-01-18

原文地址:developer.mozilla.org/en-US/docs/…

基本型別(基本數值,基本資料型別)是一種既非物件,也無方法的資料。在JavaScript中,共有六中基本型別:string、number、boolean、null、undefined、symbol(ECMAScript 2015新增)。

多數情況下,基本型別代表了最底層的語言實現。

所有基本型別的值都是不可改變的。但需要注意的是,基本型別本身和一個賦值為基本型別的變數的區別。變數會被賦予一個新值,而原值不能像陣列、物件以及函式那樣被改變。


示例1

這個示例會幫助你瞭解基本型別不可改變的事實。

// 使用字串方法不會改變一個字串
var bar = "baz";
console.log(bar);               // baz
bar.toUpperCase();
console.log(bar);               // baz

// 使用陣列方法可以改變一個陣列
var foo = [];
console.log(foo);               // []
foo.push("plugh");
console.log(foo);               // ["plugh"]

// 賦值行為可以給基本型別一個新值,而不是改變它
bar = bar.toUpperCase();       // BAZ
複製程式碼

基本型別值可以被替換,但不能被改變。


示例2

下面的示例將讓你體會到JavaScript是如何處理基本型別的。

// 基本型別
let foo = 5;

// 定義一個貌似可以改變基本型別值的函式
function addTwo(num) {
   num += 2;
}
// 和前面的函式一樣
function addTwo_v2(foo) {
    foo += 2;
}

// 呼叫第一個函式,並傳入基本型別值作為引數
addTwo(foo); // 獲取到當前的基本型別值
console.log(foo);   // 5

// 嘗試呼叫第二個函式...
addTwo_v2(foo);
console.log(foo);   // 5
複製程式碼

你是否認為會得到7,而不是5?如果是,請看看程式碼是如何執行的:

  • addTwoaddTwo_v2函式呼叫時,JavaScript會檢查識別符號foo的值,從而準確無誤的找到第一行例項化變數的宣告語句。

  • 找到以後,JavaScript將其作為引數傳遞給函式的形參。

  • 在執行函式體內的語句之前,JavaScript會將傳遞進來的引數(基本型別的值)複製一份,建立一個本地副本。這個副本只存在於該函式的作用域中,我們能夠通過指定在函式中的識別符號訪問到它(addTwo中的numaddTwo_v2中的foo)。

  • 接下來,函式體中的語句開始執行

    • 第一個函式中,建立了本地num引數,num的值加2,但這個值並不是原來的foo的值。

    • 第二個函式中,建立了本地引數foo,並將它的值加2,這個值不是外部foo的值。在這種情況下,外部的foo變數不能以任何方式被訪問到。這是因為JavaScript的詞法作用域(lexical scoping)所導致的變數覆蓋,本地的變數foo覆蓋了外部的變數foo。欲知詳情,請參閱閉包

  • 綜上所述,函式中的任何操作都不會影響到最初的foo,我們操作的只不過是它的副本。

這就是為什麼說所有基本型別的值都是不可改變的。

相關文章