摘要:在這種情況下,函數(shù)在停止執(zhí)行后將返回值。這種用法一般用在需要提前停止函數(shù)執(zhí)行而又不需要返回值的情況下嚴(yán)格模式對(duì)函數(shù)有一些限制不能把函數(shù)命名為或不能把參數(shù)命名為或不能出現(xiàn)兩個(gè)命名參數(shù)同名的情況。
把近期看高程這本書(shū)做的筆記摘錄整理出來(lái)了,總歸對(duì)原生javascript理論有了一個(gè)比較全面的的認(rèn)識(shí),這次把書(shū)中的一些知識(shí)要點(diǎn)摘錄出來(lái)了,便于以后查閱的時(shí)候有方向,也更有效率?。?/p> 第一章、javascript簡(jiǎn)介
0101、完整的javascript有三部分組成:核心ECMAScript,DOM和BOM
0102、ECMAScript規(guī)定了語(yǔ)言的下列組成部分:語(yǔ)法,類(lèi)型,語(yǔ)句,關(guān)鍵字,保留字,操作符,對(duì)象
第二章、在html中使用javascript0201、HTML4.01為script定義了下列6個(gè)屬性:async:可選,表示立即下載腳本,不阻塞;charset:可選,指定字符集;defer:可選,延遲到文檔完全被解析和顯示之后再執(zhí)行;language:已廢棄;src:可選,包含要執(zhí)行代碼的外部文件;type:可選,腳本語(yǔ)言的內(nèi)容類(lèi)型
0202、標(biāo)簽的位置:所有script元素都應(yīng)該放在頁(yè)面的
元素頁(yè)面內(nèi)容的后面0203、IE8以后不支持defer屬性
0204、async屬性的目的是不讓頁(yè)面等待腳本下載和執(zhí)行,從而異步加載頁(yè)面其他內(nèi)容
0205、<小于號(hào)在XHTML中會(huì)被當(dāng)作開(kāi)始一個(gè)新標(biāo)簽來(lái)解析
0206、noscript包含該元素的內(nèi)容只有在以下情況才會(huì)顯示出來(lái):不支持腳本,支持腳本但被禁用
第三章、基本概念0301、標(biāo)識(shí)符,就是指變量、函數(shù)、屬性的名字,或者函數(shù)的參數(shù):第一個(gè)字符必須是一個(gè)字母、下劃線( _ )或一個(gè)美元符號(hào)( $ );
其他字符可以是字母、下劃線、美元符號(hào)或數(shù)字
0302、嚴(yán)格模式下,ECMAScript 3 中的一些不確定的行為將得到處理,而且對(duì)某些不安全的操作也會(huì)拋出錯(cuò)誤。在函數(shù)內(nèi)部的上方包含這條編譯指示,也可以指定函數(shù)在嚴(yán)格模式下執(zhí)行
0303、加上這個(gè)分號(hào)可以避免很多錯(cuò)誤,加上分號(hào)也會(huì)在某些情況下增進(jìn)代碼的性能,因?yàn)檫@樣解析器就不必再花時(shí)間推測(cè)應(yīng)該在哪里插入分號(hào)了
0304、用 var 操作符定義的變量將成為定義該變量的作用域中的局部變量。也就是說(shuō),如果在函數(shù)中使用 var 定義一個(gè)變量,那么這個(gè)變量在函數(shù)退出后就會(huì)被銷(xiāo)毀。雖然省略 var 操作符可以定義全局變量,但這也不是我們推薦的做法。給未經(jīng)聲明的變量賦值在嚴(yán)格模式下會(huì)導(dǎo)致拋出 ReferenceError 錯(cuò)誤
0305、ECMAScript 中有 5 種簡(jiǎn)單數(shù)據(jù)類(lèi)型(也稱(chēng)為基本數(shù)據(jù)類(lèi)型):Undefined 、Null、Boolean 、Number和 String 。還有 1種復(fù)雜數(shù)據(jù)類(lèi)型—— Object , Object 本質(zhì)上是由一組無(wú)序的名值對(duì)組成的
0306、Safari 5 及之前版本、Chrome 7 及之前版本在對(duì)正則表達(dá)式調(diào)用 typeof 操作符時(shí)會(huì)返回 "function" ,而其他瀏覽器在這種情況下會(huì)返回"object"
0307、對(duì)未經(jīng)聲明的變量調(diào)用 delete 不會(huì)導(dǎo)致錯(cuò)誤,但這樣做沒(méi)什么實(shí)際意義,而且在嚴(yán)格模式下確實(shí)會(huì)導(dǎo)致錯(cuò)誤
0308、對(duì)未初始化和未聲明的變量執(zhí)行 typeof 操作符都返回了 undefined 值;這個(gè)結(jié)果有其邏輯上的合理性。因?yàn)殡m然這兩種變量從技術(shù)角度看有本質(zhì)區(qū)別,但實(shí)際上無(wú)論對(duì)哪種變量也不可能執(zhí)行真正的操作
0309、如果定義的變量準(zhǔn)備在將來(lái)用于保存對(duì)象,那么最好將該變量初始化為 null 而不是其他值。只要意在保存對(duì)象的變量還沒(méi)有真正保存對(duì)象,就應(yīng)該明確地讓該變量保存null值。這樣做不僅可以體現(xiàn) null 作為空對(duì)象指針的慣例,而且也有助于進(jìn)一步區(qū)分null和undefined
0310、要將一個(gè)值轉(zhuǎn)換為其對(duì)應(yīng)的 Boolean 值,可以調(diào)用轉(zhuǎn)型函數(shù) Boolean()
0311、八進(jìn)制字面值的第一位必須是零(0),然后是八進(jìn)制數(shù)字序列(0~7)。如果字面值中的數(shù)值超出了范圍,那么前導(dǎo)零將被忽略,后面的數(shù)值將被當(dāng)作十進(jìn)制數(shù)值解析
0312、十六進(jìn)制字面值的前兩位必須是 0x,后跟任何十六進(jìn)制數(shù)字(0~9 及 A~F)。其中,字母 A~F可以大寫(xiě),也可以小寫(xiě)
0313、保存浮點(diǎn)數(shù)值需要的內(nèi)存空間是保存整數(shù)值的兩倍,因此 ECMAScript會(huì)不失時(shí)機(jī)地將浮點(diǎn)數(shù)值轉(zhuǎn)換為整數(shù)值
0314、在默認(rèn)情況下,ECMASctipt 會(huì)將那些小數(shù)點(diǎn)后面帶有 6 個(gè)零以上的浮點(diǎn)數(shù)值轉(zhuǎn)換為以 e 表示法表示的數(shù)值(例如,0.0000003 會(huì)被轉(zhuǎn)換成 3e-7)
0315、浮點(diǎn)數(shù)值的最高精度是 17 位小數(shù),但在進(jìn)行算術(shù)計(jì)算時(shí)其精確度遠(yuǎn)遠(yuǎn)不如整數(shù)。例如,0.1 加 0.2的結(jié)果不是 0.3,而是 0.30000000000000004。這個(gè)小小的舍入誤差會(huì)導(dǎo)致無(wú)法測(cè)試特定的浮點(diǎn)數(shù)值
0316、要想確定一個(gè)數(shù)值是不是有窮的(換句話(huà)說(shuō),是不是位于最小和最大的數(shù)值之間),可以使用 isFinite() 函數(shù)。這個(gè)函數(shù)在參數(shù)位于最小與最大數(shù)值之間時(shí)會(huì)返回 true
0317、NaN 與任何值都不相等,包括 NaN本身18、 isNaN() 在接收到一個(gè)值之后,會(huì)嘗試將這個(gè)值轉(zhuǎn)換為數(shù)值。某些不是數(shù)值的值會(huì)直接轉(zhuǎn)換為數(shù)值,例如字符串 "10" 或 Boolean 值。而任何不能被轉(zhuǎn)換為數(shù)值的值都會(huì)導(dǎo)致這個(gè)函數(shù)返回true
0318、盡管有點(diǎn)兒不可思議,但 isNaN() 確實(shí)也適用于對(duì)象。在基于對(duì)象調(diào)用 isNaN()函數(shù)時(shí),會(huì)首先調(diào)用對(duì)象的 valueOf() 方法,然后確定該方法返回的值是否可以轉(zhuǎn)換為數(shù)值。如果不能,則基于這個(gè)返回值再調(diào)用 toString() 方法,再測(cè)試返回值。而這個(gè)過(guò)程也是 ECMAScript中內(nèi)置函數(shù)和操作符的一般執(zhí)行流程
0319、由于 Number() 函數(shù)在轉(zhuǎn)換字符串時(shí)比較復(fù)雜而且不夠合理,因此在處理整數(shù)的時(shí)候更常用的是parseInt()函數(shù)。parseInt() 函數(shù)在轉(zhuǎn)換字符串時(shí),更多的是看其是否符合數(shù)值模式。它會(huì)忽略字符串前面的空格,直至找到第一個(gè)非空格字符。如果第一個(gè)字符不是數(shù)字字符或者負(fù)號(hào), parseInt()就會(huì)返回 NaN ;也就是說(shuō),用 parseInt() 轉(zhuǎn)換空字符串會(huì)返回 NaN ( Number() 對(duì)空字符返回 0)。如果第一個(gè)字符是數(shù)字字符, parseInt() 會(huì)繼續(xù)解析第二個(gè)字符,直到解析完所有后續(xù)字符或者遇到了一個(gè)非數(shù)字字符。例如, "1234blue" 會(huì)被轉(zhuǎn)換為 1234,因?yàn)?"blue" 會(huì)被完全忽略。類(lèi)似地, "22.5"會(huì)被轉(zhuǎn)換為 22,因?yàn)樾?shù)點(diǎn)并不是有效的數(shù)字字符。
0320、除了第一個(gè)小數(shù)點(diǎn)有效之外, parseFloat() 與 parseInt() 的第二個(gè)區(qū)別在于它始終都會(huì)忽略前導(dǎo)的零, parseFloat() 只解析十進(jìn)制值
0321、ECMAScript 中的字符串是不可變的,也就是說(shuō),字符串一旦創(chuàng)建,它們的值就不能改變。要改變某個(gè)變量保存的字符串,首先要銷(xiāo)毀原來(lái)的字符串,然后再用另一個(gè)包含新值的字符串填充該變量
0322、Object 的每個(gè)實(shí)例都具有下列屬性和方法:constructor :保存著用于創(chuàng)建當(dāng)前對(duì)象的函數(shù)。對(duì)于前面的例子而言,構(gòu)造函數(shù)(constructor)就是 Object(); hasOwnProperty(propertyName) :用于檢查給定的屬性在當(dāng)前對(duì)象實(shí)例中(而不是在實(shí)例的原型中)是否存在。其中,作為參數(shù)的屬性名( propertyName )必須以字符串形式指定(例如: o.hasOwnProperty("name") );isPrototypeOf(object) :用于檢查傳入的對(duì)象是否是傳入對(duì)象的原型;propertyIsEnumerable(propertyName) :用于檢查給定的屬性是否能夠使用 for-in 語(yǔ)句(本章后面將會(huì)討論)來(lái)枚舉。與 hasOwnProperty() 方法一樣,作為參數(shù)的屬性名必須以字符串形式指定;toLocaleString() :返回對(duì)象的字符串表示,該字符串與執(zhí)行環(huán)境的地區(qū)對(duì)應(yīng);toString() :返回對(duì)象的字符串表示;valueOf() :返回對(duì)象的字符串、數(shù)值或布爾值表示。通常與 toString() 方法的返回值相同
0323、在應(yīng)用于對(duì)象時(shí),相應(yīng)的操作符通常都會(huì)調(diào)用對(duì)象的 valueOf()和(或) toString() 方法,以便取得可以操作的值
0324、使用 while 循環(huán)做不到的,使用 for 循環(huán)同樣也做不到。也就是說(shuō), for 循環(huán)只是把與循環(huán)有關(guān)的代碼集中在了一個(gè)位置
0325、Safari 3 以前版本的 for-in 語(yǔ)句中存在一個(gè) bug,該 bug 會(huì)導(dǎo)致某些屬性被返回兩次。
0326、break 和 continue 語(yǔ)句用于在循環(huán)中精確地控制代碼的執(zhí)行。其中, break 語(yǔ)句會(huì)立即退出循環(huán),強(qiáng)制繼續(xù)執(zhí)行循環(huán)后面的語(yǔ)句。而 continue 語(yǔ)句雖然也是立即退出循環(huán),但退出循環(huán)后會(huì)從循環(huán)的頂部繼續(xù)執(zhí)行
0327、with 語(yǔ)句的作用是將代碼的作用域設(shè)置到一個(gè)特定的對(duì)象中。嚴(yán)格模式下不允許使用 with 語(yǔ)句,否則將視為語(yǔ)法錯(cuò)誤。由于大量使用 with 語(yǔ)句會(huì)導(dǎo)致性能下降,同時(shí)也會(huì)給調(diào)試代碼造成困難,因此在開(kāi)發(fā)大型應(yīng)用程序時(shí),不建議使用 with 語(yǔ)句
with(location){ var qs = search.substring(1); var hostName = hostname; var url = href; }
0328、通過(guò)為每個(gè) case 后面都添加一個(gè) break 語(yǔ)句,就可以避免同時(shí)執(zhí)行多個(gè) case代碼的情況。假如確實(shí)需要混合幾種情形,不要忘了在代碼中添加注釋?zhuān)f(shuō)明你是有意省略了 break 關(guān)鍵字。雖然 ECMAScript 中的 switch 語(yǔ)句借鑒自其他語(yǔ)言,但這個(gè)語(yǔ)句也有自己的特色。首先,可以在switch 語(yǔ)句中使用任何數(shù)據(jù)類(lèi)型(在很多其他語(yǔ)言中只能使用數(shù)值),無(wú)論是字符串,還是對(duì)象都沒(méi)有問(wèn)題。其次,每個(gè) case 的值不一定是常量,可以是變量,甚至是表達(dá)式
switch (i) { case 25: /* 合并兩種情形 */ case 35: alert("25 or 35"); break; case 45: alert("45"); break; default: alert("Other"); }
0329、switch 語(yǔ)句在比較值時(shí)使用的是全等操作符,因此不會(huì)發(fā)生類(lèi)型轉(zhuǎn)換(例如,字符串 "10" 不等于數(shù)值 10)
0330、函數(shù)會(huì)在執(zhí)行完 return 語(yǔ)句之后停止并立即退出。因此,位于 return 語(yǔ)句之后的任何代碼都永遠(yuǎn)不會(huì)執(zhí)行
0331、 return 語(yǔ)句也可以不帶有任何返回值。在這種情況下,函數(shù)在停止執(zhí)行后將返回 undefined值。這種用法一般用在需要提前停止函數(shù)執(zhí)行而又不需要返回值的情況下
0332、嚴(yán)格模式對(duì)函數(shù)有一些限制:不能把函數(shù)命名為 eval 或 arguments ;不能把參數(shù)命名為 eval 或 arguments ; 不能出現(xiàn)兩個(gè)命名參數(shù)同名的情況。如果發(fā)生以上情況,就會(huì)導(dǎo)致語(yǔ)法錯(cuò)誤,代碼無(wú)法執(zhí)行
0333、函數(shù)體內(nèi)可以通過(guò) arguments 對(duì)象來(lái)訪問(wèn)這個(gè)參數(shù)數(shù)組,從而獲取傳遞給函數(shù)的每一個(gè)參數(shù)。 arguments 對(duì)象只是與數(shù)組類(lèi)似(它并不是 Array 的實(shí)例),因?yàn)榭梢允褂梅嚼ㄌ?hào)語(yǔ)法訪問(wèn)它的每一個(gè)元素(即第一個(gè)元素是 arguments[0] ,第二個(gè)元素是 argumetns[1] ,以此類(lèi)推),使用 length 屬性來(lái)確定傳遞進(jìn)來(lái)多少個(gè)參數(shù)
0334、沒(méi)有傳遞值的命名參數(shù)將自動(dòng)被賦予 undefined 值
0335、嚴(yán)格模式對(duì)如何使用 arguments 對(duì)象做出了一些限制。把 arguments[1] 設(shè)置為 10 , num2 的值仍然還是 undefined 。其次,重寫(xiě)arguments 的值會(huì)導(dǎo)致語(yǔ)法錯(cuò)誤(代碼將不會(huì)執(zhí)行)
0336、ECMAScript 中的所有參數(shù)傳遞的都是值,不可能通過(guò)引用傳遞參數(shù)
0337、通過(guò)檢查傳入函數(shù)中參數(shù)的類(lèi)型和數(shù)量并作出不同的反應(yīng),可以模仿方法的重載
0338、 ECMAScript 中的基本數(shù)據(jù)類(lèi)型包括 Undefined 、 Null 、 Boolean 、 Number 和 String
0339、與其他語(yǔ)言不同,ECMScript 沒(méi)有為整數(shù)和浮點(diǎn)數(shù)值分別定義不同的數(shù)據(jù)類(lèi)型, Number 類(lèi)型可用于表示所有數(shù)值
0340、ECMAScript 中也有一種復(fù)雜的數(shù)據(jù)類(lèi)型,即 Object 類(lèi)型,該類(lèi)型是這門(mén)語(yǔ)言中所有對(duì)象的基礎(chǔ)類(lèi)型
0341、未指定返回值的函數(shù)返回的是一個(gè)特殊的 undefined 值
0342、 可以向 ECMAScript 函數(shù)傳遞任意數(shù)量的參數(shù),并且可以通過(guò) arguments 對(duì)象來(lái)訪問(wèn)這些參數(shù)
0343、當(dāng)復(fù)制保存著對(duì)象的某個(gè)變量時(shí),操作的是對(duì)象的引用。但在為對(duì)象添加屬性時(shí),操作的是實(shí)際的對(duì)象
第四章、變量、作用域和內(nèi)存問(wèn)題0401、 typeof 操作符是確定一個(gè)變量是字符串、數(shù)值、布爾值,還是 undefined 的最佳工具
0402、通常,我們并不是想知道某個(gè)值是對(duì)象,而是想知道它是什么類(lèi)型的對(duì)象。為此,ECMAScript提供了 instanceof 操作符
0403、函數(shù)參數(shù)也被當(dāng)作變量來(lái)對(duì)待,因此其訪問(wèn)規(guī)則與執(zhí)行環(huán)境中的其他變量相同
0404、在catch 語(yǔ)句中捕獲的錯(cuò)誤對(duì)象會(huì)被添加到執(zhí)行環(huán)境的變量對(duì)象,而不是 catch 語(yǔ)句的變量對(duì)象中。換句話(huà)說(shuō),即使是在 catch 塊的外部也可以訪問(wèn)到錯(cuò)誤對(duì)象
0405、變量查詢(xún)也不是沒(méi)有代價(jià)的。很明顯,訪問(wèn)局部變量要比訪問(wèn)全局變量更快,因?yàn)椴挥孟蛏纤阉髯饔糜蜴?。JavaScript 引擎在優(yōu)化標(biāo)識(shí)符查詢(xún)方面做得不錯(cuò),因此這個(gè)差別在將來(lái)恐怕就可以忽略不計(jì)了
0406、一旦數(shù)據(jù)不再有用,最好通過(guò)將其值設(shè)置為 null 來(lái)釋放其引用——這個(gè)做法叫做解除引用(dereferencing)
0407、基本類(lèi)型值在內(nèi)存中占據(jù)固定大小的空間,因此被保存在棧內(nèi)存中
0408、 從一個(gè)變量向另一個(gè)變量復(fù)制基本類(lèi)型的值,會(huì)創(chuàng)建這個(gè)值的一個(gè)副本
0409、引用類(lèi)型的值是對(duì)象,保存在堆內(nèi)存中
0410、包含引用類(lèi)型值的變量實(shí)際上包含的并不是對(duì)象本身,而是一個(gè)指向該對(duì)象的指針
0411、從一個(gè)變量向另一個(gè)變量復(fù)制引用類(lèi)型的值,復(fù)制的其實(shí)是指針,因此兩個(gè)變量最終都指向同一個(gè)對(duì)象
0412、確定一個(gè)值是哪種基本類(lèi)型可以使用 typeof 操作符,而確定一個(gè)值是哪種引用類(lèi)型可以使用instanceof 操作符
0413、 “標(biāo)記清除”是目前主流的垃圾收集算法,這種算法的思想是給當(dāng)前不使用的值加上標(biāo)記,然后再回收其內(nèi)存
0414、解除變量的引用不僅有助于消除循環(huán)引用現(xiàn)象,而且對(duì)垃圾收集也有好處。為了確保有效地回收內(nèi)存,應(yīng)該及時(shí)解除不再使用的全局對(duì)象、全局對(duì)象屬性以及循環(huán)引用變量的引用
0415、除非必須使用變量來(lái)訪問(wèn)屬性,否則我們建議使用點(diǎn)表示法
第五章、引用類(lèi)型0501、與對(duì)象一樣,在使用數(shù)組字面量表示法時(shí),也不會(huì)調(diào)用 Array 構(gòu)造函數(shù)(Firefox 3及更早版本除外)
0502、數(shù)組最多可以包含 4 294 967 295 個(gè)項(xiàng),這幾乎已經(jīng)能夠滿(mǎn)足任何編程需求了。如果想添加的項(xiàng)數(shù)超過(guò)這個(gè)上限值,就會(huì)發(fā)生異常。而創(chuàng)建一個(gè)初始大小與這個(gè)上限值接近的數(shù)組,則可能會(huì)導(dǎo)致運(yùn)行時(shí)間超長(zhǎng)的腳本錯(cuò)誤
0503、所有對(duì)象都具有 toLocaleString() 、 toString() 和 valueOf() 方法。其中,調(diào)用數(shù)組的 toString() 方法會(huì)返回由數(shù)組中每個(gè)值的字符串形式拼接而成的一個(gè)以逗號(hào)分隔的字符串。而調(diào)用 valueOf() 返回的還是數(shù)組。實(shí)際上,為了創(chuàng)建這個(gè)字符串會(huì)調(diào)用數(shù)組每一項(xiàng)的 toString() 方法
0504、 toLocaleString() 方法經(jīng)常也會(huì)返回與 toString() 和 valueOf() 方法相同的值,但也不總是如此
0505、如果數(shù)組中的某一項(xiàng)的值是 null 或者 undefined ,那么該值在 join() 、toLocaleString() 、 toString() 和 valueOf() 方法返回的結(jié)果中以空字符串表示
0506、push() 方法可以接收任意數(shù)量的參數(shù),把它們逐個(gè)添加到數(shù)組末尾,并返回修改后數(shù)組的長(zhǎng)度。而pop() 方法則從數(shù)組末尾移除最后一項(xiàng),減少數(shù)組的 length 值,然后返回移除的項(xiàng)
0507、棧數(shù)據(jù)結(jié)構(gòu)的訪問(wèn)規(guī)則是 LIFO(后進(jìn)先出),而隊(duì)列數(shù)據(jù)結(jié)構(gòu)的訪問(wèn)規(guī)則是 FIFO(First-In-First-Out,先進(jìn)先出)
0508、結(jié)合使用 shift() 和 push() 方法,可以像使用隊(duì)列一樣使用數(shù)組
0509、同時(shí)使用 unshift() 和 pop() 方法,可以從相反的方向來(lái)模擬隊(duì)列,即在數(shù)組的前端添加項(xiàng),從數(shù)組末端移除項(xiàng)
0510、alert([0, 1, 5, 10, 15].sort());//0,1,10,15,5??梢?jiàn),即使例子中值的順序沒(méi)有問(wèn)題,但 sort() 方法也會(huì)根據(jù)測(cè)試字符串的結(jié)果改變?cè)瓉?lái)的順序。因?yàn)閿?shù)值 5 雖然小于 10,但在進(jìn)行字符串比較時(shí), "10" 則位于 "5" 的前面,于是數(shù)組的順序就被修改了。不用說(shuō),這種排序方式在很多情況下都不是最佳方案。比較函數(shù)接收兩個(gè)參數(shù),如果第一個(gè)參數(shù)應(yīng)該位于第二個(gè)之前則返回一個(gè)負(fù)數(shù),如果兩個(gè)參數(shù)相等則返回 0,如果第一個(gè)參數(shù)應(yīng)該位于第二個(gè)之后則返回一個(gè)正數(shù)
0511、由于比較函數(shù)通過(guò)返回一個(gè)小于零、等于零或大于零的值來(lái)影響排序結(jié)果,因此減法操作就可以適當(dāng)?shù)靥幚硭羞@些情況
0512、 concat() 方法會(huì)先創(chuàng)建當(dāng)前數(shù)組一個(gè)副本,然后將接收到的參數(shù)添加到這個(gè)副本的末尾,最后返回新構(gòu)建的數(shù)組。在沒(méi)有給 concat() 方法傳遞參數(shù)的情況下,它只是復(fù)制當(dāng)前數(shù)組并返回副本。如果傳遞給 concat() 方法的是一或多個(gè)數(shù)組,則該方法會(huì)將這些數(shù)組中的每一項(xiàng)都添加到結(jié)果數(shù)組中。如果傳遞的值不是數(shù)組,這些值就會(huì)被簡(jiǎn)單地添加到結(jié)果數(shù)組的末尾
0513、slice() 方法可以接受一或兩個(gè)參數(shù),即要返回項(xiàng)的起始和結(jié)束位置。在只有一個(gè)參數(shù)的情況下, slice() 方法返回從該參數(shù)指定位置開(kāi)始到當(dāng)前數(shù)組末尾的所有項(xiàng)。如果有兩個(gè)參數(shù),該方法返回起始和結(jié)束位置之間的項(xiàng)——但不包括結(jié)束位置的項(xiàng)。注意, slice() 方法不會(huì)影響原始數(shù)組
0514、如果 slice() 方法的參數(shù)中有一個(gè)負(fù)數(shù),則用數(shù)組長(zhǎng)度加上該數(shù)來(lái)確定相應(yīng)的位置。例如,在一個(gè)包含5項(xiàng)的數(shù)組上調(diào)用 slice(-2,-1) 與調(diào)用 slice(3,4) 得到的結(jié)果相同。如果結(jié)束位置小于起始位置,則返回空數(shù)組
0515、splice() 方法可以刪除任意數(shù)量的項(xiàng),只需指定2個(gè)參數(shù):要?jiǎng)h除的第一項(xiàng)的位置和要?jiǎng)h除的項(xiàng)數(shù);可以向指定位置插入任意數(shù)量的項(xiàng),只需提供 3 個(gè)參數(shù):起始位置、0(要?jiǎng)h除的項(xiàng)數(shù))和要插入的項(xiàng)。如果要插入多個(gè)項(xiàng),可以再傳入第四、第五,以至任意多個(gè)項(xiàng);可以向指定位置插入任意數(shù)量的項(xiàng),且同時(shí)刪除任意數(shù)量的項(xiàng),只需指定3個(gè)參數(shù):起始位置、要?jiǎng)h除的項(xiàng)數(shù)和要插入的任意數(shù)量的項(xiàng)。插入的項(xiàng)數(shù)不必與刪除的項(xiàng)數(shù)相等
0516、splice() 方法始終都會(huì)返回一個(gè)數(shù)組,該數(shù)組中包含從原始數(shù)組中刪除的項(xiàng)(如果沒(méi)有刪除任何項(xiàng),則返回一個(gè)空數(shù)組)
0517、 indexOf() 和 lastIndexOf()。這兩個(gè)方法都接收兩個(gè)參數(shù):要查找的項(xiàng)和(可選的)表示查找起點(diǎn)位置的索引。其中, indexOf() 方法從數(shù)組的開(kāi)頭(位置0)開(kāi)始向后查找,lastIndexOf()方法則從數(shù)組的末尾開(kāi)始向前查找。這兩個(gè)方法都返回要查找的項(xiàng)在數(shù)組中的位置,或者在沒(méi)找到的情況下返回-1。支持它們的瀏覽器包括 IE9+、Firefox 2+、Safari3+、Opera 9.5+和 Chrome
0518、ECMAScript 5 為數(shù)組定義了5個(gè)迭代方法,這些方法中的函數(shù)會(huì)接收三個(gè)參數(shù):數(shù)組項(xiàng)的值、該項(xiàng)在數(shù)組中的位置和數(shù)組對(duì)象本身。every() :對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),如果該函數(shù)對(duì)每一項(xiàng)都返回true,則返回true;filter():對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),返回該函數(shù)會(huì)返回true的項(xiàng)組成的數(shù)組;forEach():對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù)。這個(gè)方法沒(méi)有返回值;map() :對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),返回每次函數(shù)調(diào)用的結(jié)果組成的數(shù)組;some():對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),如果該函數(shù)對(duì)任一項(xiàng)返回 true ,則返回 true。以上方法都不會(huì)修改數(shù)組中的包含的值
0519、這些數(shù)組方法通過(guò)執(zhí)行不同的操作,可以大大方便處理數(shù)組的任務(wù)。支持這些迭代方法的瀏覽器有IE9+、Firefox2+、Safari 3+、Opera 9.5+和 Chrome
0520、 reduce() 和 reduceRight()。這兩個(gè)方法都會(huì)迭代數(shù)組的所有項(xiàng),然后構(gòu)建一個(gè)最終返回的值。這兩個(gè)方法都接收兩個(gè)參數(shù):一個(gè)在每一項(xiàng)上調(diào)用的函數(shù)和(可選的)作為歸并基礎(chǔ)的初始值。傳給reduce()和reduceRight()的函數(shù)接收4個(gè)參數(shù):前一個(gè)值、當(dāng)前值、項(xiàng)的索引和數(shù)組對(duì)象。這個(gè)函數(shù)返回的任何值都會(huì)作為第一個(gè)參數(shù)自動(dòng)傳給下一項(xiàng)。第一次迭代發(fā)生在數(shù)組的第二項(xiàng)上,因此第一個(gè)參數(shù)是數(shù)組的第一項(xiàng),第二個(gè)參數(shù)就是數(shù)組的第二項(xiàng)。使用reduce()方法可以執(zhí)行求數(shù)組中所有值之和的操作
0521、使用 reduce() 還是 reduceRight() ,主要取決于要從哪頭開(kāi)始遍歷數(shù)組。除此之外,它們完全相同
0522、在調(diào)用 Date 構(gòu)造函數(shù)而不傳遞參數(shù)的情況下,新創(chuàng)建的對(duì)象自動(dòng)獲得當(dāng)前日期和時(shí)間
0523、 Date.parse() 方法接收一個(gè)表示日期的字符串參數(shù),然后嘗試根據(jù)這個(gè)字符串返回相應(yīng)日期的毫秒數(shù)。ECMA-262沒(méi)有定義Date.parse() 應(yīng)該支持哪種日期格式,因此這個(gè)方法的行為因?qū)崿F(xiàn)而異,而且通常是因地區(qū)而異
0524、如果傳入 Date.parse()方法的字符串不能表示日期,那么它會(huì)返回NaN。實(shí)際上,如果直接將表示日期的字符串傳遞給 Date 構(gòu)造函數(shù),也會(huì)在后臺(tái)調(diào)用 Date.parse() 。換句話(huà)說(shuō),下面的代碼與前面的例子是等價(jià)的:var someDate = new Date("May 25, 2004");
0525、Date.UTC() 方法同樣也返回表示日期的毫秒數(shù),但它與Date.parse()在構(gòu)建值時(shí)使用不同的信息。Date.UTC()的參數(shù)分別是年份、基于 0 的月份(一月是0,二月是1,以此類(lèi)推)、月中的哪一天(1到31)、小時(shí)數(shù)(0到23)、分鐘、秒以及毫秒數(shù)。在這些參數(shù)中,只有前兩個(gè)參數(shù)(年和月)是必需的。如果沒(méi)有提供月中的天數(shù),則假設(shè)天數(shù)為1;如果省略其他參數(shù),則統(tǒng)統(tǒng)假設(shè)為 0。
0526、ECMAScript 5 添加了 Data.now() 方法,返回表示調(diào)用這個(gè)方法時(shí)的日期和時(shí)間的毫秒數(shù)
0527、支持 Data.now() 方法的瀏覽器包括IE9+、Firefox3+、Safari3+、Opera10.5和Chrome。在不支持它的瀏覽器中,使用+操作符把 Data 對(duì)象轉(zhuǎn)換成字符串,也可以達(dá)到同樣的目的
0528、正則表達(dá)式。字面量聲明和構(gòu)造函數(shù)聲明的區(qū)別,字面量始終會(huì)共享一個(gè)RegExp實(shí)例,而使用構(gòu)造函數(shù)創(chuàng)建的每一個(gè)新RegExp實(shí)例都是一個(gè)新實(shí)例
0529、RegExp 對(duì)象的主要方法是 exec() ,該方法是專(zhuān)門(mén)為捕獲組而設(shè)計(jì)的。 exec() 接受一個(gè)參數(shù),即要應(yīng)用模式的字符串,然后返回包含第一個(gè)匹配項(xiàng)信息的數(shù)組;或者在沒(méi)有匹配項(xiàng)的情況下返回 null 。返回的數(shù)組雖然是 Array 的實(shí)例,但包含兩個(gè)額外的屬性: index 和 input 。其中, index 表示匹配項(xiàng)在字符串中的位置,而 input 表示應(yīng)用正則表達(dá)式的字符串。在數(shù)組中,第一項(xiàng)是與整個(gè)模式匹配的字符串,其他項(xiàng)是與模式中的捕獲組匹配的字符串(如果模式中沒(méi)有捕獲組,則該數(shù)組只包含一項(xiàng))
0530、正則表達(dá)式的第二個(gè)方法是 test() ,它接受一個(gè)字符串參數(shù)。在模式與該參數(shù)匹配的情況下返回true ;否則,返回 false 。在只想知道目標(biāo)字符串與某個(gè)模式是否匹配,但不需要知道其文本內(nèi)容的情況下,使用這個(gè)方法非常方便
0531、正則表達(dá)式的 valueOf() 方法返回正則表達(dá)式本身。
0532、即使 test() 方法只返回一個(gè)布爾值,但RegExp 構(gòu)造函數(shù)的屬性$1和$2也會(huì)被匹配相應(yīng)捕獲組的字符串自動(dòng)填充
0533、每個(gè)函數(shù)都是Function類(lèi)型的實(shí)例,而且都與其他引用類(lèi)型一樣具有屬性和方法。由于函數(shù)是對(duì)象,因此函數(shù)名實(shí)際上也是一個(gè)指向函數(shù)對(duì)象的指針,不會(huì)與某個(gè)函數(shù)綁定
0534、Function構(gòu)造函數(shù)可以接收任意數(shù)量的參數(shù),但最后一個(gè)參數(shù)始終都被看成是函數(shù)體,而前面的參數(shù)則枚舉出了新函數(shù)的參數(shù)。但是,我們不推薦讀者使用這種方法定義函數(shù),因?yàn)檫@種語(yǔ)法會(huì)導(dǎo)致解析兩次代碼(第一次是解析常規(guī) ECMAScript代碼,第二次是解析傳入構(gòu)造函數(shù)中的字符串),從而影響性能
0535、函數(shù)聲明式與函數(shù)表達(dá)式的區(qū)別。解析器在向執(zhí)行環(huán)境中加載數(shù)據(jù)時(shí),對(duì)函數(shù)聲明和函數(shù)表達(dá)式并非一視同仁。解析器會(huì)率先讀取函數(shù)聲明,并使其在執(zhí)行任何代碼之前可用(可以訪問(wèn));至于函數(shù)表達(dá)式,則必須等到解析器執(zhí)行到它所在的代碼行,才會(huì)真正被解釋執(zhí)行
0536、因?yàn)?ECMAScript中的函數(shù)名本身就是變量,所以函數(shù)也可以作為值來(lái)使用。也就是說(shuō),不僅可以像傳遞參數(shù)一樣把一個(gè)函數(shù)傳遞給另一個(gè)函數(shù),而且可以將一個(gè)函數(shù)作為另一個(gè)函數(shù)的結(jié)果返回
0537、arguments是一個(gè)類(lèi)數(shù)組對(duì)象,包含著傳入函數(shù)中的所有參數(shù)。雖然 arguments 的主要用途是保存函數(shù)參數(shù),但這個(gè)對(duì)象還有一個(gè)名叫 callee 的屬性,該屬性是一個(gè)指針,指向擁有這個(gè) arguments 對(duì)象的函數(shù)
0538、this引用的是函數(shù)據(jù)以執(zhí)行的環(huán)境對(duì)象——或者也可以說(shuō)是this值(當(dāng)在網(wǎng)頁(yè)的全局作用域中調(diào)用函數(shù)時(shí),this對(duì)象引用的就是window)
0539、函數(shù)的名字僅僅是一個(gè)包含指針的變量而已。因此,即使是在不同的環(huán)境中執(zhí)行,全局的 sayColor() 函數(shù)與 o.sayColor() 指向的仍然是同一個(gè)函數(shù)
0540、ECMAScript5也規(guī)范化了另一個(gè)函數(shù)對(duì)象的屬性: caller 。除了Opera的早期版本不支持,其他瀏覽器都支持這個(gè) ECMAScript3并沒(méi)有定義的屬性。這個(gè)屬性中保存著調(diào)用當(dāng)前函數(shù)的函數(shù)的引用,如果是在全局作用域中調(diào)用當(dāng)前函數(shù),它的值為null。為了實(shí)現(xiàn)更松散的耦合,也可以通過(guò) arguments.callee.caller來(lái)訪問(wèn)相同的信息
0541、IE、Firefox、Chrome和Safari的所有版本以及 Opera 9.6 都支持 caller 屬性
0542、當(dāng)函數(shù)在嚴(yán)格模式下運(yùn)行時(shí),訪問(wèn)arguments.callee 會(huì)導(dǎo)致錯(cuò)誤。ECMAScript5還定義了arguments.caller 屬性,但在嚴(yán)格模式下訪問(wèn)它也會(huì)導(dǎo)致錯(cuò)誤,而在非嚴(yán)格模式下這個(gè)屬性始終是undefined。定義這個(gè)屬性是為了分清 arguments.caller和函數(shù)的caller屬性。以上變化都是為了加強(qiáng)這門(mén)語(yǔ)言的安全性,這樣第三方代碼就不能在相同的環(huán)境里窺視其他代碼了
0543、ECMAScript中的函數(shù)是對(duì)象,因此函數(shù)也有屬性和方法。每個(gè)函數(shù)都包含兩個(gè)屬性: length和prototype 。其中,length屬性表示函數(shù)希望接收的命名參數(shù)的個(gè)數(shù)
0544、在ECMAScript5中,prototype屬性是不可枚舉的,因此使用 for-in 無(wú)法發(fā)現(xiàn)
0545、每個(gè)函數(shù)都包含兩個(gè)非繼承而來(lái)的方法:apply() 和 call() 。這兩個(gè)方法的用途都是在特定的作用域中調(diào)用函數(shù),實(shí)際上等于設(shè)置函數(shù)體內(nèi)this對(duì)象的值。首先, apply() 方法接收兩個(gè)參數(shù):一個(gè)是在其中運(yùn)行函數(shù)的作用域,另一個(gè)是參數(shù)數(shù)組。其中,第二個(gè)參數(shù)可以是Array 的實(shí)例,也可以是arguments 對(duì)象
0546、在嚴(yán)格模式下,未指定環(huán)境對(duì)象而調(diào)用函數(shù),則 this 值不會(huì)轉(zhuǎn)型為 window 。除非明確把函數(shù)添加到某個(gè)對(duì)象或者調(diào)用 apply() 或 call() ,否則 this 值將是undefined
0547、call()方法與apply()方法的作用相同,它們的區(qū)別僅在于接收參數(shù)的方式不同。對(duì)于call()方法而言,第一個(gè)參數(shù)是 this值沒(méi)有變化,變化的是其余參數(shù)都直接傳遞給函數(shù)。換句話(huà)說(shuō),在使用call()方法時(shí),傳遞給函數(shù)的參數(shù)必須逐個(gè)列舉出來(lái)
0548、事實(shí)上,傳遞參數(shù)并非 apply() 和 call() 真正的用武之地;它們真正強(qiáng)大的地方是能夠擴(kuò)充函數(shù)賴(lài)以運(yùn)行的作用域
0549、使用 call()(或apply())來(lái)擴(kuò)充作用域的最大好處,就是對(duì)象不需要與方法有任何耦合關(guān)系
0550、ECMAScript 5 還定義了一個(gè)方法: bind() 。這個(gè)方法會(huì)創(chuàng)建一個(gè)函數(shù)的實(shí)例,其 this 值會(huì)被綁定到傳給 bind() 函數(shù)的值。支持 bind() 方法的瀏覽器有 IE9+、Firefox 4+、Safari 5.1+、Opera 12+和 Chrome
0551、為了便于操作基本類(lèi)型值,ECMAScript還提供了 3 個(gè)特殊的引用類(lèi)型:Boolean、Number和String。這些類(lèi)型與本章介紹的其他引用類(lèi)型相似,但同時(shí)也具有與各自的基本類(lèi)型相應(yīng)的特殊行為。實(shí)際上,每當(dāng)讀取一個(gè)基本類(lèi)型值的時(shí)候,后臺(tái)就會(huì)創(chuàng)建一個(gè)對(duì)應(yīng)的基本包裝類(lèi)型的對(duì)象,從而讓我們能夠調(diào)用一些方法來(lái)操作這些數(shù)據(jù)
0552、引用類(lèi)型與基本包裝類(lèi)型的主要區(qū)別就是對(duì)象的生存期。使用 new操作符創(chuàng)建的引用類(lèi)型的實(shí)例,在執(zhí)行流離開(kāi)當(dāng)前作用域之前都一直保存在內(nèi)存中。而自動(dòng)創(chuàng)建的基本包裝類(lèi)型的對(duì)象,則只存在于一行代碼的執(zhí)行瞬間,然后立即被銷(xiāo)毀。這意味著我們不能在運(yùn)行時(shí)為基本類(lèi)型值添加屬性和方法
0553、Object構(gòu)造函數(shù)也會(huì)像工廠方法一樣,根據(jù)傳入值的類(lèi)型返回相應(yīng)基本包裝類(lèi)型的實(shí)例。var obj = new Object("some text"); alert(obj instanceof String); //true
0554、使用new調(diào)用基本包裝類(lèi)型的構(gòu)造函數(shù),與直接調(diào)用同名的轉(zhuǎn)型函數(shù)是不一樣的
0555、 toFixed()方法會(huì)按照指定的小數(shù)位返回?cái)?shù)值的字符串表示。如果數(shù)值本身包含的小數(shù)位比指定的還多,那么接近指定的最大小數(shù)位的值就會(huì)舍入??梢岳胷ound配合toFixed加爵該方法的在ie瀏覽器上的兼容問(wèn)題
0556、對(duì)于一個(gè)數(shù)值來(lái)說(shuō),toPrecision()方法可能會(huì)返回固定大小(fixed)格式,也可能返回指數(shù)(exponential)格式;具體規(guī)則是看哪種格式最合適。這個(gè)方法接收一個(gè)參數(shù),即表示數(shù)值的所有數(shù)字的位數(shù)(不包括指數(shù)部分)。實(shí)際上,toPrecision()會(huì)根據(jù)要處理的數(shù)值決定到底是調(diào)用 toFixed() 還是調(diào)用 toExponential()
0557、在使用typeof操作符測(cè)試基本類(lèi)型數(shù)值時(shí),始終會(huì)返回 "number" ,而在測(cè)試 Number 對(duì)象時(shí),則會(huì)返回 "object" 。類(lèi)似地,Number對(duì)象是Number類(lèi)型的實(shí)例,而基本類(lèi)型的數(shù)值則不是
0558、兩個(gè)用于訪問(wèn)字符串中特定字符的方法是:charAt() 和 charCodeAt()。這兩個(gè)方法都接收一個(gè)參數(shù),即基于 0 的字符位置。其中,charAt()方法以單字符字符串的形式返回給定位置的那個(gè)字符(ECMAScript中沒(méi)有字符類(lèi)型)
0559、ECMAScript5還定義了另一個(gè)訪問(wèn)個(gè)別字符的方法。在支持此方法的瀏覽器中,可以使用方括號(hào)加數(shù)字索引來(lái)訪問(wèn)字符串中的特定字符。使用方括號(hào)表示法訪問(wèn)個(gè)別字符的語(yǔ)法得到了 IE8 及 Firefox、Safari、Chrome 和 Opera 所有版本的支持。如果是在IE7及更早版本中使用這種語(yǔ)法,會(huì)返回undefined值(盡管根本不是特殊的undefined 值)
0560、ECMAScript還提供了三個(gè)基于子字符串創(chuàng)建新字符串的方法: slice() 、 substr() 和 substring() 。這三個(gè)方法都會(huì)返回被操作字符串的一個(gè)子字符串,而且也都接受一或兩個(gè)參數(shù)。第一個(gè)參數(shù)指定子字符串的開(kāi)始位置,第二個(gè)參數(shù)(在指定的情況下)表示子字符串到哪里結(jié)束。具體來(lái)說(shuō), slice() 和substring() 的第二個(gè)參數(shù)指定的是子字符串最后一個(gè)字符后面的位置。而 substr() 的第二個(gè)參數(shù)指定的則是返回的字符個(gè)數(shù)。如果沒(méi)有給這些方法傳遞第二個(gè)參數(shù),則將字符串的長(zhǎng)度作為結(jié)束位置。與concat() 方法一樣, slice() 、 substr() 和 substring() 也不會(huì)修改字符串本身的值——它們只是返回一個(gè)基本類(lèi)型的字符串值,對(duì)原始字符串沒(méi)有任何影響。在傳遞給這些方法的參數(shù)是負(fù)值的情況下,它們的行為就不盡相同了。其中, slice() 方法會(huì)將傳入的負(fù)值與字符串的長(zhǎng)度相加, substr() 方法將負(fù)的第一個(gè)參數(shù)加上字符串的長(zhǎng)度,而將負(fù)的第二個(gè)參數(shù)轉(zhuǎn)換為 0。最后, substring() 方法會(huì)把所有負(fù)值參數(shù)都轉(zhuǎn)換為 0
0561、IE 的 JavaScript 實(shí)現(xiàn)在處理向 substr() 方法傳遞負(fù)值的情況時(shí)存在問(wèn)題,它會(huì)返回原始的字符串。IE9 修復(fù)了這個(gè)問(wèn)題
0562、有兩個(gè)可以從字符串中查找子字符串的方法: indexOf() 和 lastIndexOf() 。這兩個(gè)方法都是從一個(gè)字符串中搜索給定的子字符串,然后返子字符串的位置(如果沒(méi)有找到該子字符串,則返回 -1 )。這兩個(gè)方法的區(qū)別在于: indexOf() 方法從字符串的開(kāi)頭向后搜索子字符串,而 lastIndexOf() 方法是從字符串的末尾向前搜索子字符串。這兩個(gè)方法都可以接收可選的第二個(gè)參數(shù),表示從字符串中的哪個(gè)位置開(kāi)始搜索
0563、ECMAScript 5 為所有字符串定義了 trim() 方法。這個(gè)方法會(huì)創(chuàng)建一個(gè)字符串的副本,刪除前置及后綴的所有空格,然后返回結(jié)果。由于 trim() 返回的是字符串的副本,所以原始字符串中的前置及后綴空格會(huì)保持不變。支持這個(gè)方法的瀏覽器有 IE9+、Firefox 3.5+、Safari 5+、Opera 10.5+和 Chrome。此外,F(xiàn)irefox 3.5+、Safari 5+和 Chrome 8+還支持非標(biāo)準(zhǔn)的 trimLeft() 和 trimRight() 方法,分別用于刪除字符串開(kāi)頭和末尾的空格
0564、接下來(lái)我們要介紹的是一組與大小寫(xiě)轉(zhuǎn)換有關(guān)的方法。ECMAScript中涉及字符串大小寫(xiě)轉(zhuǎn)換的方法有 4 個(gè):toLowerCase()、toLocaleLowerCase()、toUpperCase()和 toLocaleUpperCase() 。其中, toLowerCase() 和 toUpperCase() 是兩個(gè)經(jīng)典的方法,借鑒自 java.lang.String 中的同名方法。而 toLocaleLowerCase() 和 toLocaleUpperCase() 方法則是針對(duì)特定地區(qū)的實(shí)現(xiàn)。一般來(lái)說(shuō),在不知道自己的代碼將在哪種語(yǔ)言環(huán)境中運(yùn)行的情況下,還是使用針對(duì)地區(qū)的方法更穩(wěn)妥一些
0565、String 類(lèi)型定義了幾個(gè)用于在字符串中匹配模式的方法。第一個(gè)方法就是 match() ,在字符串上調(diào)用這個(gè)方法,本質(zhì)上與調(diào)用 RegExp 的 exec() 方法相同。 match() 方法只接受一個(gè)參數(shù),要么是一個(gè)正則表達(dá)式,要么是一個(gè) RegExp 對(duì)象
0566、另一個(gè)用于查找模式的方法是 search() 。這個(gè)方法的唯一參數(shù)與 match() 方法的參數(shù)相同:由字符串或 RegExp 對(duì)象指定的一個(gè)正則表達(dá)式。 search() 方法返回字符串中第一個(gè)匹配項(xiàng)的索引;如果沒(méi)有找到匹配項(xiàng),則返回 -1 。而且, search() 方法始終是從字符串開(kāi)頭向后查找模式
0567、ECMAScript 提供了 replace() 方法。這個(gè)方法接受兩個(gè)參數(shù):第一個(gè)參數(shù)可以是一個(gè) RegExp 對(duì)象或者一個(gè)字符串(這個(gè)字符串不會(huì)被轉(zhuǎn)換成正則表達(dá)式),第二個(gè)參數(shù)可以是一個(gè)字符串或者一個(gè)函數(shù)。如果第一個(gè)參數(shù)是字符串,那么只會(huì)替換第一個(gè)子字符串。要想替換所有子字符串,唯一的辦法就是提供一個(gè)正則表達(dá)式,而且要指定全局( g )標(biāo)志
0568、replace() 方法的第二個(gè)參數(shù)也可以是一個(gè)函數(shù)。在只有一個(gè)匹配項(xiàng)(即與模式匹配的字符串)的情況下,會(huì)向這個(gè)函數(shù)傳遞 3 個(gè)參數(shù):模式的匹配項(xiàng)、模式匹配項(xiàng)在字符串中的位置和原始字符串。在正則表達(dá)式中定義了多個(gè)捕獲組的情況下,傳遞給函數(shù)的參數(shù)依次是模式的匹配項(xiàng)、第一個(gè)捕獲組的匹配項(xiàng)、第二個(gè)捕獲組的匹配項(xiàng)……,但最后兩個(gè)參數(shù)仍然分別是模式的匹配項(xiàng)在字符串中的位置和原始字符串。這個(gè)函數(shù)應(yīng)該返回一個(gè)字符串,表示應(yīng)該被替換的匹配項(xiàng)使用函數(shù)作為 replace() 方法的第二個(gè)參數(shù)可以實(shí)現(xiàn)更加精細(xì)的替換操作
0569、最后一個(gè)與模式匹配有關(guān)的方法是 split() ,這個(gè)方法可以基于指定的分隔符將一個(gè)字符串分割成多個(gè)子字符串,并將結(jié)果放在一個(gè)數(shù)組中。分隔符可以是字符串,也可以是一個(gè) RegExp 對(duì)象(這個(gè)方法不會(huì)將字符串看成正則表達(dá)式)。 split() 方法可以接受可選的第二個(gè)參數(shù),用于指定數(shù)組的大小,以便確保返回的數(shù)組不會(huì)超過(guò)既定大小。對(duì) split() 中正則表達(dá)式的支持因?yàn)g覽器而異。盡管對(duì)于簡(jiǎn)單的模式?jīng)]有什么差別,但對(duì)于未發(fā)現(xiàn)匹配項(xiàng)以及帶有捕獲組的模式,匹配的行為就不大相同了
0570、與操作字符串有關(guān)的最后一個(gè)方法是 localeCompare() ,這個(gè)方法比較兩個(gè)字符串,并返回下列值中的一個(gè): 如果字符串在字母表中應(yīng)該排在字符串參數(shù)之前,則返回一個(gè)負(fù)數(shù)(大多數(shù)情況下是 -1 ,具體的值要視實(shí)現(xiàn)而定); 如果字符串等于字符串參數(shù),則返回 0 ;如果字符串在字母表中應(yīng)該排在字符串參數(shù)之后,則返回一個(gè)正數(shù)(大多數(shù)情況下是 1 ,具體的值同樣要視實(shí)現(xiàn)而定)。localeCompare() 方法比較與眾不同的地方,就是實(shí)現(xiàn)所支持的地區(qū)(國(guó)家和語(yǔ)言)決定了這個(gè)方法的行為
0571、另外, String 構(gòu)造函數(shù)本身還有一個(gè)靜態(tài)方法: fromCharCode() 。這個(gè)方法的任務(wù)是接收一或多個(gè)字符編碼,然后將它們轉(zhuǎn)換成一個(gè)字符串。從本質(zhì)上來(lái)看,這個(gè)方法與實(shí)例方法 charCodeAt()執(zhí)行的是相反的操作
0572、 encodeURI() 主要用于整個(gè) URI(例如,http://www.wrox.com/illegal value.htm),而 encode-URIComponent() 主要用于對(duì) URI 中的某一段(例如前面 URI 中的 illegal value.htm )進(jìn)行編碼。它們的主要區(qū)別在于, encodeURI() 不會(huì)對(duì)本身屬于 URI 的特殊字符進(jìn)行編碼,例如冒號(hào)、正斜杠、問(wèn)號(hào)和井字號(hào);而 encodeURIComponent() 則會(huì)對(duì)它發(fā)現(xiàn)的任何非標(biāo)準(zhǔn)字符進(jìn)行編碼
0573、一 般 來(lái) 說(shuō) , 我 們 使 用 encodeURIComponent() 方 法 的 時(shí) 候 要 比 使 用encodeURI() 更多,因?yàn)樵趯?shí)踐中更常見(jiàn)的是對(duì)查詢(xún)字符串參數(shù)而不是對(duì)基礎(chǔ) URI進(jìn)行編碼。
0574、與 encodeURI() 和 encodeURIComponent() 方法對(duì)應(yīng)的兩個(gè)方法分別是 decodeURI() 和decodeURIComponent()
0575、現(xiàn)在,我們介紹最后一個(gè)——大概也是整個(gè) ECMAScript語(yǔ)言中最強(qiáng)大的一個(gè)方法: eval() 。 eval()方法就像是一個(gè)完整的 ECMAScript 解析器,它只接受一個(gè)參數(shù),即要執(zhí)行的 ECMAScript (或 JavaScript)字符串
0576、能夠解釋代碼字符串的能力非常強(qiáng)大,但也非常危險(xiǎn)。因此在使用 eval() 時(shí)必須極為謹(jǐn)慎,特別是在用它執(zhí)行用戶(hù)輸入數(shù)據(jù)的情況下。否則,可能會(huì)有惡意用戶(hù)輸入威脅你的站點(diǎn)或應(yīng)用程序安全的代碼(即所謂的代碼注入)
0577、其中, min() 和 max() 方法用于確定一組數(shù)值中的最小值和最大值。這兩個(gè)方法都可以接收任意多個(gè)數(shù)值參數(shù)
0578、要找到數(shù)組中的最大或最小值,可以像下面這樣使用 apply() 方法。Math.max.apply(Math,[1,2,4,65,8,4)//65
0579、下面來(lái)介紹將小數(shù)值舍入為整數(shù)的幾個(gè)方法: Math.ceil() 、 Math.floor() 和 Math.round()
0580、Math.random() 方法返回大于等于 0 小于 1 的一個(gè)隨機(jī)數(shù)
0581、 引用類(lèi)型與傳統(tǒng)面向?qū)ο蟪绦蛟O(shè)計(jì)中的類(lèi)相似,但實(shí)現(xiàn)不同
0582、Object 是一個(gè)基礎(chǔ)類(lèi)型,其他所有類(lèi)型都從 Object 繼承了基本的行為
0583、Array 類(lèi)型是一組值的有序列表,同時(shí)還提供了操作和轉(zhuǎn)換這些值的功能
0584、Date 類(lèi)型提供了有關(guān)日期和時(shí)間的信息,包括當(dāng)前日期和時(shí)間以及相關(guān)的計(jì)算功能
0585、RegExp 類(lèi)型是 ECMAScript 支持正則表達(dá)式的一個(gè)接口,提供了最基本的和一些高級(jí)的正則表達(dá)式功能
0586、函數(shù)實(shí)際上是 Function 類(lèi)型的實(shí)例,因此函數(shù)也是對(duì)象;而這一點(diǎn)正是 JavaScript 最有特色的地方。由于函數(shù)是對(duì)象,所以函數(shù)也擁有方法,可以用來(lái)增強(qiáng)其行為
0587、因?yàn)橛辛嘶景b類(lèi)型,所以 JavaScript 中的基本類(lèi)型值可以被當(dāng)作對(duì)象來(lái)訪問(wèn)。三種基本包裝類(lèi)型分別是: Boolean 、 Number 和 String 。以下是它們共同的特征
0588、在所有代碼執(zhí)行之前,作用域中就已經(jīng)存在兩個(gè)內(nèi)置對(duì)象: Global 和 Math 。在大多數(shù) ECMAScript實(shí)現(xiàn)中都不能直接訪問(wèn) Global 對(duì)象;不過(guò),Web 瀏覽器實(shí)現(xiàn)了承擔(dān)該角色的 window 對(duì)象。全局變量和函數(shù)都是 Global 對(duì)象的屬性。 Math 對(duì)象提供了很多屬性和方法,用于輔助完成復(fù)雜的數(shù)學(xué)計(jì)算任務(wù)
第六章、面向?qū)ο蟮某绦蛟O(shè)計(jì)0601、ECMAScript中有兩種屬性:數(shù)據(jù)屬性和訪問(wèn)器屬性。數(shù)據(jù)屬性包含一個(gè)數(shù)據(jù)值的位置。在這個(gè)位置可以讀取和寫(xiě)入值。數(shù)據(jù)屬性有4個(gè)描述其行為的特性。對(duì)于像前面例子中那樣直接在對(duì)象上定義的屬性,它們的[[Configurable]] 、[[Enumerable]]和[[Writable]]特性都被設(shè)置為 true ,而[[Value]]特性被設(shè)置為指定的值。要修改屬性默認(rèn)的特性,必須使用ECMAScript5的Object.defineProperty()方法。這個(gè)方法接收三個(gè)參數(shù):屬性所在的對(duì)象、屬性的名字和一個(gè)描述符對(duì)象。其中,描述符(descriptor)對(duì)象的屬性必須是:configurable、enumerable 、 writable和value。設(shè)置其中的一或多個(gè)值,可以修改對(duì)應(yīng)的特性值。可以多次調(diào)用Object.defineProperty() 方法修改同一個(gè)屬性,但在把configurable特性設(shè)置為 false 之后就會(huì)有限制了。在調(diào)用Object.defineProperty() 方法時(shí),如果不指定,configurable、enumerable 和writable特性的默認(rèn)值都是false。多數(shù)情況下,可能都沒(méi)有必要利用Object.defineProperty()方法提供的這些高級(jí)功能
0602、訪問(wèn)器屬性不包含數(shù)據(jù)值;它們包含一對(duì)兒getter 和 setter函數(shù)(不過(guò),這兩個(gè)函數(shù)都不是必需的)。在讀取訪問(wèn)器屬性時(shí),會(huì)調(diào)用getter函數(shù),這個(gè)函數(shù)負(fù)責(zé)返回有效的值;在寫(xiě)入訪問(wèn)器屬性時(shí),會(huì)調(diào)用setter函數(shù)并傳入新值,這個(gè)函數(shù)負(fù)責(zé)決定如何處理數(shù)據(jù)。訪問(wèn)器屬性有如下 4 個(gè)特性:[[Configurable]]、[[Enumerable]]、[[Get]]、[[Set]]
0603、在不支持Object.defineProperty()方法的瀏覽器中不能修改[[Configurable]]和[[Enumerable]]
0604、支持 Object.defineProperties()方法的瀏覽器有 IE9+、Firefox 4+、Safari 5+、Opera 12+和Chrome
0605、在 JavaScript 中,可以針對(duì)任何對(duì)象——包括 DOM 和 BOM 對(duì)象,使用 Object.getOwnProperty-Descriptor() 方法。支持這個(gè)方法的瀏覽器有 IE9+、Firefox 4+、Safari 5+、Opera 12+和 Chrome
0606、工廠模式是軟件工程領(lǐng)域一種廣為人知的設(shè)計(jì)模式,這種模式抽象了創(chuàng)建具體對(duì)象的過(guò)程。工廠模式雖然解決了創(chuàng)建多個(gè)相似對(duì)象的問(wèn)題,但卻沒(méi)有解決對(duì)象識(shí)別的問(wèn)題(即怎樣知道一個(gè)對(duì)象的類(lèi)型)
0607、構(gòu)造器模式。沒(méi)有顯式地創(chuàng)建對(duì)象;直接將屬性和方法賦給了 this 對(duì)象;沒(méi)有 return 語(yǔ)句。以這種方式調(diào)用構(gòu)造函數(shù)實(shí)際上會(huì)經(jīng)歷以下 4個(gè)步驟:創(chuàng)建一個(gè)新對(duì)象; 將構(gòu)造函數(shù)的作用域賦給新對(duì)象(因此 this 就指向了這個(gè)新對(duì)象);執(zhí)行構(gòu)造函數(shù)中的代碼(為這個(gè)新對(duì)象添加屬性);返回新對(duì)象。以這種方式定義的構(gòu)造函數(shù)是定義在 Global 對(duì)象(在瀏覽器中是 window 對(duì)象)中的。使用構(gòu)造函數(shù)的主要問(wèn)題,就是每個(gè)方法都要在每個(gè)實(shí)例上重新創(chuàng)建一遍。在前面的例子中, person1 和 person2 都有一個(gè)名為 sayName() 的方法,但那兩個(gè)方法不是同一個(gè) Function 的實(shí)例
0608、 prototype 就是通過(guò)調(diào)用構(gòu)造函數(shù)而創(chuàng)建的那個(gè)對(duì)象實(shí)例的原型對(duì)象我們創(chuàng)建的每個(gè)函數(shù)都有一個(gè) prototype (原型)屬性,這個(gè)屬性是一個(gè)指針,指向一個(gè)對(duì)象,而這個(gè)對(duì)象的用途是包含可以由特定類(lèi)型的所有實(shí)例共享的屬性和方法。使用原型對(duì)象的好處是可以讓所有對(duì)象實(shí)例共享它所包含的屬性和方法。換句話(huà)說(shuō),不必在構(gòu)造函數(shù)中定義對(duì)象實(shí)例的信息,而是可以將這些信息直接添加到原型對(duì)象中
0609、無(wú)論什么時(shí)候,只要?jiǎng)?chuàng)建了一個(gè)新函數(shù),就會(huì)根據(jù)一組特定的規(guī)則為該函數(shù)創(chuàng)建一個(gè) prototype屬性,這個(gè)屬性指向函數(shù)的原型對(duì)象。在默認(rèn)情況下,所有原型對(duì)象都會(huì)自動(dòng)獲得一個(gè) constructor(構(gòu)造函數(shù))屬性,這個(gè)屬性包含一個(gè)指向 prototype 屬性所在函數(shù)的指針
0610、使用 Object.getPrototypeOf()可以方便地取得一個(gè)對(duì)象的原型,而這在利用原型實(shí)現(xiàn)繼承(本章稍后會(huì)討論)的情況下是非常重要的。支持這個(gè)方法的瀏覽器有 IE9+、Firefox 3.5+、Safari 5+、Opera 12+和 Chrome
0611、使用 delete 操作符則可以完全刪除實(shí)例屬性,從而讓我們能夠重新訪問(wèn)原型中的屬性
0612、使用 hasOwnProperty() 方法可以檢測(cè)一個(gè)屬性是存在于實(shí)例中,還是存在于原型中。這個(gè)方法(不要忘了它是從 Object 繼承來(lái)的)只在給定屬性存在于對(duì)象實(shí)例中時(shí),才會(huì)返回 true
0613、ECMAScript 5 的 Object.getOwnPropertyDescriptor() 方法只能用于實(shí)例屬性,要取得原型屬性的描述符,必須直接在原型對(duì)象上調(diào)用 Object.getOwnProperty-Descriptor() 方法
0614、有兩種方式使用 in 操作符:多帶帶使用和在 for-in 循環(huán)中使用。在多帶帶使用時(shí), in 操作符會(huì)在通過(guò)對(duì)象能夠訪問(wèn)給定屬性時(shí)返回true,無(wú)論該屬性存在于實(shí)例中還是原型中
0615、由于 in 操作符只要通過(guò)對(duì)象能夠訪問(wèn)到屬性就返回 true , hasOwnProperty() 只在屬性存在于實(shí)例中時(shí)才返回 true ,因此只要 in 操作符返回 true 而 hasOwnProperty() 返回 false ,就可以確定屬性是原型中的屬性
0616、要取得對(duì)象上所有可枚舉的實(shí)例屬性,可以使用 ECMAScript 5 的 Object.keys() 方法。這個(gè)方法接收一個(gè)對(duì)象作為參數(shù),返回一個(gè)包含所有可枚舉屬性的字符串?dāng)?shù)組
0617、如果你想要得到所有實(shí)例屬性,無(wú)論它是否可枚舉,都可以使用 Object.getOwnPropertyNames()方法。 Object.keys() 和 Object.getOwnProperty-Names() 方法都可以用來(lái)替代 for-in 循環(huán)。支持這兩個(gè)方法的瀏覽器有 IE9+、Firefox 4+、Safari 5+、Opera12+和 Chrome
0618、實(shí)例與原型之間的連接只不過(guò)是一個(gè)指針,而非一個(gè)副本,因此就可以在原型中找到新的 sayHi 屬性并返回保存在那里的函數(shù)
0619、原型模式也不是沒(méi)有缺點(diǎn)。首先,它省略了為構(gòu)造函數(shù)傳遞初始化參數(shù)這一環(huán)節(jié),結(jié)果所有實(shí)例在默認(rèn)情況下都將取得相同的屬性值。雖然這會(huì)在某種程度上帶來(lái)一些不方便,但還不是原型的最大問(wèn)題。原型模式的最大問(wèn)題是由其共享的本性所導(dǎo)致的
0620、混合模式。創(chuàng)建自定義類(lèi)型的最常見(jiàn)方式,就是組合使用構(gòu)造函數(shù)模式與原型模式。構(gòu)造函數(shù)模式用于定義實(shí)例屬性,而原型模式用于定義方法和共享的屬性。結(jié)果,每個(gè)實(shí)例都會(huì)有自己的一份實(shí)例屬性的副本,但同時(shí)又共享著對(duì)方法的引用,最大限度地節(jié)省了內(nèi)存。另外,這種混成模式還支持向構(gòu)造函數(shù)傳遞參數(shù);可謂是集兩種模式之長(zhǎng)。這種構(gòu)造函數(shù)與原型混成的模式,是目前在 ECMAScript中使用最廣泛、認(rèn)同度最高的一種創(chuàng)建自定義類(lèi)型的方法??梢哉f(shuō),這是用來(lái)定義引用類(lèi)型的一種默認(rèn)模式
0621、使用動(dòng)態(tài)原型模式時(shí),不能使用對(duì)象字面量重寫(xiě)原型。前面已經(jīng)解釋過(guò)了,如果在已經(jīng)創(chuàng)建了實(shí)例的情況下重寫(xiě)原型,那么就會(huì)切斷現(xiàn)有實(shí)例與新原型之間的聯(lián)系
0622、關(guān)于寄生構(gòu)造函數(shù)模式,有一點(diǎn)需要說(shuō)明:首先,返回的對(duì)象與構(gòu)造函數(shù)或者與構(gòu)造函數(shù)的原型屬性之間沒(méi)有關(guān)系;也就是說(shuō),構(gòu)造函數(shù)返回的對(duì)象與在構(gòu)造函數(shù)外部創(chuàng)建的對(duì)象沒(méi)有什么不同。為此,不能依賴(lài) instanceof 操作符來(lái)確定對(duì)象類(lèi)型。由于存在上述問(wèn)題,我們建議在可以使用其他模式的情況下,不要使用這種模式
0623、繼承是 OO 語(yǔ)言中的一個(gè)最為人津津樂(lè)道的概念。許多 OO 語(yǔ)言都支持兩種繼承方式:接口繼承和實(shí)現(xiàn)繼承。接口繼承只繼承方法簽名,而實(shí)現(xiàn)繼承則繼承實(shí)際的方法。如前所述,由于函數(shù)沒(méi)有簽名,在 ECMAScript 中無(wú)法實(shí)現(xiàn)接口繼承。ECMAScript 只支持實(shí)現(xiàn)繼承,而且其實(shí)現(xiàn)繼承主要是依靠原型鏈來(lái)實(shí)現(xiàn)的
0624、構(gòu)造函數(shù)、原型和實(shí)例的關(guān)系。每個(gè)構(gòu)造函數(shù)都有一個(gè)原型對(duì)象,原型對(duì)象都包含一個(gè)指向構(gòu)造函數(shù)的指針,而實(shí)例都包含一個(gè)指向原型對(duì)象的內(nèi)部指針
0625、謹(jǐn)慎地定義方法。子類(lèi)型有時(shí)候需要重寫(xiě)超類(lèi)型中的某個(gè)方法,或者需要添加超類(lèi)型中不存在的某個(gè)方法。但不管怎樣,給原型添加方法的代碼一定要放在替換原型的語(yǔ)句之后
0626、通過(guò)原型鏈實(shí)現(xiàn)繼承時(shí),不能使用對(duì)象字面量創(chuàng)建原型方法。因?yàn)檫@樣做就會(huì)重寫(xiě)原型鏈
0627、在解決原型中包含引用類(lèi)型值所帶來(lái)問(wèn)題的過(guò)程中,開(kāi)發(fā)人員開(kāi)始使用一種叫做借用構(gòu)造函數(shù)(constructor stealing)的技術(shù)(有時(shí)候也叫做偽造對(duì)象或經(jīng)典繼承)。這種技術(shù)的基本思想相當(dāng)簡(jiǎn)單,即在子類(lèi)型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類(lèi)型構(gòu)造函數(shù)。別忘了,函數(shù)只不過(guò)是在特定環(huán)境中執(zhí)行代碼的對(duì)象,因此通過(guò)使用 apply() 和 call() 方法也可以在(將來(lái))新創(chuàng)建的對(duì)象上執(zhí)行構(gòu)造函數(shù)
0628、相對(duì)于原型鏈而言,借用構(gòu)造函數(shù)有一個(gè)很大的優(yōu)勢(shì),即可以在子類(lèi)型構(gòu)造函數(shù)中向超類(lèi)型構(gòu)造函數(shù)傳遞參數(shù)
0629、如果僅僅是借用構(gòu)造函數(shù),那么也將無(wú)法避免構(gòu)造函數(shù)模式存在的問(wèn)題——方法都在構(gòu)造函數(shù)中定義,因此函數(shù)復(fù)用就無(wú)從談起了。而且,在超類(lèi)型的原型中定義的方法,對(duì)子類(lèi)型而言也是不可見(jiàn)的,結(jié)果所有類(lèi)型都只能使用構(gòu)造函數(shù)模式??紤]到這些問(wèn)題,借用構(gòu)造函數(shù)的技術(shù)也是很少多帶帶使用的
0630、ECMAScript 5 通過(guò)新增 Object.create() 方法規(guī)范化了原型式繼承。這個(gè)方法接收兩個(gè)參數(shù):一個(gè)用作新對(duì)象原型的對(duì)象和(可選的)一個(gè)為新對(duì)象定義額外屬性的對(duì)象。在傳入一個(gè)參數(shù)的情況下,Object.create() 與 object() 方法的行為相同。Object.create() 方法的第二個(gè)參數(shù)與 Object.defineProperties() 方法的第二個(gè)參數(shù)格式相同:每個(gè)屬性都是通過(guò)自己的描述符定義的。以這種方式指定的任何屬性都會(huì)覆蓋原型對(duì)象上的同名屬性
0631、寄生組合式繼承,即通過(guò)借用構(gòu)造函數(shù)來(lái)繼承屬性,通過(guò)原型鏈的混成形式來(lái)繼承方法
0632、 工廠模式,使用簡(jiǎn)單的函數(shù)創(chuàng)建對(duì)象,為對(duì)象添加屬性和方法,然后返回對(duì)象。這個(gè)模式后來(lái)被構(gòu)造函數(shù)模式所取代
0633、 構(gòu)造函數(shù)模式,可以創(chuàng)建自定義引用類(lèi)型,可以像創(chuàng)建內(nèi)置對(duì)象實(shí)例一樣使用 new 操作符。不過(guò),構(gòu)造函數(shù)模式也有缺點(diǎn),即它的每個(gè)成員都無(wú)法得到復(fù)用,包括函數(shù)。由于函數(shù)可以不局限于任何對(duì)象(即與對(duì)象具有松散耦合的特點(diǎn)),因此沒(méi)有理由不在多個(gè)對(duì)象間共享函數(shù)
0634、原型模式,使用構(gòu)造函數(shù)的 prototype 屬性來(lái)指定那些應(yīng)該共享的屬性和方法。組合使用構(gòu)造函數(shù)模式和原型模式時(shí),使用構(gòu)造函數(shù)定義實(shí)例屬性,而使用原型定義共享的屬性和方法
0635、JavaScript 主要通過(guò)原型鏈實(shí)現(xiàn)繼承。原型鏈的構(gòu)建是通過(guò)將一個(gè)類(lèi)型的實(shí)例賦值給另一個(gè)構(gòu)造函數(shù)的原型實(shí)現(xiàn)的。這樣,子類(lèi)型就能夠訪問(wèn)超類(lèi)型的所有屬性和方法,這一點(diǎn)與基于類(lèi)的繼承很相似。原型鏈的問(wèn)題是對(duì)象實(shí)例共享所有繼承的屬性和方法,因此不適宜多帶帶使用。解決這個(gè)問(wèn)題的技術(shù)是借用構(gòu)造函數(shù),即在子類(lèi)型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類(lèi)型構(gòu)造函數(shù)。這樣就可以做到每個(gè)實(shí)例都具有自己的屬性,同時(shí)還能保證只使用構(gòu)造函數(shù)模式來(lái)定義類(lèi)型。使用最多的繼承模式是組合繼承,這種模式使用原型鏈繼承共享的屬性和方法,而通過(guò)借用構(gòu)造函數(shù)繼承實(shí)例屬性。 寄生組合式繼承,集寄生式繼承和組合繼承的優(yōu)點(diǎn)與一身,是實(shí)現(xiàn)基于類(lèi)型繼承的最有效方式
0636、當(dāng)某個(gè)函數(shù)被調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)執(zhí)行環(huán)境(execution context)及相應(yīng)的作用域鏈。然后,使用 arguments 和其他命名參數(shù)的值來(lái)初始化函數(shù)的活動(dòng)對(duì)象(activation object)。但在作用域鏈中,外部函數(shù)的活動(dòng)對(duì)象始終處于第二位,外部函數(shù)的外部函數(shù)的活動(dòng)對(duì)象處于第三位,……直至作為作用域鏈終點(diǎn)的全局執(zhí)行環(huán)境
第七章 函數(shù)表達(dá)式0701、由于閉包會(huì)攜帶包含它的函數(shù)的作用域,因此會(huì)比其他函數(shù)占用更多的內(nèi)存。過(guò)度使用閉包可能會(huì)導(dǎo)致內(nèi)存占用過(guò)多,我們建議讀者只在絕對(duì)必要時(shí)再考慮使用閉包。雖然像 V8 等優(yōu)化后的 JavaScript 引擎會(huì)嘗試回收被閉包占用的內(nèi)存,但請(qǐng)大家還是要慎重使用閉包
0702、在閉包中使用 this 對(duì)象也可能會(huì)導(dǎo)致一些問(wèn)題。我們知道, this 對(duì)象是在運(yùn)行時(shí)基于函數(shù)的執(zhí)行環(huán)境綁定的:在全局函數(shù)中, this 等于 window ,而當(dāng)函數(shù)被作為某個(gè)對(duì)象的方法調(diào)用時(shí), this 等于那個(gè)對(duì)象。不過(guò),匿名函數(shù)的執(zhí)行環(huán)境具有全局性,因此其 this 對(duì)象通常指向window。但有時(shí)候由于編寫(xiě)閉包的方式不同,這一點(diǎn)可能不會(huì)那么明顯
0703、如果閉包的作用域鏈中保存著一個(gè)HTML 元素,那么就意味著該元素將無(wú)法被銷(xiāo)毀
0704、閉包會(huì)引用包含函數(shù)的整個(gè)活動(dòng)對(duì)象,而其中包含著 element 。即使閉包不直接引用 element ,包含函數(shù)的活動(dòng)對(duì)象中也仍然會(huì)保存一個(gè)引用。因此,有必要把 element 變量設(shè)置為 null 。這樣就能夠解除對(duì) DOM 對(duì)象的引用,順利地減少其引用數(shù),確保正?;厥掌湔加玫膬?nèi)存
0705、函數(shù)聲明后面不能跟圓括號(hào)。然而,函數(shù)表達(dá)式的后面可以跟圓括號(hào)。要將函數(shù)聲明轉(zhuǎn)換成函數(shù)表達(dá)式,只要像下面這樣給它加上一對(duì)圓括號(hào)即可
0706、一般來(lái)說(shuō),我們都應(yīng)該盡量少向全局作用域中添加變量和函數(shù)。在一個(gè)由很多開(kāi)發(fā)人員共同參與的大型應(yīng)用程序中,過(guò)多的全局變量和函數(shù)很容易導(dǎo)致命名沖突。而通過(guò)創(chuàng)建私有作用域,每個(gè)開(kāi)發(fā)人員既可以使用自己的變量,又不必?fù)?dān)心搞亂全局作用域
0707、嚴(yán)格來(lái)講,JavaScript 中沒(méi)有私有成員的概念;所有對(duì)象屬性都是公有的。不過(guò),倒是有一個(gè)私有變量的概念。任何在函數(shù)中定義的變量,都可以認(rèn)為是私有變量,因?yàn)椴荒茉诤瘮?shù)的外部訪問(wèn)這些變量。私有變量包括函數(shù)的參數(shù)、局部變量和在函數(shù)內(nèi)部定義的其他函數(shù)。
0708、構(gòu)造函數(shù)模式的缺點(diǎn)是針對(duì)每個(gè)實(shí)例都會(huì)創(chuàng)建同樣一組新方法,而使用靜態(tài)私有變量來(lái)實(shí)現(xiàn)特權(quán)方法就可以避免這個(gè)問(wèn)題
0709、初始化未經(jīng)聲明的變量,總是會(huì)創(chuàng)建一個(gè)全局變量
0710、多查找作用域鏈中的一個(gè)層次,就會(huì)在一定程度上影響查找速度。而這正是使用閉包和私有變量的一個(gè)顯明的不足之處
0711、 函數(shù)表達(dá)式不同于函數(shù)聲明。函數(shù)聲明要求有名字,但函數(shù)表達(dá)式不需要。沒(méi)有名字的函數(shù)表達(dá)式也叫做匿名函數(shù)
0712、在無(wú)法確定如何引用函數(shù)的情況下,遞歸函數(shù)就會(huì)變得比較復(fù)雜
0713、 遞歸函數(shù)應(yīng)該始終使用 arguments.callee 來(lái)遞歸地調(diào)用自身,不要使用函數(shù)名——函數(shù)名可能會(huì)發(fā)生變化
0714、當(dāng)在函數(shù)內(nèi)部定義了其他函數(shù)時(shí),就創(chuàng)建了閉包。閉包有權(quán)訪問(wèn)包含函數(shù)內(nèi)部的所有變量:在后臺(tái)執(zhí)行環(huán)境中,閉包的作用域鏈包含著它自己的作用域、包含函數(shù)的作用域和全局作用域;通常,函數(shù)的作用域及其所有變量都會(huì)在函數(shù)執(zhí)行結(jié)束后被銷(xiāo)毀;但是,當(dāng)函數(shù)返回了一個(gè)閉包時(shí),這個(gè)函數(shù)的作用域?qū)?huì)一直在內(nèi)存中保存到閉包不存在為止
0715、使用閉包可以在 JavaScript中模仿塊級(jí)作用域(JavaScript本身沒(méi)有塊級(jí)作用域的概念)
0716、JavaScript 中的函數(shù)表達(dá)式和閉包都是極其有用的特性,利用它們可以實(shí)現(xiàn)很多功能。不過(guò),因?yàn)閯?chuàng)建閉包必須維護(hù)額外的作用域,所以過(guò)度使用它們可能會(huì)占用大量?jī)?nèi)存
第八章 BOM0801、拋開(kāi)全局變量會(huì)成為 window 對(duì)象的屬性不談,定義全局變量與在 window 對(duì)象上直接定義屬性還是有一點(diǎn)差別:全局變量不能通過(guò) delete 操作符刪除,而直接在 window 對(duì)象上的定義的屬性可以
0802、剛才使用 var 語(yǔ)句添加的 window 屬性有一個(gè)名為 [[Configurable]] 的特性,這個(gè)特性的值被設(shè)置為 false ,因此這樣定義的屬性不可以通過(guò) delete 操作符刪除。IE8及更早版本在遇到使用 delete刪除 window 屬性的語(yǔ)句時(shí),不管該屬性最初是如何創(chuàng)建的,都會(huì)拋出錯(cuò)誤,以示警告。IE9 及更高版本不會(huì)拋出錯(cuò)誤
0803、嘗試訪問(wèn)未聲明的變量會(huì)拋出錯(cuò)誤,但是通過(guò)查詢(xún) window 對(duì)象,可以知道某個(gè)可能未聲明的變量是否存在202、窗口位置。用來(lái)確定和修改 window 對(duì)象位置的屬性和方法有很多。IE、Safari、Opera 和 Chrome 都提供了screenLeft 和 screenTop 屬性,分別用于表示窗口相對(duì)于屏幕左邊和上邊的位置。Firefox 則在screenX 和 screenY 屬性中提供相同的窗口位置信息,Safari 和 Chrome 也同時(shí)支持這兩個(gè)屬性。Opera雖然也支持 screenX 和 screenY 屬性,但與 screenLeft 和 screenTop 屬性并不對(duì)應(yīng),因此建議大家不要在 Opera 中使用它們
0804、最終結(jié)果,就是無(wú)法在跨瀏覽器的條件下取得窗口左邊和上邊的精確坐標(biāo)值。然而,使用 moveTo()和 moveBy() 方法倒是有可能將窗口精確地移動(dòng)到一個(gè)新位置。這兩個(gè)方法都接收兩個(gè)參數(shù),其中moveTo() 接收的是新位置的 x 和 y 坐標(biāo)值,而 moveBy() 接收的是在水平和垂直方向上移動(dòng)的像素?cái)?shù)。
0805、需要注意的是,這兩個(gè)方法可能會(huì)被瀏覽器禁用;而且,在 Opera 和 IE 7(及更高版本)中默認(rèn)就是禁用的。另外,這兩個(gè)方法都不適用于框架,只能對(duì)最外層的 window 對(duì)象使用
0806、跨瀏覽器確定一個(gè)窗口的大小不是一件簡(jiǎn)單的事。IE9+、Firefox、Safari、Opera 和 Chrome 均為此提供了 4個(gè)屬性: innerWidth、 innerHeight 、 outerWidth 和 outerHeight 。在 IE9+、Safari和 Firefox中, outerWidth 和 outerHeight 返回瀏覽器窗口本身的尺寸(無(wú)論是從最外層的 window 對(duì)象還是從某個(gè)框架訪問(wèn))。在Opera中,這兩個(gè)屬性的值表示頁(yè)面視圖容器① 的大小。而innerWidth 和 innerHeight則表示該容器中頁(yè)面視圖區(qū)的大?。p去邊框?qū)挾龋?。?Chrome 中, outerWidth 、 outerHeight 與innerWidth 、 innerHeight 返回相同的值,即視口(viewport)大小而非瀏覽器窗口大小
0807、在 IE、Firefox、Safari、Opera 和 Chrome 中, document.documentElement.clientWidth 和document.documentElement.clientHeight 中保存了頁(yè)面視口的信息。在 IE6 中,這些屬性必須在標(biāo)準(zhǔn)模式下才有效;如果是混雜模式,就必須通過(guò) document.body.clientWidth 和 document.body.clientHeight 取得相同信息。而對(duì)于混雜模式下的 Chrome,則無(wú)論通過(guò) document.documentEle-ment 還是 document.body 中的 clientWidth 和 clientHeight 屬性,都可以取得視口的大小
0808、對(duì)于移動(dòng)設(shè)備, window.innerWidth 和 window.innerHeight 保存著可見(jiàn)視口,也就是屏幕上可見(jiàn)頁(yè)面區(qū)域的大小。移動(dòng) IE 瀏覽器不支持這些屬性,但通過(guò) document.documentElement.client-Width 和 document.documentElement.clientHeihgt 提供了相同的信息。隨著頁(yè)面的縮放,這些值也會(huì)相應(yīng)變化
0809、有關(guān)移動(dòng)設(shè)備視口的話(huà)題比較復(fù)雜,有很多非常規(guī)的情形,也有各種各樣的建議。移動(dòng)開(kāi)發(fā)咨詢(xún)師 Peter-Paul Koch 記述了他對(duì)這個(gè)問(wèn)題的研究:http://t.cn/zOZs0Tz。如果你在做移動(dòng) Web 開(kāi)發(fā),推薦你讀一讀這篇文章
0810、 window.open() 方法既可以導(dǎo)航到一個(gè)特定的 URL,也可以打開(kāi)一個(gè)新的瀏覽器窗口。這個(gè)方法可以接收 4 個(gè)參數(shù):要加載的 URL、窗口目標(biāo)、一個(gè)特性字符串以及一個(gè)表示新頁(yè)面是否取代瀏覽器歷史記錄中當(dāng)前加載頁(yè)面的布爾值。通常只須傳遞第一個(gè)參數(shù),最后一個(gè)參數(shù)只在不打開(kāi)新窗口的情況下使用。后面這行代碼會(huì)打開(kāi)一個(gè)新的可以調(diào)整大小的窗口,窗口初始大小為 400×400 像素,并且距屏幕上沿和左邊各 10 像素。window.open("http://www.wrox.com/","wroxWindow","height=400,width=400,top=10,left=10,resizable=yes");
0811、wroxWin.close()這個(gè)方法僅適用于通過(guò) window.open() 打開(kāi)的彈出窗口。對(duì)于瀏覽器的主窗口,如果沒(méi)有得到用戶(hù)的允許是不能關(guān)閉它的。不過(guò),彈出窗口倒是可以調(diào)用 top.close() 在不經(jīng)用戶(hù)允許的情況下關(guān)閉自己。彈出窗口關(guān)閉之后,窗口的引用仍然還在,但除了像下面這樣檢測(cè)其 closed 屬性之外,已經(jīng)沒(méi)有其他用處了
0812、超時(shí)調(diào)用需要使用 window 對(duì)象的 setTimeout() 方法,它接受兩個(gè)參數(shù):要執(zhí)行的代碼和以毫秒表示的時(shí)間(即在執(zhí)行代碼前需要等待多少毫秒)。由于傳遞字符串可能導(dǎo)致性能損失,因此不建議以字符串作為第一個(gè)參數(shù)
0813、JavaScript 是一個(gè)單線程序的解釋器,因此一定時(shí)間內(nèi)只能執(zhí)行一段代碼。為了控制要執(zhí)行的代碼,就有一個(gè) JavaScript 任務(wù)隊(duì)列。這些任務(wù)會(huì)按照將它們添加到隊(duì)列的順序執(zhí)行。 setTimeout() 的第二個(gè)參數(shù)告訴 JavaScript 再過(guò)多長(zhǎng)時(shí)間把當(dāng)前任務(wù)添加到隊(duì)列中。如果隊(duì)列是空的,那么添加的代碼會(huì)立即執(zhí)行;如果隊(duì)列不是空的,那么它就要等前面的代碼執(zhí)行完了以后再執(zhí)行
0814、超時(shí)調(diào)用的代碼都是在全局作用域中執(zhí)行的,因此函數(shù)中 this 的值在非嚴(yán)格模式下指向 window 對(duì)象,在嚴(yán)格模式下是 undefined
0815、一般認(rèn)為,使用超時(shí)調(diào)用來(lái)模擬間歇調(diào)用的是一種最佳模式。在開(kāi)發(fā)環(huán)境下,很少使用真正的間歇調(diào)用,原因是后一個(gè)間歇調(diào)用可能會(huì)在前一個(gè)間歇調(diào)用結(jié)束之前啟動(dòng)。而像前面示例中那樣使用超時(shí)調(diào)用,則完全可以避免這一點(diǎn)。所以,最好不要使用間歇調(diào)用
0816、通過(guò) JavaScript 打開(kāi)的對(duì)話(huà)框,即“查找”和“打印”。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/107739.html
摘要:類(lèi)型沒(méi)有重載聲明了兩個(gè)同名函數(shù),而結(jié)果則是后面的函數(shù)覆蓋了前面的函數(shù)。引用的是函數(shù)據(jù)以執(zhí)行的環(huán)境對(duì)象函數(shù)屬性和方法表示函數(shù)希望接收的命名參數(shù)的個(gè)數(shù)。而自動(dòng)創(chuàng)建的基本包裝類(lèi)型的對(duì)象,則只存在于一行代碼的執(zhí)行瞬間,然后立即被銷(xiāo)毀。 Function類(lèi)型 沒(méi)有重載 聲明了兩個(gè)同名函數(shù),而結(jié)果則是后面的函數(shù)覆蓋了前面的函數(shù)。 var addSomeNumber = function (num)...
摘要:方法接受一個(gè)布爾值參數(shù),表示是否執(zhí)行深復(fù)制方法不會(huì)復(fù)制添加到節(jié)點(diǎn)中的屬性,例如事件處理程序等。由于跨域安全限制,來(lái)自不同子域的頁(yè)面無(wú)法通過(guò)通信。這三個(gè)集合都是動(dòng)態(tài)的換句話(huà)說(shuō),每當(dāng)文檔結(jié)構(gòu)發(fā)生變化時(shí),它們都會(huì)得到更新。 第十章 DOM 1001、每一段標(biāo)記都可以通過(guò)樹(shù)中的一個(gè)節(jié)點(diǎn)來(lái)表示:HTML 元素通過(guò)元素節(jié)點(diǎn)表示,特性(attribute)通過(guò)特性節(jié)點(diǎn)表示,文檔類(lèi)型通過(guò)文檔類(lèi)型節(jié)點(diǎn)...
摘要:其中負(fù)載均衡那一節(jié),基本上是參考的權(quán)威指南負(fù)載均衡的內(nèi)容。開(kāi)發(fā)指南讀了一半,就是看這本書(shū)理解了的事件循環(huán)。哈哈創(chuàng)京東一本騙錢(qián)的書(shū)。 歡迎大家前往騰訊云+社區(qū),獲取更多騰訊海量技術(shù)實(shí)踐干貨哦~ 本文由騰訊IVWEB團(tuán)隊(duì) 發(fā)表于云+社區(qū)專(zhuān)欄作者:link 2014年一月以來(lái),自己接觸web前端開(kāi)發(fā)已經(jīng)兩年多了,記錄一下自己前端學(xué)習(xí)路上看過(guò)的,以及道聽(tīng)途說(shuō)的一些書(shū),基本上按照由淺入深來(lái)介紹...
摘要:其中負(fù)載均衡那一節(jié),基本上是參考的權(quán)威指南負(fù)載均衡的內(nèi)容。開(kāi)發(fā)指南讀了一半,就是看這本書(shū)理解了的事件循環(huán)。哈哈創(chuàng)京東一本騙錢(qián)的書(shū)。 歡迎大家前往騰訊云+社區(qū),獲取更多騰訊海量技術(shù)實(shí)踐干貨哦~ 本文由騰訊IVWEB團(tuán)隊(duì) 發(fā)表于云+社區(qū)專(zhuān)欄作者:link 2014年一月以來(lái),自己接觸web前端開(kāi)發(fā)已經(jīng)兩年多了,記錄一下自己前端學(xué)習(xí)路上看過(guò)的,以及道聽(tīng)途說(shuō)的一些書(shū),基本上按照由淺入深來(lái)介紹...
閱讀 2972·2023-04-25 19:20
閱讀 839·2021-11-24 09:38
閱讀 2115·2021-09-26 09:55
閱讀 2472·2021-09-02 15:11
閱讀 2156·2019-08-30 15:55
閱讀 3643·2019-08-30 15:54
閱讀 3178·2019-08-30 14:03
閱讀 2992·2019-08-29 17:11