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