第二章:在HTML中使用JS
2.1? <script>標(biāo)簽重要屬性
? ? ? ? async:表示立即下載腳本,但不該妨礙頁面中其他的操作,比如下載其他資源或等待加載其他腳本。只對外部腳本文件有效。
? ? ? ? defer:表示腳本可以延遲到文檔完全被解析和顯示后再執(zhí)行。只對外部腳本文件有效。
? ? ? ? src:
? ? ? ? type:表示要編寫代碼使用的腳本語言的內(nèi)容類型(MIME類型)
除此之外,使用<script>標(biāo)簽嵌入JS代碼的時候,代碼中不要出現(xiàn)字符串“</script>”,會被默認(rèn)認(rèn)為其是結(jié)束的標(biāo)簽,必須要轉(zhuǎn)義,如:"<\/script>"才行。
2.2 使用外部腳本的優(yōu)點(diǎn)
? ? ? 1.可維護(hù)性:開發(fā)人員可以在不觸及HTML標(biāo)記的情況下,集中編輯JS代碼。
? ? ? 2.可緩存:如果有兩個頁面都使用的同一個JS文件,那么這個文件只需要被下載一次。
2.3 <noscript>元素
? ? ?該標(biāo)簽是可以指定在不支持腳本的瀏覽器中所顯示的替代內(nèi)容,啟用腳本之后,瀏覽器不會顯示該標(biāo)簽中任何內(nèi)容:如 ?<noscript> ?<p>本頁面需要瀏覽器支持(啟用)JS</p></noscript>
第三章:基本概念
number: ? var num1 = parseInt("10",2); ?//2(按二進(jìn)制解析) ? ??
? ? ? ? ? ? ? ? ? ? ?var num2 = parseInt("10",8); //8(按八進(jìn)制解析)
string: ?? 1. ?null和undefined沒有toString的方法,需要用String方法
? ? ? ? ? ? ? ? ? ? 2. toString方法前面是變量,如10.toString(2)會報錯,需要先把10賦值給一個變? ? ? ? 量,如var num=10,num.toString(2)才行。
Object:
1.Object的每個實(shí)例都有下面屬性和方法
? ?constructor:保存著用于創(chuàng)建當(dāng)前對象的函數(shù)。
? ?hasOwnProperty(propertyName):用于檢查給定屬性在當(dāng)前當(dāng)前實(shí)例中(而不是在實(shí)例原型中)是否存在,其中,作為參數(shù)的屬性名必須用字符串形式指定(object.hasOwnProperty("name")).
? ?isPrototypeOf(object):用于檢查傳入的對象是否是另一個對象的原型。
? ?propertyIsEnumerable(propertyName):用于檢查給定屬性是否能用for-in語句來枚舉,同樣的屬性名必須用字符串形式制定。
? toString():返回對象的字符串表示。
valueOf():通常和toString()的返回值相同
第四章:變量、作用域和內(nèi)存
4.1:基本類型和引用類型的值
⑴基本類型的值不能添加屬性(盡管不會導(dǎo)致任何錯誤),引用類型的值可以添加屬性方法
⑵從一個變量向另外一個變量上復(fù)制基本類型的值,會在新變量對象上創(chuàng)建一個和該值相同的新值,兩個值互相操作不影響;而引用類型則是復(fù)制一個指針,和前一個變量一樣指向的是儲存在堆內(nèi)存中的同個對象。因此,改變其中一個變量,就會影響另一個變量。如下圖:

第五章:引用類型
5.1:Object類型
? ? (1)兩種方式訪問對象屬性:person.name和person["name"],后者的好處是可以通過變量來訪問屬性以及當(dāng)屬性名包含導(dǎo)致錯誤語法的字符。如果不是必須,通常建議用第一種方法訪問屬性

