接下來的一系列學(xué)習(xí)筆記都來自于阮一峰老師的JavaScript 教程疾忍,重新回顧一遍JavaScript基礎(chǔ)叶眉。
本篇是對于這個教程中數(shù)據(jù)類型的相關(guān)總結(jié)黑竞。
在學(xué)習(xí)基礎(chǔ)知識之前眨层,先來看一下關(guān)于JavaScript的相關(guān)介紹和特點:
- JavaScript 是一種輕量級的腳本語言匣距。
- 是一種嵌入式語言面哥,本身不提供任何與 I/O相關(guān)的 API,都要靠宿主環(huán)境(host)提供
- 從語法角度看毅待,JavaScript 語言是一種“對象模型”語言
- JavaScript 并不是純粹的“面向?qū)ο笳Z言”尚卫,還支持其他編程范式(比如函數(shù)式編程)
下面以提問的方式來對JavaScript的數(shù)據(jù)類型來進行學(xué)習(xí)和總結(jié):
JavaScript中有幾種數(shù)據(jù)類型?
JavaScript 的數(shù)據(jù)類型尸红,共有六種,(ES6 又新增了第七種 Symbol 類型的值).
主要包括:數(shù)值(number)吱涉,字符串(string)刹泄,布爾值(boolean),undefined怎爵,null特石,以及對象(object)。
其中對象又包括狹義的對象object鳖链,函數(shù)和數(shù)組姆蘸。
判斷數(shù)據(jù)類型的方法?
JavaScript 有三種方法撒轮,可以確定一個值到底是什么類型乞旦。
- typeof運算符
- instanceof運算符
- Object.prototype.toString方法
不過需要注意,null使用typeof運算符會返回object题山。
為何typeof 用來檢查一個沒有聲明的變量不報錯兰粉?
- 因為 typeof undefined // "undefined"
null 和 undefined 有什么區(qū)別?
- null是一個表示“空”的對象顶瞳,轉(zhuǎn)為數(shù)值時為0玖姑;
- undefined是一個表示"此處無定義"的原始值,轉(zhuǎn)為數(shù)值時為NaN慨菱。
布爾值的轉(zhuǎn)化規(guī)則焰络?
如果 JavaScript 預(yù)期某個位置應(yīng)該是布爾值,會將該位置上現(xiàn)有的值自動轉(zhuǎn)為布爾值符喝。轉(zhuǎn)換規(guī)則是除了下面六個值被轉(zhuǎn)為false闪彼,其他值都視為true。
- undefined
- null
- false
- 0
- NaN
- ""或''(空字符串)
為何說JavaScript 語言的底層根本沒有整數(shù)协饲?
- JavaScript 內(nèi)部畏腕,所有數(shù)字都是以64位浮點數(shù)形式儲存,即使整數(shù)也是如此茉稠。所以描馅,1與1.0是相同的,是同一個數(shù)而线。1 === 1.0 // true
+0 和 -0的區(qū)別铭污?
- 幾乎所有場合,正零和負零都會被當作正常的0膀篮。唯一有區(qū)別的場合是嘹狞,+0或-0當作分母,返回的值是不相等的誓竿。
數(shù)值NaN有什么特殊性磅网?
- 屬于Number類型,
typeof NaN // 'number'
- NaN不等于任何值烤黍,包括它本身
- indexOf方法不能判定NaN
- NaN與任何數(shù)(包括它自己)的運算知市,得到的都是NaN
- NaN在布爾運算時被當作false
為何使用isNaN之前傻盟,最好判斷一下數(shù)據(jù)類型?
- 因為isNaN只對數(shù)值有效嫂丙,如果傳入其他值娘赴,會被先轉(zhuǎn)成數(shù)值。當isNaN為true的值跟啤,有可能不是NaN诽表。
如何把長字符串分成多行?
- 在每一行的尾部使用反斜杠
為什么對象的所有鍵名加不加引號都可以?
- 因為對象的所有鍵名都是字符串
如果行首是一個大括號隅肥,它到底是表達式還是語句竿奏?
- JavaScript 引擎的做法是,如果遇到這種情況腥放,無法確定是對象還是代碼塊泛啸,一律解釋為代碼塊。如果要解釋為對象秃症,最好在大括號前加上圓括號候址。
delete命令可以刪除對象的所有屬性嗎?
- 只能刪除對象本身的屬性种柑,無法刪除繼承的屬性岗仑,即使delete返回true,該屬性依然可能讀取到值聚请。
for...in 循環(huán) 和普通for循環(huán)的區(qū)別
- for...in 遍歷的是對象所有可遍歷(enumerable)的屬性荠雕,會跳過不可遍歷的屬性。它不僅遍歷對象自身的屬性驶赏,還遍歷繼承的屬性炸卑。
- 標準的for循環(huán)中的i是number類型,表示的是數(shù)組的下標,但是foreach循環(huán)中例如
for(var i in array)
的i表示的是數(shù)組的key是string類型 - for循環(huán)是對數(shù)組的元素進行循環(huán),而不能引用于非數(shù)組對象
arguments 對象跟數(shù)組的關(guān)系母市?
- arguments對象包含了函數(shù)運行時的所有參數(shù)矾兜,具有l(wèi)ength屬性损趋,可以判斷函數(shù)調(diào)用時到底帶幾個參數(shù)
- arguments是類數(shù)組患久,“類似數(shù)組的對象”的根本特征,就是具有l(wèi)ength屬性浑槽。只要有l(wèi)ength屬性蒋失,就可以認為這個對象類似于數(shù)組
- 雖然arguments很像數(shù)組,但它是一個對象桐玻。數(shù)組專有的方法(比如slice和forEach)篙挽,不能在arguments對象上直接使用
- 將arguments轉(zhuǎn)為真正的數(shù)組:
Array.prototype.slice.call(arguments)
JavaScript 的作用域?
JavaScript 有兩種作用域:全局作用域和函數(shù)作用域
- 全局作用域:變量在整個程序中一直存在镊靴,所有地方都可以讀认晨ā链韭;
- 函數(shù)作用域,變量只在函數(shù)內(nèi)部存在煮落。
- (ES6 新增了塊級作用域)
函數(shù)本身的作用域在哪里敞峭?
函數(shù)本身也是一個值,也有自己的作用域蝉仇。它的作用域與變量一樣旋讹,就是其聲明時所在的作用域,與其運行時所在的作用域無關(guān)轿衔。
var a = 'out';
var x = function () {
console.log(a);
};
function f() {
var a = 'inter';
x();
}
f() // 'out'
函數(shù)參數(shù)的傳遞方式沉迹?
- 函數(shù)參數(shù)如果是原始類型的值(數(shù)值、字符串害驹、布爾值)鞭呕,傳遞方式是傳值傳遞
- 如果函數(shù)參數(shù)是復(fù)合類型的值(數(shù)組、對象宛官、其他函數(shù))琅拌,傳遞方式是傳址傳遞(pass by reference)。因此在函數(shù)內(nèi)部修改參數(shù)摘刑,將會影響到原始值进宝。
如果在函數(shù)體內(nèi)修改參數(shù)值,會不會影響到函數(shù)外部枷恕?
- 如果是原始類型的值(數(shù)值党晋、字符串、布爾值)徐块,傳遞方式是傳值傳遞未玻,不影響;
- 如果是復(fù)合類型的值(數(shù)組胡控、對象扳剿、其他函數(shù)),傳遞方式是傳址傳遞昼激。在函數(shù)內(nèi)部修改參數(shù)庇绽,將會影響到原始值;
- 如果函數(shù)內(nèi)部修改的,不是參數(shù)對象的某個屬性橙困,而是替換掉整個參數(shù)瞧掺,這時不會影響到原始值;
什么是閉包?
當我們需要獲取到某個函數(shù)f1的局部變量時凡傅,我們可以在函數(shù)f1內(nèi)定義一個函數(shù)f2辟狈,則在函數(shù)B中可以獲到f1中的局部變量,把函數(shù)f2作為返回值return回來,我們就可以在函數(shù)f1的外部獲取到它的局部變量哼转,此時明未,這個函數(shù)f2就是閉包。
閉包壹蔓,即能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)亚隅。
閉包的用處:
- 讀取函數(shù)內(nèi)部的變量,讓這些變量始終保持在內(nèi)存中庶溶,即閉包可以使得它誕生環(huán)境一直存在煮纵。
- 封裝對象的私有屬性和私有方法
為何不能濫用閉包?
- 內(nèi)存消耗會很大偏螺,造成網(wǎng)頁的性能問題行疏。
立即調(diào)用的函數(shù)表達式(IIFE)的作用是什么?
- 不必為函數(shù)命名套像,避免了污染全局變量
- IIFE 內(nèi)部形成了一個單獨的作用域酿联,可以封裝一些外部無法讀取的私有變量。
數(shù)組的某個位置是空位與某個位置是undefined的區(qū)別夺巩?
- 如果是空位贞让,使用數(shù)組的forEach方法、for...in結(jié)構(gòu)柳譬、以及Object.keys方法進行遍歷喳张,空位都會被跳過。