你不知道的JavaScript(中卷)|類型

關(guān)于在我的前端文集中發(fā)表的你不知道的JavaScript(中卷)|xx,是我在閱讀《你不知道的JavaScript》(中卷)時對知識點(diǎn)的摘抄撰茎。

內(nèi)置類型
JavaScript有七種內(nèi)置類型:

  • 空值(null)
  • 未定義(undefined)
  • 布爾值(boolean)
  • 數(shù)字(number)
  • 字符串(string)
  • 對象(object)
  • 符號(symbol嗽冒,ES6中新增)
    除對象之外捌显,其他統(tǒng)稱為“基本類型”。
    我們可以用typeof運(yùn)算符來查看值的類型农尖,它返回的是類型的字符串值屉符。有意思的是剧浸,這七種類型和它們的字符串值并不一一對應(yīng):
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對它的處理有問題:

typeof null === "object"; // true

正確的返回結(jié)果應(yīng)該是“null”唆香,但這個bug由來已久,在JavaScript中已經(jīng)存在了將近二十年吨艇,也許永遠(yuǎn)也不會修復(fù)躬它,因?yàn)檫@牽涉到太多的Web系統(tǒng),“修復(fù)”它會產(chǎn)生更多的bug东涡,令許多系統(tǒng)無法正常工作。
我們需要使用復(fù)合條件來檢測null值的類型:

var a = null;
(!a && typeof a === "object"); // true

還有一種情況:

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

這樣看來疮跑,function(函數(shù))也是JavaScript的一個內(nèi)置類型。然而查閱規(guī)范就會知道祖娘,它實(shí)際上是object的一個“子類型”。具體來說,函數(shù)是“可調(diào)用對象”掀潮,它有一個內(nèi)部屬性[[Call]]菇夸,該屬性使其可以被調(diào)用仪吧。
函數(shù)不僅是對象庄新,還可以擁有屬性薯鼠。例如:

function a(b, c) {
    /* .. */
}

函數(shù)對象的length屬性是其聲明的參數(shù)的個數(shù):

a.length;//2

因?yàn)樵摵瘮?shù)聲明了兩個命名參數(shù)摄咆,b和c,所以其length值為2人断。
再來看看數(shù)組。JavaScript支持?jǐn)?shù)組:

typeof [1,2,3] === "object"; // true

數(shù)組也是對象恶迈。確切地說谱醇,它也是object的一個“子類型”暇仲,數(shù)組的元素按數(shù)字順序來進(jìn)行索引(而非普通像對象那樣通過字符串鍵值)副渴,其length屬性是元素的個數(shù)。

值和類型
JavaScript中的變量是沒有類型的煮剧,只有值才有。變量可以隨時持有任何類型的值勉盅。

undefined和undeclared
變量在未持有值的時候?yàn)閡ndefined。此時typeof返回“undefined”挑胸。
大多數(shù)開發(fā)者傾向于將undefined等同于undeclared(未聲明)宰闰,但在JavaScript中它們完全是兩回事。
已在作用域中聲明但還沒有賦值的變量移袍,是undefined的。相反舆逃,還沒有在作用域中聲明過的變量,是undeclared的路狮。

var a;
a; // undefined
b; // ReferenceError: b is not defined
var a;
typeof a; // "undefined"
typeof b; // "undefined"

對于undeclared(或者not defined)變量,typeof照樣返回“undefined”涂籽。請注意雖然b是一個undeclared變量,但typeof b并沒有報錯砸抛。這是因?yàn)閠ypeof有一個特殊的安全防范機(jī)制。
typeof Undeclared
該安全防范機(jī)制對在瀏覽器中運(yùn)行的JavaScript代碼來說還是很有幫助的景东,因?yàn)槎鄠€腳本文件會在共享的全局命名空間中加載變量奔誓。
舉個簡單的例子,在程序中使用全局變量DEBUG作為“調(diào)試模式”的開關(guān)和措。在輸出調(diào)試信息到控制臺之前蜕煌,我們會檢查DEBUG變量是否已被聲明。頂層的全局變量聲明var DEBUG=true只在debug.js文件中才有斜纪,而該文件只在開發(fā)和測試時才被加載到瀏覽器,在生產(chǎn)環(huán)境中不予加載颁独。
問題是如何在程序中檢查全局變量DEBUG才不會出現(xiàn)ReferenceError錯誤伪冰。這時typeof的安全防范機(jī)制就成了我們的好幫手:

// 這樣會拋出錯誤
if (DEBUG) {
    console.log("Debugging is starting");
}
// 這樣是安全的
if (typeof DEBUG !== "undefined") {
    console.log("Debugging is starting");
}

這不僅對用戶定義的變量(比如DEBUG)有用,對內(nèi)建的API也有幫助:

if (typeof atob === "undefined") {
    atob = function() { /*..*/ };
}