5.2:Array類型
? ?(1)訪問數(shù)組中不存在或者未賦值的項返回的是undefined,如數(shù)組長度是3,你訪問array[3]。
? ?(2)檢測是否是數(shù)組一般直接用Array.isArray(array)方法,因為instanceof方法在多于一個框架的情況下會有多個不同的原生數(shù)組的構(gòu)造函數(shù)
? ?(3)當(dāng)數(shù)組中的某個值為null或者undefined時使用join、toString、valueOf方法返回的是空字符串
? ?(4)數(shù)組模擬棧方法(后入先出,最后一項被移除) ?使用push和pop方法
? ?(5)數(shù)組模擬隊列方法(先入先出,第一項被移除) ?使用push和shift方法
? ?(6)slice:兩個參數(shù)時返回起始到結(jié)束的項。包含開始項,不包含結(jié)束項。
? ?(7)splice:①刪除:指定兩個參數(shù),刪除第一個參數(shù)項的位置和刪除的項數(shù) 如splice(0,2)會刪除 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?數(shù)組中的前兩項。
? ? ? ? ? ? ? ? ? ②插入:可以向指定位置插入任意數(shù)量的項數(shù) ?如splice(2,0,"red","blue"),原數(shù)組會在第 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 三項后面插入兩個顏色字符串。當(dāng)前返回的是一個空數(shù)組。
? ? ? ? ? ? ? ? ? ③替換:可以像指定位置插入任意數(shù)量的項,且同時刪除任意數(shù)量的項 ?如 splice(2,1,"red","blue")會刪除并返回第三項,原數(shù)組會在第三項的位置插入兩個顏色字符串。
(8)數(shù)組的迭代方法:每個參數(shù)接收兩個參數(shù),第一個是要給數(shù)組每項執(zhí)行的函數(shù)和(可選的)運(yùn)行該函數(shù)的作用域?qū)ο蟆魅氲暮瘮?shù)會接收三個參數(shù):數(shù)組項的值、值的索引、數(shù)組本身
? ①every():對數(shù)組的每一項都運(yùn)行該函數(shù),如果該函數(shù)對每一項都返回true,則返回true。該函數(shù)返回的是布爾值。
? ②filter():對數(shù)組的每一項都運(yùn)行該函數(shù),返回該函數(shù)會返回true的項組成的數(shù)組。
? ③forEach():對數(shù)組的每一項都運(yùn)行該函數(shù),該方法沒有返回值。
? ④map():對數(shù)組的每一項都運(yùn)行該函數(shù),返回每次函數(shù)調(diào)用的結(jié)果組成的數(shù)組。
? ⑤some():對數(shù)組的每一項都運(yùn)行該函數(shù),如果該函數(shù)對任意一項返回true,則返回true。
以上的方法都不會修改原數(shù)組的值。
(9)數(shù)組的縮小方法:reduce()和reduceRight()。也是接收兩個參數(shù),一個是調(diào)用的函數(shù)和(可選的)作為縮小基礎(chǔ)的初始值。調(diào)用的函數(shù)接收4個參數(shù):前一個值、當(dāng)前值、值的索引和數(shù)組對象。
5.3:Date類型

5.4:Function類型
? ?(1):因為函數(shù)也是對象,所以函數(shù)名實(shí)際是指向函數(shù)對象的一個指針,不會與某個函數(shù)綁定。
? (2):解析器會率先讀取函數(shù)聲明,并使其在執(zhí)行任何代碼前可用;而函數(shù)表達(dá)式則必須等到解析器執(zhí)行到它所在的代碼行才會被真正解析執(zhí)行。
? (3):arguments.callee:指向擁有這個arguments對象的函數(shù)(嚴(yán)格模式下訪問會出錯)
5.5:String類型
(1):indexOf():可以用該函數(shù)來匹配字符串里所有的給定字符

