腦圖學習 JavaScript 之犀牛書【三 · 一】數據類型

介紹

犀牛書第三章主要講了類型、值還有變量,本篇主要講 數據類型es6

須要注意引用類型和非引用類型的區別、-0、NaN、八進制、字符串編碼等問題。編程

類型轉換部分查看:數組

自我提問

  • 數據類型怎麼區分?
  • 何時會觸發隱式類型轉換?
  • 浮點計算爲什麼會丟失精度?
    0.1 + 0.2 === 0.3;
    複製代碼
  • 字符串中有什麼坑?
    var e = '👋';
    console.log(e.length);
    複製代碼
  • 0 和 -0 是否徹底同樣?
    0 === -0;
    1/0 === 1/-0;
    複製代碼

腦圖

腦圖

關鍵知識點

數據類型

數據類型主要分爲兩類:瀏覽器

  • 原始類型(也稱爲 值類型基本類型不可變類型非引用類型),原始類型包括 數字字符串布爾值nullundefined(以及 es6 中的 Symbol )。
  • 對象類型(也稱爲 可變類型引用類型),非原始類型的全部類型均爲對象類型(普通對象、數組、函數、正則、日期等等)。

隱式類型轉化

JavaScript 會在 程序期待使用對應數據類型 的地方 自動進行類型轉換(常說的 隱式類型轉換,如將非 Boolean 型的數據放在 if 判斷條件中、使用非字符串和數字進行 + 運算等)。安全

弱類型

JavaScript 變量是 無類型的,變量 能夠賦予任何類型的值,而且 能夠從新賦予不一樣類型的值(也就是第一章所說的 弱類型 概念)。閉包

詞法做用域

JavaScript 採用 詞法做用域(也稱 靜態做用域,正是由於詞法做用域的緣故,纔會出現閉包,在變量定義的時候,它的做用域就已經肯定好了)。編程語言

IEEE 754 標準

JavaScript 中的數字採用 IEEE 754 標準,整數範圍爲 -(2**53) ~ 2**53Number.MAX_SAFE_INTEGER 的值爲 2**53 - 1,和這裏相差了 1,由於 超出(安全)範圍的值沒法保證精度,故而最大值自己是不安全的,可能由某個失去精度的值轉換而來️)。函數

下面是 MDN 中的例子。post

var x = Number.MAX_SAFE_INTEGER + 1;
var y = Number.MAX_SAFE_INTEGER + 2;

// 9007199254740991 9007199254740992 9007199254740992
console.log(Number.MAX_SAFE_INTEGER, x, y);
// true
console.log(x === y);
複製代碼

實際操做基於 32 位整數

JavaScript 中的實際操做如數組索引等 是基於 32 位整數 的。學習

// 4294967296
console.log(2**32);
// 安全
new Array(2**32 - 1);
// 報錯:RangeError: Invalid array length
new Array(2**32);
複製代碼

特殊的 NaN

NaN 的意思是 Not a Number,不過 typeof NaN 是 number,因此它是一個不是(有效)數字的數字值。

因爲 NaN 不等於任何值包括自身,可使用 a !== a 來判斷 a 是否是一個 NaN 值。

八進制

八進制雖然大部分瀏覽器支持,可是它自己是 非標準的,在嚴格模式下 明令禁止(八進制使用 0 做爲前置標識,這會在某些地方引發歧義)。

// 9
console.log(09);
// 15
console.log(017);
// 上述都是前導 0 可是卻按照兩種進制去進行了解析

(function() {
 'use strict';
    // 嚴格模式下會報錯:SyntaxError: Octal literals are not allowed in strict mode.
    console.log(09);
    console.log(017);
})();
複製代碼

浮點數計算精度

JavaScript 中的浮點數計算精度問題是因爲採用了 IEEE 754 浮點數表示法(大部分編程語言都是採用這個標準,因此這個問題真不是 JavaScript 的設計缺陷之類的),二進制表示法 致使十進制的小數沒法精確的標識,因此致使一系列浮點計算的精度問題。

var a = 0.3 - 0.2;
var b = 0.2 - 0.1;
// false
console.log(a === b);
// 0.09999999999999998 0.1
console.log(a, b);
複製代碼

這種時候建議使用整數來進行計算:

var a = (0.3 * 10 - 0.2 * 10) / 10;
var b = (0.2 * 10 - 0.1 * 10) / 10;
// true
console.log(a === b);
// 0.1 0.1
console.log(a, b);
複製代碼

特殊的 -0

0 和 -0 並不徹底對等

var a = 0, b = -0;
// 全等號會認爲他們相等
console.log(a === b);
// 可是進行除法計算時將會影響計算結果 
// Infinity -Infinity false
console.log(1/a, 1/b, 1/a === 1/b);
複製代碼

字符串編碼致使的奇怪問題

JavaScript 字符串是由無符號的 16 位值 組成的序列,常見的 Unicode 字符都是經過 16 位內碼錶示的,若是出現 超出範圍 的字符,將會遵循 UTF-16 編碼規則,使用 兩個 16 位值 標識,然而 JavaScript 中對字符串的操做都是 基於 16 位值

// 👋 遵循 UTF-16 規則,實際編碼爲 '\ud83d\udc4b',在 JavaScript 中佔用兩個字符長度
var e = '👋';
// 2 d83d dc4b
console.log(e.length, e.charCodeAt(0).toString(16), e.charCodeAt(1).toString(16));
// true 👋 👋
console.log(e === '\ud83d\udc4b', e, '\ud83d\udc4b');
複製代碼

null 和 undefined

從語義上,null 表明 空值,undefined 表明 未定義、不存在,正常而言 null 可用來給變量賦值(清空變量等),而 不多使用 undefined 去給變量賦值

全局變量

聲明全局變量時變量會 成爲全局對象的一個屬性

// 定義全局變量時 a 會直接掛載到 全局對象下
var a = {};
// {} {} true
console.log(a, window.a, a === window.a);
複製代碼

系列文章目錄

  1. 腦圖學習 JavaScript 之犀牛書【一】
  2. 腦圖學習 JavaScript 之犀牛書【二】詞法結構
  3. 腦圖學習 JavaScript 之犀牛書【三 · 一】數據類型
  4. 腦圖學習 JavaScript 之犀牛書【三 · 二】類型轉換、變量
  5. 腦圖學習 JavaScript 之犀牛書【四 · 一】運算符、類型轉換
  6. 腦圖學習 JavaScript 之犀牛書【四 · 二】表達式
相關文章
相關標籤/搜索