類型----《你不知道的js》

1、內置類型

js共有7種內置類型:數組

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

除對象外,其餘統稱爲「基本類型」瀏覽器

咱們可用typeof來查看值的類型:安全

typeof undefined === "undefined"; // true
typeof true === "boolean"; // true
typeof 42 === "number"; // true
typeof "42" === "string"; // true
typeof { life: 42 } === "object"; // true
// ES6新增類型
typeof Symbol() === "symbol"; // true
複製代碼

null比較特殊,typeof對它處理有問題:bash

typeof null === "object"; // true
複製代碼

正確結果應該返回null,但這個bug由來已久,在js中已經存在了將近20年,因爲牽涉到太多的Web系統,「修復」它會產生更多的bug,令許多系統沒法修復。函數

咱們須要使用符合條件來檢測null的類型:spa

var a = null;
(!a && typeof a === "object"); // true
複製代碼

null是假值,也是惟一一個用typeof檢測會返回「object」的基本類型code

還有一種狀況:對象

typeof function a() { /*...*/ } === "function"; // true
複製代碼

function也是js的一個內置函數。其實是object的一個「子類型」。具體來講,函數是「可調用對象」,它有一個內部屬性[[Call]],該屬性使其能夠被調用。索引

函數不只是對象,還能夠擁有屬性。如:作用域

function a(b, c) {
    /*..*/
}
複製代碼

函數對象的length屬性是其聲明的參數的個數:

a.length; // 2
複製代碼

該函數聲明瞭兩個命名參數,b、c,因此其length值爲2

typeof [1, 2, 3] === "object"; // true
複製代碼

數組也是對象,確切的說是object的一個「子類型」,數組的元素按數字順序來進行索引,其length屬性是元素的個數

3、值和類型

js中的變量是沒有類型的,只有值纔有。變量能夠隨時持有任何類型的值。js不作「類型強制」,語言引擎不要求變量老是持有與其初始值同類型的值。

在對變量執行操做時,獲得的結果並非該變量的類型,而是該變量持有的值的類型,由於js中的變量沒有類型

var a = 42;
typeof a; // "number"
a = true;
typeof a; // "boolean"
複製代碼

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

typeof typeof 42; // "string"
複製代碼

typeof 42 = "number", typeof "number" = "string"

一、undefined和undeclared

變量在未持有值的時候爲undefined,此時typeof返回「undefined」

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

大多數開發者傾向於undefined等同於undeclared(未聲明),但在js中他們徹底是兩回事

  • undefined:已在做用域中聲明但尚未賦值的變量
  • undeclared:尚未在做用域中聲明過的變量
var a;
a; // undefined
b; // ReferenceError: b is not defined
複製代碼

undefined 和 is not defined是兩碼事。若此時瀏覽器報錯成「b is not found」 或 「b is not declared」會更準確

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

對於undeclared變量,typeof照樣返回"undefined"

雖然b是一個undeclared變量,但typeof b沒報錯,這是由於typeof有一個特殊的安全防範機制

二、typeof Undeclared

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

如何在程序中檢查全局變量DEBUG纔不會出現RefrenceError錯誤,這是typeof的安全防範機制就能作到:

// 這樣會報錯
if (DEBUG) {
    console.log("Debugging is staring");
}
// 這樣是安全的
if (typeof DEBUG !== "undefined") {
    console.log("Debugging is staring");
}
複製代碼

還有一種不經過typeof的安全防範機制的方法,就是檢查全部全局變量是不是全局對象的屬性,瀏覽器中的全局對象是window

if (window.DEBUG) {
    // ..
}
if (!window.atob) {
    // ..
}
複製代碼

與undeclared變量不一樣,訪問不存在的對象屬性(甚至是在全局對象window上)不會產生RefrenceError錯誤。

相關文章
相關標籤/搜索