(2):trim():創(chuàng)建一個字符串副本,去除字符串前置及后綴所有空格;該方法是為所有字符串創(chuàng)建的方法;例如:str.trim()
第六章:面向?qū)ο蟮某绦蛟O(shè)計
6.1.1:屬性類型 (為實(shí)現(xiàn)JS引擎用的內(nèi)部屬性) :數(shù)據(jù)屬性和訪問器屬性
1.數(shù)據(jù)屬性:
? ? ?[[configurable]]:表示能否通過delete刪除屬性,能否修改屬性的特性或者能否把屬性修改為訪問器屬性;默認(rèn)值為true。(改為false將不能改回true)
? ? [[enumerable]]:表示能否通過for-in循環(huán)返回屬性;默認(rèn)值是true。
? ? [[writable]]:表示能否修改屬性值;默認(rèn)值是true。
? ? [[value]]:包含屬性的數(shù)據(jù)值。默認(rèn)值是 undefined。
2.訪問器屬性:
? ?[[configurable]]:表示能否通過delete刪除屬性,能否修改屬性的特性或者能否把屬性修改為訪問器屬性;默認(rèn)值為true。
? [[enumerable]]:表示能否通過for-in循環(huán)返回屬性;默認(rèn)值是true。
? [[get]]:在讀取屬性時調(diào)用的函數(shù)。默認(rèn)值是 undefined。
? [[set]]:在寫入屬性時調(diào)用的函數(shù)。默認(rèn)值是 undefined。
以上屬性都是通過Object.defineProperty()方法修改:如Object.defineProperty(對象名,屬性,{configurable:false})則該對象的該屬性不可被刪除
6.2創(chuàng)建對象
6.2.1創(chuàng)建對象之工廠模式
? ? 該模式的缺點(diǎn)是沒有解決對象識別的問題(就是該模式是直接創(chuàng)建對象然后將其返回出去,它相當(dāng)于是。person1.constructor和instanceof不等于createPerson)

6.2.2創(chuàng)建對象之構(gòu)造函數(shù)模式
? ?直接將屬性和方法賦給this對象,然后用new關(guān)鍵字來創(chuàng)建實(shí)例,這樣該實(shí)例的constructior會指向構(gòu)造函數(shù)并且可以通過instanceof知道該實(shí)例是構(gòu)造函數(shù)的實(shí)例。
? 缺點(diǎn):是構(gòu)造函數(shù)里的方法會在每個實(shí)例被重新創(chuàng)建一次,比如構(gòu)造函數(shù)上面有一個sayName的方法,那就會在每個實(shí)例上都創(chuàng)建一個該方法,但是創(chuàng)建兩個及更多完成同樣任務(wù)的Function是沒必要的。
6.2.3創(chuàng)建對象之原型模式
? ?1. 方法:將屬性和方法直接添加到構(gòu)造函數(shù)的prototype中,然后用new關(guān)鍵字來生成實(shí)例。

?2.原型與in操作符:通過in操作符和hasOwnProperty()可以確定屬性是在實(shí)例上還是在原型上;
?3:for-in、Object.keys()、Object.getOwnPropertyNames()三種可以遍歷對象屬性的方法。
? ? for-in是返回當(dāng)前對象及其原型上所有可枚舉的屬性;Object.keys()是返回當(dāng)前對象上所有可以枚舉的屬性;?Object.getOwnPropertyNames()是返回當(dāng)前對象上所有的屬性,不管是否可以枚舉
?4:缺點(diǎn)
? ? ⑴:它省略了為構(gòu)造函數(shù)傳遞初始化參數(shù)這一過程,導(dǎo)致所有實(shí)例在默認(rèn)情況下都將取得相同的屬性值。
? ?⑵:致命問題是當(dāng)某個屬性是包含引用類型值的時候(如數(shù)組),問題就很突出。就是當(dāng)某個實(shí)例修改了含引用類型值的時候(如數(shù)組中的值被添加或者刪除),那修改的數(shù)組會在所有實(shí)例中反映出來。
6.2.4組合使用構(gòu)造函數(shù)模式和原型模式
? 1. 方法:構(gòu)造函數(shù)用于定義實(shí)例屬性,而原型模式用于定義方法和共享屬性

