筆記來(lái)自《JavaScript權(quán)威指南(第六版)》
包含的內(nèi)容:
在JavaScript中,類(lèi)的所有實(shí)例對(duì)象都從同一個(gè)原型對(duì)象上繼承屬性。因此,原型對(duì)象是類(lèi)的核心。
定義構(gòu)造函數(shù)既是定義類(lèi),并且類(lèi)名首字母要大寫(xiě)。而普通的函數(shù)和方法都是首字母小寫(xiě)的。
任何JavaScript函數(shù)都可以用做構(gòu)造函數(shù),并且調(diào)用構(gòu)造函數(shù)是需要用到一個(gè)prototype屬性的。因此,每個(gè)JavaScript函數(shù)都自動(dòng)擁有一個(gè)prototype屬性。這個(gè)屬性的值是一個(gè)對(duì)象,這個(gè)對(duì)象包含唯一一個(gè)不可枚舉屬性constructor。
對(duì)于任意函數(shù)F.prototype.constructor == F
JavaScript中的函數(shù)都是以值的形式出現(xiàn)的,方法和字段之間并沒(méi)有太大的區(qū)別。如果屬性值是函數(shù),那么這個(gè)函數(shù)就定義一個(gè)方法;否則,它只是一個(gè)普通的屬性或“字段”。
JavaScript中基于原型的繼承機(jī)制是動(dòng)態(tài)的:對(duì)象從其原型繼承屬性,如果創(chuàng)建對(duì)象之后原型的屬性發(fā)生改變,也會(huì)影響到繼承這個(gè)原型的所有實(shí)例對(duì)象。
可以給Object.prototype添加方法,從而使所有的對(duì)象都可以調(diào)用這些方法。但是這種做法無(wú)法將這些新增加的方法設(shè)置為不可枚舉的。可以使用Object.defineProperty()方法安全地?cái)U(kuò)充Object.prototype。
instanceof檢測(cè)對(duì)象是否是屬于某個(gè)類(lèi)的構(gòu)造函數(shù),不一定是直接繼承。
構(gòu)造函數(shù)是類(lèi)的公共標(biāo)識(shí),當(dāng)原型是唯一的標(biāo)識(shí)。
如果想檢測(cè)對(duì)象的原型鏈上是否存在某個(gè)特定的原型對(duì)象,可以使用isPrototypeOf()方法。
Instanceof和isPrototypeOf()的缺點(diǎn)是,我們無(wú)法通過(guò)對(duì)象來(lái)獲得類(lèi)名,只能檢測(cè)對(duì)象是否屬于指定的類(lèi)名。
另一個(gè)識(shí)別對(duì)象是否屬于某個(gè)類(lèi)的方法是使用constructor屬性。
使用構(gòu)造函數(shù)的名字而不是構(gòu)造函數(shù)本身作為類(lèi)標(biāo)識(shí)符。在一些JavaScript的實(shí)現(xiàn)中為函數(shù)對(duì)象提供了一個(gè)非標(biāo)準(zhǔn)的屬性name,用來(lái)表示函數(shù)的名稱(chēng)。
【圖】可以判斷值的類(lèi)型的type()函數(shù)。
鴨式辯型:如果一個(gè)對(duì)象可以像鴨子一樣走路、游泳并且嘎嘎叫,就認(rèn)為這個(gè)對(duì)象是鴨子,哪怕它并不是從鴨子類(lèi)的原型對(duì)象繼承而來(lái)的。
ValueOf()用來(lái)將對(duì)象轉(zhuǎn)換為原始值。
toJSON()由JSON.stringify()自動(dòng)調(diào)用的。JSON格式用于序列化良好的數(shù)據(jù)結(jié)構(gòu),而且可以處理JavaScript原始值、數(shù)組和純對(duì)象。它和類(lèi)無(wú)關(guān),當(dāng)對(duì)一個(gè)對(duì)象執(zhí)行序列化操作時(shí),它會(huì)忽略對(duì)象的原型和構(gòu)造函數(shù)。
JSON.parse()將字符串轉(zhuǎn)化為純對(duì)象,不包含繼承來(lái)的方法。
方法借用,也叫做“多重繼承”,把一個(gè)類(lèi)的方法用到其他的類(lèi)中的做法。
如:Range.prototype.equals = generic.equals;
私有實(shí)例字段,只能被類(lèi)的實(shí)例方法訪問(wèn),且在類(lèi)的外部是不可見(jiàn)的。
可以通過(guò)將變量(或參數(shù))閉包在一個(gè)構(gòu)造函數(shù)內(nèi)來(lái)模擬實(shí)現(xiàn)私有實(shí)例字段,調(diào)用構(gòu)造函數(shù)會(huì)創(chuàng)建一個(gè)實(shí)例。為了做到這一點(diǎn),需要在構(gòu)造函數(shù)內(nèi)部定義一個(gè)函數(shù)(因此這個(gè)函數(shù)可以訪問(wèn)構(gòu)造函數(shù)內(nèi)部的參數(shù)和變量),并將這個(gè)函數(shù)賦值給新創(chuàng)建對(duì)象的屬性。
使用閉包來(lái)封裝類(lèi)的狀態(tài)的類(lèi)一定會(huì)比不使用封裝的狀態(tài)變量的等價(jià)類(lèi)運(yùn)行速度更慢,并占用更多的內(nèi)存。
B.prototype = inherit(A.prototype); //子類(lèi)派生自父類(lèi)
B.prototype.constructor = B; //重載繼承來(lái)的constructor屬性
這兩行代碼是在JavaScript中創(chuàng)建子類(lèi)的關(guān)鍵。如果不這樣做,原型對(duì)象僅僅是一個(gè)普通對(duì)象,它只繼承自O(shè)bject.prototype,這意味著你的類(lèi)和所有的類(lèi)一樣是Object的子類(lèi)。
定義子類(lèi)時(shí),我們往往希望對(duì)父類(lèi)的行為進(jìn)行修改或擴(kuò)充,而不是完全替換掉它們。為了做到這一點(diǎn),構(gòu)造函數(shù)和子類(lèi)的方法需要調(diào)用或鏈接到父類(lèi)構(gòu)造函數(shù)和父類(lèi)方法。
Object.defineProperty()和Object.defineProperties()可以用來(lái)創(chuàng)建新屬性,也可以修改已有屬性的特性。當(dāng)用它們創(chuàng)建新屬性時(shí),默認(rèn)的屬性特性的值都是false。但當(dāng)用它們修改已經(jīng)存在的屬性時(shí),默認(rèn)的屬性特性依然保持不變。
通常認(rèn)為,通過(guò)給原型對(duì)象添加方法可以動(dòng)態(tài)地對(duì)類(lèi)進(jìn)行擴(kuò)展,這是JavaScript本身的特性。ECMAScript 5可以根據(jù)需要對(duì)此特性加以限制。
Object.preventExtensions()可以將對(duì)象設(shè)置為不可擴(kuò)展的,也就是說(shuō)不能給對(duì)象添加任何新屬性。
Object.seal()則更加強(qiáng)大,它除了能阻止用戶(hù)給對(duì)象添加新屬性,還能將當(dāng)前已有的屬性設(shè)置為不可配置的。這樣就不能刪除這些屬性了,但不可配置的屬性可以是可寫(xiě)的,也可以轉(zhuǎn)換為只讀屬性。Object.seal(Object.prototype)。
一般來(lái)講,模塊是一個(gè)獨(dú)立的JavaScript文件。模塊文件可以包含一個(gè)類(lèi)定義、一組相關(guān)的類(lèi)、一個(gè)實(shí)用函數(shù)庫(kù)或者是一些待執(zhí)行的代碼。
在模塊創(chuàng)建過(guò)程中避免污染全局變量的一種方法是使用一個(gè)對(duì)象作為命名空間。它將函數(shù)和值作為命名空間對(duì)象屬性存儲(chǔ)起來(lái)(可以通過(guò)全局變量應(yīng)用),而不是定義全局函數(shù)和變量。
如果想讓代碼在一個(gè)私有命名空間中運(yùn)行,只需要把代碼放在如下的位置。使用了立即執(zhí)行的匿名函數(shù)。
(function(){
/*代碼*/
}())
子集的定義大部分都是出于安全考慮,只有使用這門(mén)語(yǔ)言的一個(gè)安全的子集編寫(xiě)腳本,才能讓代碼執(zhí)行地更安全、更穩(wěn)定,比如如何更安全地執(zhí)行一段由不可信第三方提供的廣告代碼。
為了讓JavaScript代碼靜態(tài)地通過(guò)安全檢查,必須移除一些JavaScript特性:
安全子集:ADsafe、dojox.secure、Caja、FBJS、Microsoft Web Sandbox、
const pi = 3.14; //定義一個(gè)常量并賦值
關(guān)鍵字let有4種使用方式:
1、 可以作為變量聲明,和var一樣;
2、 在for/in循環(huán)中,作為var的替代方案;
3、 在語(yǔ)句塊中定義一個(gè)新變量并顯式指定它的作用域;
4、 定義一個(gè)在表達(dá)式內(nèi)部作用域中的變量,這個(gè)變量只在表達(dá)式內(nèi)可用。
JavaScript擴(kuò)展:解構(gòu)賦值、迭代器、生成器yield、數(shù)組推導(dǎo)、函數(shù)簡(jiǎn)寫(xiě)、多catch從句。。。
文檔信息
聯(lián)系客服