如果要為某個缺失的功能寫polyfill(即襯墊代碼或補(bǔ)充代碼靠柑,用來補(bǔ)充當(dāng)前運(yùn)行環(huán)境中缺失的功能)吓懈,一般不會用var atob來聲明變量atob。如果在if語句中使用var atob耻警,聲明會被提升到作用域(即當(dāng)前腳本或函數(shù)的作用域)的最頂層甸怕,即使if條件不成立也是如此(因?yàn)閍tob全局變量已經(jīng)存在)腮恩。在有些瀏覽器中,對于一些特殊的內(nèi)建全局變量(通常稱為“宿主對象”)武契,這樣的重復(fù)聲明會報錯荡含。去掉var則可以防止聲明被提升。
還有一種不用通過typeof的安全防范機(jī)制的方法全释,就是檢查所有全局變量是否是全局對象的屬性误债,瀏覽器中的全局對象是window。所以前面的例子也可以這樣來實(shí)現(xiàn):

if (window.DEBUG) {
    // ..
}
if (!window.atob) {
    // ..
}

與undeclared變量不同,訪問不存在的對象屬性(甚至是在全局對象window上)不會產(chǎn)生ReferenceError錯誤判族。
一些開發(fā)人員不喜歡通過window來訪問全局對象,尤其當(dāng)代碼需要運(yùn)行在多種JavaScript環(huán)境中時(不僅僅是瀏覽器槽惫,還有服務(wù)器端辩撑,如node.js等),因此此時全局對象并非總是window合冀。
從技術(shù)角度來說,typeof的安全防范機(jī)制對于非全局變量也很管用峭判,雖然這種情況并不多見棕叫,也有一些開發(fā)人員不大愿意這樣做。如果想讓別人在他們的程序或模塊中復(fù)制黏貼你的代碼疗认,就需要檢查你用到的變量是否已經(jīng)在宿主程序中定義過:

function doSomethingCool() {
    var helper =
        (typeof FeatureXYZ !== "undefined") ?
            FeatureXYZ :
            function () { /*.. default feature ..*/ };
    var val = helper();
    // ..
}

還有一些人喜歡使用“依賴注入”設(shè)計(jì)模式,就是將依賴通過參數(shù)顯示地傳遞到函數(shù)中横漏,如:

function doSomethingCool(FeatureXYZ) {
    var helper = FeatureXYZ ||
        function () { /*.. default feature ..*/ };
    var val = helper();
    // ..
}
好不容易在夢里可以看見您绊茧,然后您卻還是一句話都沒有對我說
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鹏秋,隨后出現(xiàn)的幾起案子亡笑,更是在濱河造成了極大的恐慌,老刑警劉巖百拓,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晰甚,死亡現(xiàn)場離奇詭異,居然都是意外死亡蓖捶,警方通過查閱死者的電腦和手機(jī)扁远,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來并闲,“玉大人谷羞,你說我怎么就攤上這事∨榷校” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵宏浩,是天一觀的道長靠瞎。 經(jīng)常有香客問我求妹,道長佳窑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任净神,我火速辦了婚禮溉委,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘坡慌。我一直安慰自己藻三,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布熄求。 她就那樣靜靜地躺著逗概,像睡著了一般。 火紅的嫁衣襯著肌膚如雪仗谆。 梳的紋絲不亂的頭發(fā)上淑履,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天秘噪,我揣著相機(jī)與錄音,去河邊找鬼指煎。 笑死,一個胖子當(dāng)著我的面吹牛威始,可吹牛的內(nèi)容都是我干的像街。 我是一名探鬼主播晋渺,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼脓斩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了八千?” 一聲冷哼從身側(cè)響起燎猛,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鸠信,沒想到半個月后论寨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绰垂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年火焰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片占业。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡纯赎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出犬金,到底是詐尸還是另有隱情,我是刑警寧澤峰伙,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布该默,位于F島的核電站,受9級特大地震影響匣摘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜恋沃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一囊咏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧梅割,春花似錦、人聲如沸户辞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽双仍。三九已至,卻和暖如春苞轿,著一層夾襖步出監(jiān)牢的瞬間逗物,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工契邀, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留莲祸,地道東北人蹂安。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像畜号,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蛮拔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 這兩周主要看的第一部分。第一部分由5章組成畦韭,現(xiàn)看到第一部分的第四章完結(jié)肛跌。做一下讀書筆記總結(jié)。 第一章 類型 具體細(xì)...
    原味的夏天寶寶閱讀 371評論 0 0
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持转唉,譯者再次奉上一點(diǎn)點(diǎn)福利:阿里云產(chǎn)品券稳捆,享受所有官網(wǎng)優(yōu)惠赠法,并抽取幸運(yùn)大...
    HetfieldJoe閱讀 1,395評論 3 9
  • 你不懂JS:類型與文法 第一章:類型 大多數(shù)開發(fā)者會說砖织,動態(tài)語言(就像JS)沒有 類型末荐。讓我們看看ES5.1語言規(guī)...
    xiayujlu閱讀 155評論 0 0
  • 特別說明,為便于查閱茂蚓,文章轉(zhuǎn)自https://github.com/getify/You-Dont-Know-JS...
    殺破狼real閱讀 297評論 0 0
  • 記一次南京之行~廢話不多說剃幌,上圖。 南京的特產(chǎn)有很多~章云板鴨店是南京人的寵兒负乡。料特別多,也很便宜茂腥。打開的那一刻我...
    書中自有東施閱讀 370評論 0 0