? 2. 缺點(diǎn):構(gòu)造函數(shù)和原型分開寫看著可能讓其他OO經(jīng)驗的人員感到困惑
6.2.5動態(tài)原型模式
? 1. 方法:只是將上種方法設(shè)計的所有信息封裝在構(gòu)造函數(shù)中

2.缺點(diǎn)?:沒缺點(diǎn),完美。其中的if語句檢查的可以是任意一種初始化后應(yīng)該有的方法或者屬性,不必檢查每個屬性和每個方法,只需檢查一個就行。
6.3繼承
? ? ?實(shí)例永遠(yuǎn)指向的是構(gòu)造函數(shù)的原型而不是構(gòu)造函數(shù)
6.3.1原型鏈繼承
? 1.原型鏈:比如一個實(shí)例的原型指的是其構(gòu)造函數(shù)的原型(假定為A),而A也是其他構(gòu)造函數(shù)的實(shí)例(假定為B),這時A的原型指向為B的原型,那假設(shè)B的原型也是其他構(gòu)造函數(shù)的實(shí)例,那么上述關(guān)系依然成立,如此層層遞進(jìn)就形成了原型鏈
?2.例子:下例SuperType的原型指向的是Object的實(shí)例(實(shí)例是對象),Object的實(shí)例的原型為null

? 3.缺點(diǎn):6.23的缺點(diǎn)。
6.3.2借用構(gòu)造函數(shù)繼承

? ?缺點(diǎn):和6.22缺點(diǎn)相同。除此之外,在SuperType的原型上定義的方法或者屬性,SubType的實(shí)例訪問不到,因為它們的原型指向的是SubType的原型。
6.3.3組合繼承
?1.方法:使用原型鏈實(shí)現(xiàn)對原型屬性和方法的繼承,而通過借用構(gòu)造函數(shù)來實(shí)現(xiàn)對實(shí)例的繼承

? 2.缺點(diǎn):無論什么情況下,都會調(diào)用兩次SuperType函數(shù)。一次在創(chuàng)建子類型原型的時候,一次在子類型構(gòu)造函數(shù)內(nèi)部。
6.3.4原型式繼承
? ?方法:使用Object.create()方法。第一個參數(shù)是用作新對象原型的對象,(可選的)第二個參數(shù)是為新對象添加的額外屬性的對象,格式為{name:{value:"wanghao"}}。
? 原理:只傳一個參數(shù)的情況例子如下:

缺點(diǎn):當(dāng)傳入對象的某個屬性值為引用類型(如數(shù)組)的話,只要生成的任意一個實(shí)例添加,刪除,修改該數(shù)組的值,都會在所有實(shí)例中反映出來。因為所有實(shí)例中該數(shù)組的屬性名字只是指向內(nèi)存中該引用類型的一個指針。
6.3.5寄生組合式繼承:將6.3.3組合繼承中的缺點(diǎn)改正了,將創(chuàng)建子類型原型的那一行代碼改成了調(diào)用inheritPrototype函數(shù)。

第七章:函數(shù)表達(dá)式
? ?函數(shù)聲明提升:意思是執(zhí)行代碼之前會優(yōu)先讀取函數(shù)聲明。
7.3:模擬塊級作用域:創(chuàng)建匿名函數(shù)自運(yùn)行;優(yōu)點(diǎn)是避免全局變量過多、造成污染和減少其占用的內(nèi)存問題,因為只要該匿名函數(shù)執(zhí)行完畢,就會銷毀其作用域鏈。
7.4:私有變量:任何在函數(shù)中定義的變量,都可以認(rèn)為是私有變量,因為不能在函數(shù)外部訪問這些變量。我們把有權(quán)訪問私有變量和私有函數(shù)的公有方法稱為特權(quán)方法。有兩種在對象上創(chuàng)建的特權(quán)方法:
? ? 1:構(gòu)造函數(shù)中定義特權(quán)方法

