你不知道的js讀後感-類型

前言

最近找時間讀了"你不知道的javascript",公司導師要求應該要有一些產出,因此隨筆記錄下。順便完善下本身的知識結構體系。但我讀的順序卻很奇葩,從中再到上,最後再讀下,最近又聽了winter的重學前端,因此文章講述的順序可能與書目錄的順序不一致而且夾雜一下其餘的感悟。javascript

正文

內置類型

  • 數字(number)
  • 字符串(string)
  • 布爾值(boolean)
  • 未定義(undefined)
  • 空值(null)
  • 對象(object)
  • 符號(symbol -> ES6)

咱們可使用 typeof 運算符來查看值的類型,但這七種類型和它們的字符串值並非一一對應的, 如下是其中特殊的個例:前端

typeof null === 'object'; // truejava

問題來了,咱們期待的結果應該是web

typeof null === 'null'; // true編程

書中明確給出了答案。實際上這是一個 js 存在了將近20年的 bug,也許永遠都不會修復,由於牽涉太多的 web 系統,一旦修復可能致使更多bug,使這些系統沒法正常的工做。數組

同時書中也給出了用複合條件檢測null的類型:瀏覽器

var a = null;
(!a && typeof a === "object"); // true
null 是基本類型中惟一的一個「假值」類型typeof對它返回值是'object'
複製代碼

還有一種狀況:安全

typeof function a(){ /* .. */ } === "function"; // truebash

看起來, function 函數應該也是一個內置類型, 但實際上它是 object 的一個 "子類型";架構

具體來講, 函數是 "可調用的對象", 它有一個內部屬性 [[call]], 該屬性使其可以被調用;

既然函數是對象, 那麼它就應該有本身的屬性:

function test(a, b, c) {
    /* .. */
}
test.length // 3
由於該函數聲明瞭三個命名參數,a、b 和 c,因此其 length 值爲 3

複製代碼

能夠看到, 函數的 length 屬性指的是其參數的個數

再來看看數組。JavaScript 支持數組,那麼它是否也是一個特殊類型?

typeof [] === 'object'; // true
// 數組也是對象, 它是 object 的一個子類型,數組的元素按數字順序來進行索引(而非普通像對象那樣經過字符串鍵值),其 length 屬性是元 素的個數。
複製代碼

typeof

typeof 運算符老是會返回一個字符串

typeof typeof 42; // string
複製代碼

該表達式, 首先會執行 typeof 42 返回字符串 number, 再執行 typeof 'number', 返回 string

值和類型

JavaScript 中的變量是沒有類型的,只有值纔有。變量能夠隨時持有任何類型的值。 也就是說, 語言引擎不要求變量老是持有與其初始值同類型的值, 咱們能夠隨時修改變量的值的類型:

var a = 1;
typeof a === 'number' //true
a = "1"
typeof a === 'string' //true
複製代碼

undefined 和 undeclared

undefined 即變量已被聲明, 但未被賦值,undeclared 即沒在做用域中聲明過的變量;

訪問已聲明但未賦值的變量 (undefined), 瀏覽器會返回 undefined; 訪問從未在做用域中聲明的變量 (undeclared), 則會拋出錯誤:

var a;
console.log(a) // undefined
console.log(b) // ReferenceError: b is not defined
複製代碼

上例中,「b is not defined」容易讓人誤覺得是「b is undefined」。此時若是瀏覽器 報錯成「b is not found」或者「b is not declared」會更準確。

再舉個typeof的🌰

var a;
typeof a; // "undefined"
typeof b; // "undefined"
複製代碼

因此要引出一個typeof的安全防範機制的概念

typeof 的安全機制

該安全防範機制對在瀏覽器中運行的 JavaScript 代碼來講仍是頗有幫助的,由於多個腳本 文件會在共享的全局命名空間中加載變量。

舉個🌰

咱們有一個變量叫作 DEBUG, 該變量存放在 dev.js 中, 該 js 文件只會在開發環境被調用, 咱們須要在另外一個 js 文件中判斷 DEBUG 變量是否存在, 而進行接下來的操做

// app.js
if (DEBUG) {
  /* ... */
}
複製代碼

如上代碼, 若是在生產環境, 瀏覽器確定會拋出異常 ReferenceError: DEBUG is not defined, 從而阻斷 js 的運行;

這種狀況, 咱們就能夠經過 typeof 的安全機制來解決這個問題:

if (typeof DEBUG !== 'undefined') {
  /* ... */
}
複製代碼

小結

JavaScript 有 七 種 內 置 類 型:null、undefined、boolean、number、string、object 和 symbol,可使用 typeof 運算符來查看。

變量沒有類型,但它們持有的值有類型。類型定義了值的行爲特徵。

不少開發人員將 undefined 和 undeclared 混爲一談,但在 JavaScript 中它們是兩碼事。 undefined 是值的一種。undeclared 則表示變量尚未被聲明過。

遺憾的是,JavaScript 卻將它們混爲一談,在咱們試圖訪問 "undeclared" 變量時這樣報 錯:ReferenceError: a is not defined, 並 且 typeof 對 undefined 和 undeclared 變 量 都 返 回 "undefined"。

然而,經過 typeof 的安全防範機制(阻止報錯)來檢查 undeclared 變量,有時是個不錯的 辦法。


感悟

第一章給個人感受是知識的範圍不是特別廣,因此特地讀了winter的重學前端,winter開篇就提出了幾個問題。以下:

  • 爲何有的編程規範要求用 void 0 代替 undefined
  • 字符串有最大長度嗎
  • 0.1 + 0.2 不是等於 0.3 麼?爲何 JavaScript不是這樣的
  • ES6的symbol是個什麼玩應兒
  • 爲何給對象添加的方法能用在基本類型上?

後續文章結合於此書沒有給出的知識點給出這些問題的答案~

但願你們都能找到適合本身的學習方法重學前端,完善本身的知識體系架構~

相關文章
相關標籤/搜索