1. 程式人生 > 其它 >JavaScript中的資料型別,儲存上有和差別

JavaScript中的資料型別,儲存上有和差別

#前言

JavaScript中,我們可以分成兩種型別:

  • 基本型別
  • 複雜型別

兩種型別的區別是:儲存位置不同

#一、基本型別

基本型別主要為以下6種:

  • Number
  • String
  • Boolean
  • Undefined
  • null
  • symbol

#Number

數值最常見的整數型別格式則為十進位制,還可以設定八進位制(零開頭)、十六進位制(0x開頭)

let intNum = 55 // 10進位制的55
let num1 = 070 // 8進位制的56
let hexNum1 = 0xA //16進位制的10

浮點型別則在數值彙總必須包含小數點,還可通過科學計數法表示

let floatNum1 = 1.1;
let floatNum2 
= 0.1; let floatNum3 = .1; // 有效,但不推薦 let floatNum = 3.125e7; // 等於 31250000

在數值型別中,存在一個特殊數值NaN,意為“不是數值”,用於表示本來要返回數值的操作失敗了(而不是丟擲錯誤)

console.log(0/0); // NaN
console.log(-0/+0); // NaN

#Undefined

Undefined型別只有一個值,就是特殊值undefined。當使用varlet聲明瞭變數但沒有初始化時,就相當於給變數賦予了undefined

let message;
console.log(message == undefined); //
true
包含undefined值的變數跟未定義變數是有區別的
let message; // 這個變數被聲明瞭,只是值為 undefined

console.log(message); // "undefined"
console.log(age); // 沒有宣告過這個變數,報錯

#String

字串可以使用雙引號(")、單引號(')或反引號(`)標示

let firstName = "John";
let lastName = 'Jacob';
let lastName = `Jingleheimerschmidt`

字串是不可變的,意思是一旦建立,它們的值就不能變了

let lang = "Java";
lang 
= lang + "Script"; // 先銷燬再建立

#Null

Null型別同樣只有一個值,即特殊值null

邏輯上講, null 值表示一個空物件指標,這也是給typeof傳一個null會返回"object"的原因

let car = null;
console.log(typeof car); // "object"

undefined值是由null值派生而來

console.log(null == undefined); // true

只要變數要儲存物件,而當時又沒有那個物件可儲存,就可用null來填充該變數

#Boolean

Boolean(布林值)型別有兩個字面值:truefalse

通過Boolean可以將其他型別的資料轉化成布林值

規則如下:

資料型別                      轉換為 true 的值                      轉換為 false 的值
 String                         非空字串                              "" 
 Number                 非零數值(包括無窮值)                        0 、 NaN 
 Object                      任意物件                                null
Undefined                     N/A (不存在)                         undefined

#Symbol

Symbol (符號)是原始值,且符號例項是唯一、不可變的。符號的用途是確保物件屬性使用唯一識別符號,不會發生屬性衝突的危險

let genericSymbol = Symbol();
let otherGenericSymbol = Symbol();
console.log(genericSymbol == otherGenericSymbol); // false

let fooSymbol = Symbol('foo');
let otherFooSymbol = Symbol('foo');
console.log(fooSymbol == otherFooSymbol); // false

#二、引用型別

複雜型別統稱為Object,我們這裡主要講述下面三種:

  • Object
  • Array
  • Function

#Object

建立object常用方式為物件字面量表示法,屬性名可以是字串或數值

let person = {
    name: "Nicholas",
    "age": 29,
    5: true
};

#Array

JavaScript陣列是一組有序的資料,但跟其他語言不同的是,陣列中每個槽位可以儲存任意型別的資料。並且,陣列也是動態大小的,會隨著資料新增而自動增長

let colors = ["red", 2, {age: 20 }]
colors.push(2)

#Function

函式實際上是物件,每個函式都是Function型別的例項,而Function也有屬性和方法,跟其他引用型別一樣

函式存在三種常見的表達方式:

  • 函式宣告
// 函式宣告
function sum (num1, num2) {
    return num1 + num2;
}
  • 函式表示式
let sum = function(num1, num2) {
    return num1 + num2;
};
  • 箭頭函式

函式宣告和函式表示式兩種方式

let sum = (num1, num2) => {
    return num1 + num2;
};

#其他引用型別

除了上述說的三種之外,還包括DateRegExpMapSet等......

#三、儲存區別

基本資料型別和引用資料型別儲存在記憶體中的位置不同:

  • 基本資料型別儲存在棧中

  • 引用型別的物件儲存於堆中

當我們把變數賦值給一個變數時,解析器首先要確認的就是這個值是基本型別值還是引用型別值

下面來舉個例子

#基本型別

let a = 10;
let b = a; // 賦值操作
b = 20;
console.log(a); // 10值

a的值為一個基本型別,是儲存在棧中,將a的值賦給b,雖然兩個變數的值相等,但是兩個變數儲存了兩個不同的記憶體地址

下圖演示了基本型別賦值的過程:

#引用型別

var obj1 = {}
var obj2 = obj1;
obj2.name = "Xxx";
console.log(obj1.name); // xxx

引用型別資料存放在內對內中,每個堆記憶體中有一個引用地址,該引用地址存放在棧中

obj1是一個引用型別,在賦值操作過程彙總,實際是將堆記憶體物件在棧記憶體的引用地址複製了一份給了obj2,實際上他們共同指向了同一個堆記憶體物件,所以更改obj2會對obj1產生影響

下圖演示這個引用型別賦值過程

#小結

    • 宣告變數時不同的記憶體地址分配:
      • 簡單型別的值存放在棧中,在棧中存放的是對應的值
      • 引用型別對應的值儲存在堆中,在棧中存放的是指向堆記憶體的地址
    • 不同的型別資料導致賦值變數時的不同:
      • 簡單型別賦值,是生成相同的值,兩個物件對應不同的地址
      • 複雜型別賦值,是將儲存物件的記憶體地址賦值給另一個變數。也就是兩個變數指向堆記憶體中同一個物件

        原文轉自https://github.com/febobo/web-interview

再忙也別忘記學習