? ?2:原型模式

第八章:BOM
8.1:全局作用域:
? (1)使用var聲明的全局變量不能通過delete刪除,而直接使用window對象上定義的屬性可以刪除。
? (2)嘗試訪問未聲明的變量會跑出錯誤,而通過window對象查詢該屬性,會返回undefined。
8.2:打開新窗口:window.open()方法。該方法可接收4個參數(shù):url地址、窗口目標(biāo)、一個特性字符串以及一個表示新頁面是否取代瀏覽器歷史記錄中當(dāng)前加載頁面的布爾值。通常只需傳第一個參數(shù),最后一個參數(shù)只在不打開新窗口的情況下使用。
8.3:超時調(diào)用和間歇調(diào)用:setInterval和setTimeout;超時調(diào)用的代碼都是在全局作用域中執(zhí)行的,所以其this在嚴(yán)格模式中指向undefined,非嚴(yán)格模式指向window。
8.4:位置操作
(1):location.assign()方法。為其傳遞一個url地址就能打開新url并在歷史記錄中生成一條記錄
(2):location.href="url地址",該方法是調(diào)用(1)方法。
(3):location.replace()方法。為其傳遞一個url地址就能打開新url并不會生成歷史記錄。
(4):location.reload();重新加載當(dāng)前頁面(有可能從緩存中加載)
(5):location.reload();從 服務(wù)器重新加載當(dāng)前頁
(6):history.back():后退一頁。
(7):history.forward():前進(jìn)一頁。
第十三章:事件
? 13.1:
?(1):addEventListener(),removeEventListener();都接收三個參數(shù):要處理的事件名、作為事件處理的函數(shù)和一個布爾值。如果最后這個布爾值為true,表示在捕獲階段調(diào)用函數(shù);如果是false,表示在冒泡階段調(diào)用函數(shù)。還有就是通過addEventListener()添加的匿名函數(shù)是無法移除的。事件名不需要加on:如“click”。
?(2):在IE中對應(yīng)的是attachEvent(),detachEvent();都接收相同的兩個參數(shù):要處理的事件名、作為事件處理的函數(shù);所有事件處理程序都會被添加到冒泡階段執(zhí)行。事件名需要加on:如“onclick”。還有就是事件處理程序是按照相反的添加順序執(zhí)行的(也就是最先添加的最后執(zhí)行)
13.2:移除事件處理程序
? ? ? 當(dāng)使用removeChild()、replaceChild()、innerHTML移除或者替換頁面的某一部分時。如果帶有事件處理程序的元素被替換、刪除掉,那么原來添加到元素中的事件處理程序極有可能無法被當(dāng)作垃圾回收。如下圖;所以最好手工移除事件處理程序,如下圖注釋行。除此之外還可以用事件委托解決該問題,將事件指定給被替換掉部分更高層次的元素上

第十四章:表單腳本
14.1:可以用document.forms["表單名"]來訪問表單,用form.elements[0或者name特性]來訪問表單中的元素。
14.2:可以用element.focus()方法讓某個輸入框自動聚焦(也可以直接給元素加autofocus屬性,不過為了兼容應(yīng)該判斷if(element.autofocus !== true){element.focus});
14.3:可以用size特性來指定input框的顯示字符,用maxlength來指定其可接受的最大字符。在textarea中可以結(jié)合focus事件和select()方法來讓文本域獲得焦點(diǎn)時自動選中所有文本。
第十七章:錯誤處理與調(diào)試
17.1:處理錯誤:try-catch語句。try{//可能導(dǎo)致錯誤的代碼}catch{//在錯誤發(fā)生時怎么處理}當(dāng)try塊中的任何代碼發(fā)生錯誤時,會立即退出代碼執(zhí)行過程,然后執(zhí)行catch塊。此時,catch塊會受到一個包含錯誤信息的對象。不管你是否使用它,也要給它起名字。
17.2:finally字句:不管try和catch解析哪個,finally子句中的代碼塊都會執(zhí)行。
17.3:throw:拋出自定義的錯誤。解析器遇到throw操作符時,代碼會停止執(zhí)行。
第二十章:JSON:是一種輕量級數(shù)據(jù)格式
20.1:語法。JSON語法包含以下三種類型值
? ?1、簡單值:使用與JS相同的語法,可以在JSON中表示字符串、數(shù)值、布爾值和null,但不支持undefined。
? 2、對象:每個鍵值對的值可以是簡單值,可以是復(fù)雜數(shù)據(jù)類型(對象,數(shù)組)。
? 3、數(shù)組:數(shù)組中每個值也可以是任意類型,
JSON不支持變量、函數(shù)或者對象實(shí)例。JSON中字符串必須使用雙引號、屬性名必須加雙引號(單引號會導(dǎo)致語法錯誤)。
20.2:解析與序列化
?1、JSON.stringify():用于把JS對象序列化為JSON字符串。該方法接收三個參數(shù):第一個為序列化的js對象;第二個是個過濾器,該參數(shù)可以是一個數(shù)組,可以是一個函數(shù);第三個參數(shù)是一個選項,表示是否在JSON字符串中保留縮進(jìn)。
? ①當(dāng)過濾器是數(shù)組時:JSON.stringify(obj,["name","age"])返回的是{"name":"wang","age",21}.
? ②當(dāng)過濾器是函數(shù)時:函數(shù)接收兩個參數(shù):鍵名和鍵值。然后在函數(shù)里執(zhí)行相應(yīng)操作(必須有返回值)
? ③第三個參數(shù)可以填數(shù)值或者字符串,最大值為10,所有大于10的值或者字符串都會自動轉(zhuǎn)化為10,如果為數(shù)值則縮進(jìn)對應(yīng)的字符量,如果是字符串則縮進(jìn)改為字符串。
2、JSON.parse():用于把JSON字符串解析為原生JS值。該方法接收2個參數(shù),第一個為JSON對象;第二個同樣是一個函數(shù),該函數(shù)有兩個參數(shù),同樣需要有返回值。如果返回值是undefined則表示刪除相應(yīng)的鍵。
第二十一章:Ajax與Comet
跨域通信
1:CORS(跨域資源共享):http://www.ruanyifeng.com/blog/2016/04/cors.html
2:圖像Ping:與服務(wù)器進(jìn)行簡單、單向的跨域通信的一種方式。請求的數(shù)據(jù)是通過字符串形式發(fā)送的,而響應(yīng)可以是任意內(nèi)容, 但通常是像素圖或204(服務(wù)器成功處理了請求,但不需要返回任何實(shí)體內(nèi)容)響應(yīng)。通過圖像ping,瀏覽器得不到任何具體數(shù)據(jù),但通過load和error事件,能知道響應(yīng)是什么時候接收到的。如下列子中發(fā)送了一個name參數(shù),無論是什么響應(yīng),只要請求完成就能得到通知。缺點(diǎn)是一:只能發(fā)送get請求,二是無法訪問服務(wù)器的文本。因此,圖像ping只能用于瀏覽器與服務(wù)器的單向通信。

3:JSONP:由回調(diào)函數(shù)和數(shù)據(jù)組成,回調(diào)函數(shù)的名字一般是在請求中指定的。而數(shù)據(jù)就是傳入回調(diào)函數(shù)中的JSON數(shù)據(jù)。相比于圖像ping,其優(yōu)點(diǎn)是能夠直接訪問響應(yīng)文本,支持在瀏覽器與服務(wù)器之間的雙向通信。不過JSONP的也有兩點(diǎn)不足:一是其加載的是其他域的代碼,一旦其他域不安全,很可能會夾雜一些惡意代碼,而此時除了放棄JSONP調(diào)用之外,沒有辦法追究。二是?jsonp在調(diào)用失敗的時候不會返回各種HTTP狀態(tài)碼。
4:WebSocket:目標(biāo)是在一個單獨(dú)持久的連接上提供全雙工、雙向通信。其使用的是自定義協(xié)議而不是http協(xié)議。自定義協(xié)議的優(yōu)點(diǎn)是能在客戶端和服務(wù)端發(fā)送非常少量的數(shù)據(jù),很適合移動端。缺點(diǎn)是制定協(xié)議的時間比JS API的時間還要長。

第二十二章:高級技巧
22.1:高級函數(shù)
1:作用域安全的構(gòu)造函數(shù)
如下面例子,第一次undefined是因為Square中的this對象并不是Polygon的實(shí)例,所以會創(chuàng)建并返回一個新實(shí)例,而Square中的this對象并沒有增長得到這個新實(shí)例,所以就沒有sides屬性,其實(shí)例也沒有sides屬性,所以是?undefined。加上光標(biāo)行的注釋之后,就能成功繼承sides屬性打印出2。

2:懶性載入函數(shù)
因為瀏覽器之間行為的差異,所以檢查不同瀏覽器能力的時候會有很多if語句,但是當(dāng)其支持某個功能能力之后,其這個能力會一直存在,以后調(diào)用該函數(shù)時就沒必要再去一一檢查了,如下

3:函數(shù)綁定
如下面例子,第一次打印undefined是因為this指向的是DOM按鈕button,而button并沒有message屬性;第二次是使用閉包直接調(diào)用handleClick方法讓this指向handle;第三次是用bind方法讓其指向handle。而bind是為函數(shù)定義的原生方法,其接收2個參數(shù):第一個為調(diào)用該方法的函數(shù)的執(zhí)行環(huán)境(作用域)。第二個會作為調(diào)用該方法的函數(shù)的第一個參數(shù),也就是下例handleClick函數(shù)的一個參數(shù)。

22.2:防篡改對象
1:不可拓展對象:可以使用Object.preventExtensions(obj)方法將obj對象改為不可拓展?fàn)顟B(tài),也就是說不能在向該方法中的參數(shù)obj對象添加任何屬性和方法;在非嚴(yán)格模式下會添加失敗,而在嚴(yán)格模式下繼續(xù)添加屬性或者方法會報錯。可以修改或者刪除對象中原有的方法或者屬性。使用Object.isExtensible(obj)來判斷對象是否為可拓展?fàn)顟B(tài)。

2:密封的對象:使用Object.seal(obj)來將對象密封,密封以后不能添加任何方法或者屬性,也不能刪除對象中原有的方法及屬性,但是可以修改方法或者屬性。同樣在嚴(yán)格模式下還是會報錯。使用Object.isSealed(obj)來判斷對象是否為密封狀態(tài)。
3:凍結(jié)的對象:使用Object.freeze(obj)來將對象凍結(jié),凍結(jié)以后不能添加,修改,刪除任何方法或者屬性,換句話說,就是該對象本身不可改變。同樣在嚴(yán)格模式下還是會報錯。使用Object.isFrozen(obj)來判斷對象是否為凍結(jié)狀態(tài)。
第二十三章:離線應(yīng)用與數(shù)據(jù)存儲
23.1:cookie的讀取,寫入和刪除。
23.2:web的存儲機(jī)制(即Storage:Storage只能存儲字符串,其他類型在存儲時會被轉(zhuǎn)換成字符串)
? ? ?(1)sessionStroage:可以用length屬性和key()方法迭代sessionStorage中的值

? ? ? ? ? ? ? ? ? 還可以用for-in來迭代sessionStorage中的值

(2)localStroage與上述相同
第二十四章:最佳實(shí)踐
24.1:可維護(hù)性
1、可讀性:下列情況加注釋:①函數(shù)或方法:描述其目的和可能使用的方法。②大段代碼:用于完成單個任務(wù)的多行代碼應(yīng)在前面加注釋。③復(fù)雜的算法:幫助別人或者以后自己的觀看。
2、變量和函數(shù)命名:起語義化的名字,返回布爾值的函數(shù)用is來開頭。
3、變量類型透明:①初始化:當(dāng)定義變量后,用初始化的值來暗示其類型(var num=1;//說明num是數(shù)值類型)。②匈利亞標(biāo)記法:在變量第一個字符加上其類型單詞的首個字母(var Nnum=1)。③加注釋。
4、松散耦合:①解耦HTML/JS:將html文件和JS文件分開,并避免在JS中創(chuàng)建大量HTML;②解耦CSS/JS:避免直接用JS修改元素的樣式,而是去修改元素的樣式類(修改其className);③解耦應(yīng)用邏輯/事件處理程序:一個事件處理程序應(yīng)該從事件對象中提取相關(guān)信息,并將這些信息傳到處理應(yīng)用程序的某個方法中。
5、編程實(shí)踐:①尊重對象所有權(quán):即最好不要修改不是由你創(chuàng)建的對象(document,Array等),可以繼承你想修改的類型然后在實(shí)例中修改。②避免全局量:避免過多的使用全局量,可將這些全局量(變量或函數(shù)名)放在一個對象中創(chuàng)建:var myObj={name:"",sayName:function(){}}③類型檢測避免與null比較:如果值為引用類型,使用instanceof檢查其構(gòu)造函數(shù);如果值為基本類型,使用typeof檢查其類型。
24.2:性能
1、注意作用域:①避免全局查找:如全局變量、函數(shù)、全局對象(如document)等將在一個函數(shù)中引用多次的情況下,將其賦值給一個局部變量來儲存。②避免with語句:因為with會創(chuàng)建自己的作用域,因此會增加其中執(zhí)行代碼的作用域鏈的長度。
2、選擇正確方法:①避免不必要的屬性查找:一旦多次用到對象屬性,應(yīng)將其存儲在局部變量中。②優(yōu)化循環(huán):(1)減值迭代:從最大值開始在循環(huán)中不斷減值的迭代器更高效。(2)簡化終止條件:避免屬性查找或其他O(n)操作。(3)簡化循環(huán)體:確保沒有某些可以被很容易移出循環(huán)的密集計算。(4)使用后測循環(huán),如do-while。③性能的其他注意事項:(1)原生方法較快:原生方法是用諸如C/C++之類的編譯性語言編寫的,如Math對象中的方法絕對比任何用JS寫出來的同樣方法快。(2)switch語句較快:如果有一系列if-else語句,可以將其轉(zhuǎn)化為switch語句。(3)位運(yùn)算符比較快。
3、最小化語句數(shù):①多個變量聲明:盡量用一個var來聲明多個變量,變量間用逗號隔開。②插入迭代值:如var name = value[i];i++; 可以變?yōu)関ar name = values[i++];③使用數(shù)組和對象字面量:即使用[]和{}來創(chuàng)建數(shù)組或?qū)ο?,減少直接用構(gòu)造函數(shù)創(chuàng)建。
4、優(yōu)化DOM交互:①最小化現(xiàn)場更新:即盡量減少createElement()和appendChild()等DOM方法。②使用innerHTML:該方法比使用多個DOM更快(也盡量少用)。③使用時間代理。④注意HTMLCollection:以下情況會返回HTMLCollection對象:(1)對元素進(jìn)行g(shù)etElementByTagName()的調(diào)用。(2)獲取元素的childNodes屬性。(3)獲取元素的attributes屬性。(4)訪問特殊的集合:如document.forms,document.images等。
5、壓縮代碼。