記錄下遺忘的知識點
part2: 在HTML中使用JavaScript
1.所有<script>元素都會按照他們在頁面中出現的先后順序依次被解析(不使用defer和async屬性的情況下)。
- 只有 Internet Explorer 支持 defer 屬性。
2.1. <script src="script.js"></script>
沒有 defer 或 async,瀏覽器會立即加載并執行指定的腳本,“立即”指的是在渲染該 script 標簽之下的文檔元素之前,也就是說不等待后續載入的文檔元素,讀到就加載并執行。
2.2. <script async src="script.js"></script>
有 async,加載和渲染后續文檔元素的過程將和 script.js 的加載與執行并行進行(異步)。
2.3. <script defer src="myscript.js"></script>
有 defer,加載后續文檔元素的過程將和 script.js 的加載并行進行(異步),但是 script.js 的執行要在所有元素解析完成之后,DOMContentLoaded 事件觸發之前完成。
[圖片上傳失敗...(image-407000-1560162831547)]
3.<noscript>:讓頁面平穩退化。
瀏覽器不支持腳本;
瀏覽器支持腳本,但腳本被禁用
Part3 基本概念
- ECMAScript5引入嚴格模式(嚴格模式下,ECMAScript3中的一些不確定的行為將得到處理,而且對某些不安全的操作也會拋出異常)
使用方法:這個腳本頂部添加 'use strict'
- ECMAScript5引入嚴格模式(嚴格模式下,ECMAScript3中的一些不確定的行為將得到處理,而且對某些不安全的操作也會拋出異常)
2.五種簡單數據類型(基本數據類型)
Undefined、Null、Bollean、Number、String
一個復雜數據類型:Object3.undefined(聲明了變量但未加以初始化)
4.null (表示一個空指針)
5.boolean 任何數據類型的值調用Boolean()函數,總會返回一個Boolean值,參照下圖:
6.NaN(非數值是一個特殊的數值)表示一個本來要返回數值的操作數未返回數值的情況。
特殊點:任何涉及NaN的操作都會返回NaN;NaN與任何數值都不想等,包括他本身。
isNaN() :嘗試轉換為數值,不能被轉換為數值的值返回 true。(轉換數值知識點)7.ECMAScript 中的所有參數傳遞的都是值,不可能通過引用傳遞參數。
8.ECMAScript函數不能重載。
Part4 變量作用域和內存問題
1.基本數據類型是按值訪問的,因此可以操作保存在變量中的實際的值。
引用類型的值時按引用訪問的(JavaScript不允許直接訪問內存中的 位置)2.檢測基本數據類型時用 typeof 操作符
檢測引用類型的值時用 instanceof 操作符3.沒有塊級作用域
查詢標識符,從作用域鏈的前端開始,向上逐級查詢與給定名字匹配的標識符。
4.垃圾收集:
標記清除:算法的思想是給當前不使用的值加上標記,然后在回收其內存。
第一階段,標記所有的可訪問對象.第一階段叫做標記階段.
第二階段,垃圾收集算法掃描堆并回收所有的未標記對象.第二階段叫做收集階段.
引用計數:算法是思想是跟蹤記錄所有的值被引用的次數。
引用計數對循環引用的垃圾回收會出現內存泄漏,而IE的DOM回收機制便是采用引用計數的。IE9+把BOM和DOM對象都轉換成真正意義的JavaScript對象。避免兩種垃圾收集算法的并存。5.解除變量的引用不僅有助于消除循環引用現象,而且對垃圾收集也有好處。為了確保有效地回收內存,應該及時解除不在使用的全局對象、全局對象屬性以及循環引用變量的引用。
Part5 引用類型
對象是某個特定引用類型的實例
1.Object類型
創建方式:
① new操作符后跟Object構造函數
②使用對象字面量表示法。
2.Array類型
ECMAScript數組的每一項可以保存任何類型的數據。
創建方式:
①使用Array構造函數 eg: var arr= new Array();
②使用數組字面量表示法 eg: var arr=[1,2,'A'];
數組最多包含4294967295個項
2.1檢測數組
ECMAScript新增 Array.isArray()
2.2轉換方法
toString()
valueOf()
toLocaleString()
調用數組的 toString()方法會返回有數組中每個值的字符串形式拼接而成的一個以逗號分隔的字符串。
調用數組的 valueOf()方法會返回的還是數組。
toLocaleString()不同之處在于,為取到每一項的值,調用的是toLocaleString()方法,而不是toString()方法
join()方法可以使用不同的分隔符來構建這個字符串。 如, || *
2.3棧方法(后進先出)
push() 可以接收任意數量的參數,把他們逐個添加到數組末尾。并返回修改后數組的長度。
pop() 從數組末尾移除最后一項,減少數組的length值,返回移除的項。
2.4隊列方法(先進先出)
shift() 移除數組中的第一個項并返回該項,同時將數組長度減一。
unshift()在數組前端添加任意個項并返回新數組的長度。
2.5重排序方法
reverse() 翻轉數組項的順序
sort() 方法時按升序排列數組項(調動數組項的toString()轉型方法,比較字符串。)
arrayObject.sort(sortby)
sortby 可選。規定排序順序。必須是函數。
給數值型數組排序時,可以定義排序函數
var arr = [12,5,8,40];
function sortNumber(a,b){
return a - b // return b-a 為降序排列
}
arr.sort(sortNumber);
或者 復雜點
var arr = [12,5,8,40];
function compare(value1, value2) {
if (value1 < value2) {
return -1;
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
}
arr.sort(compare);
2.6操作方法
concat()
創建當前數組的一個副本,將接收到的參數添加到這個副本的末尾,最后返回新構建的數組,
slice()
arrayObject.slice(start,end)
start 必需。規定從何處開始選取。如果是負數,那么它規定從數組尾部開始算起的位置。也就是說,-1 指最后一個元素,-2 指倒數第二個元素,以此類推。
end 可選。規定從何處結束選取。該參數是數組片斷結束處的數組下標。如果沒有指定該參數,那么切分的數組包含從 start 到數組結束的所有元素。如果這個參數是負數,那么它規定的是從數組尾部開始算起的元素。
splice() 方法向/從數組中添加/刪除項目,然后返回被刪除的項目。
arrayObject.splice(index,howmany,item1,.....,itemX)
index 必需。整數,規定添加/刪除項目的位置,使用負數可從數組結尾處規定位置。
howmany 必需。要刪除的項目數量。如果設置為 0,則不會刪除項目。
item1, ..., itemX 可選。向數組添加的新項目。
2.7位置方法
indexOf() 方法可返回某個指定的字符串值在字符串中首次出現的位置。
lastIndexOf() 方法可返回一個指定的字符串值最后出現的位置,在一個字符串中的指定位置從后向前搜索。
2.8迭代方法
map()是對數組中的每一項運行給定函數,返回每次函數調用的結果組成的數組。這個數組的每一項都是在原始數據中的對應項上運行傳入函數的結果
filter()是對數組中的每一項運行給定函數,返回該函數會返回true的項所組成的數組。它利用指定的函數確定是否在返回的數組中包含某一項
every()是對數組中的每一項運行給定函數,如果該函數對每一項都返回true,則返回true。
some()是對數組中的每一項運行給定函數,如果該函數對任一項返回true,則返回true。
forEach() 是多數組中的每一項運行給定函數,這個方法沒有返回值。它只是對數組中的每一項運行傳入的函數,沒有返回值。本質上與使用for循環迭代數組一樣。
2.9縮小方法
reduce() reduceRight()
迭代數組的所有項,然后構建一個最終返回的值。
3.Date類型
4.RegExp類型
5.Function類型
函數是對象,函數名是指針。
5.1 沒有重載(兩個同名函數,后面的會覆蓋前面的函數)
5.2 函數聲明與函數表達式
解析器會率先讀取函數聲明,并使其在執行任何代碼前可用,
函數表達式,會在解析器執行到它所在是代碼行,才會真正被解釋執行。
5.3作為值的函數
5.4函數內部屬性
特殊對象:arguments 和 this
用例:階乘
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num - 1);
}
}
5.5函數屬性和方法
每個函數都包含兩個屬性 length 和 prototype
length 表示函數希望接受的命名參數的個數。
prototype是保存他們所有實例方法的真實所在。
6基本包裝類型
引用類型與基本包裝類型的主要區別就是對象的生存期。
基本包裝類型,也是一種引用類型。基本包裝類型是對基本數據類型的封裝,封裝后即具有基本類型的功能,也有各自的特殊行為(方法)
基本包裝類型需要一個new來創建。請看下面的例子:
1.字面量寫法:var box = 'Mr. Lee';//字面量
box.name = 'Lee';//無效屬性
box.age = function () {//無效方法
return 100;
};
alert(box);//Mr. Lee
alert(box.substring(2));//. Lee
alert(typeof box);//string
alert(box.name);//undefined
alert(box.age());//錯誤
2.new 運算符寫法:var box = new String('Mr. Lee');//new 運算符
box.name = 'Lee';//有效屬性
box.age = function () {//有效方法
return 100;
};
alert(box);//Mr. Lee
alert(box.substring(2));//. Lee
alert(typeof box);//object
alert(box.name);//Lee
alert(box.age());//100
6.1Boolean類型
6.2Number類型
6.3String類型
7.單體內置對象
Global對象
Math對象
Part6 面向對象的程序設計
ECMAScript中有兩種屬性:數據屬性和訪問器屬性。
1.數據屬性:
數據屬性包含一個數據值的位置。在這個位置可以讀取和寫入值。數據屬性有4個描述其行為的特性。
[[Configureable]]:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性。默認值是true。
[[Enumerable]]:表示能否通過for-in 循環返回屬性。默認值是true。
[[Writable]]:表示能否修改屬性的值。默認值是true。
[[Value]]:包含這個屬性的數據值。讀取屬性值的時候,從這個位置讀;寫入屬性值的時候,把新值保存在這個位置。這個特性的默認值為undefined。
2.訪問器屬性
訪問器屬性不包含數據值;它們包含一對兒getter和setter函數。
[[Configurable]]:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為數據屬性。默認值是true。
[[Enumerable]]:表示能否通過for-in 循環返回屬性。默認值是true。
[[Get]]:在讀取屬性時調用的函數。默認值為undefined。
[[Set]]:在寫入屬性時調用的函數。默認值為undefined。
Object.defineProperty()
Object.defineProperties()
讀取屬性的特性:Object.getOwnPropertyDescriptor()
6.2創建對象
6.2.1工廠模式
function createPerson(name, age, job) {
let o = new Object()
o.name = name
o.age = age
o.job = job
o.sayName = function () {
console.log(this.name)
}
return o
}
let person = createPerson('AA', 29, 'engineer')
let person2 = createPerson('BB', 28, 'doctor')
6.2.2構造函數模式
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
this.sayName = function () {
console.log(this.name)
}
}
let person = new Person('AA', 29, 'engineer')
let person2 = new Person('BB', 28, 'doctor')
console.log(person)
console.log(person2)
與工廠模式不同之處:
- 沒有顯式地創建對象
- 直接將屬性和方法賦給了this對象
- 沒有return語句
缺點:
每個方法都要在每個實例上重新創建一遍。
6.2.3原型模式
function Person() {
}
Person.prototype.name= 'AA'
Person.prototype.age= 29
Person.prototype.job= 'engineer'
Person.prototype.sayName = function(){
console.log(this.name)
}
console.log(Object.getOwnPropertyNames(Person.prototype)) // ["constructor", "name", "age", "job", "sayName"]
let person = new Person()
let person2 = new Person()
console.log(person.hasOwnProperty('name')) // false
console.log('name' in person) // true
person.name= 'CC'
console.log(person.hasOwnProperty('name')) // true
console.log('name' in person) // true
delete person.name
console.log(person.hasOwnProperty('name')) // false
console.log('name' in person) // true
使用hasOwnProperty() 可以檢查訪問的是實例屬性還是原型屬性。
使用 in 操作符只要通過對象能訪問到屬性就返回true
- 原型模式缺點:
原型中所有屬性是被很多實例共享的,這種共享對于函數非常合適,但是對于包含引用類型值的屬性來說,就存在問題了。
6.2.4 組合使用構造函數模式與原型模式
function Person(name,age,job) {
this.name = name
this.age = age
this.job = job
this.friends =['A','B']
}
Person.prototype = {
constructor:Person,
sayName :function(){
console.log(this.name)
}
}
let person = new Person('AA',29,'engineer')
let person2 = new Person('BB',28,'doctor')
person.friends.push('C')
console.log(person.friends)
console.log(person2.friends)
console.log(person.sayName === person2.sayName)
6.2.5 動態原型模式
6.2.6寄生構造函數模式
6.2.7穩妥構造函數模式
6.3 繼承
接口繼承:只繼承方法簽名
實現繼承:繼承實際的方法
由于函數沒有簽名,在ECMAScript中無法實現接口繼承,只支持實現繼承,而且其實現繼承主要是依靠原型鏈來實現的。
6.3.1 原型鏈
問題:
1.來自包含引用類型值的原型
2.沒有辦法在不影響所有對象實例的情況下,給超類型的構造函數傳遞參數。
6.3.2 借用構造函數
6.3.3 組合繼承
6.3.4 原型式繼承
6.3.5 寄生式繼承
6.3.6 寄生組合式繼承
Part7 函數表達式
- 1.遞歸:是在一個函數通過名字調用自身的情況下構成的
- 2.閉包:是指有權訪問另一個函數作用域中的變量的函數
Part8 BOM
1.BOM的核心對象是window,他表示瀏覽器的一個實例。
2.全局變量 不能通過delete操作符刪除,而直接在window對象上的定義的屬性可以。
- JavaScript是單線程語言,但他允許通過設置超時值和間歇時間值來調度代碼在特定的時刻執行。
超時調用: setTimeout();
間歇調用: setInterval();
- JavaScript是單線程語言,但他允許通過設置超時值和間歇時間值來調度代碼在特定的時刻執行。
4.系統對話框
alert()
confirm()
prompt()
Part9 客戶端檢測
- 1.客戶端檢測是JavaScript開發中最具爭議的一個話題。經常使用:
能力檢測:在編寫代碼之前先檢測特定瀏覽器的能力。
怪癖檢測:實際上是瀏覽器實現中存在的bug。(無法精確檢測特定的瀏覽器和版本)
用戶代理檢測:通過檢測用戶代理字符串來識別瀏覽器。(萬不得已才使用)
Part10 DOM
- 最基本的節點類型時Node,用于抽象地表示文檔中一個獨立的部分,所有其他類型都繼承自Node
*jQuery 的核心就是通過CSS選擇符查詢DOM文檔取得元素的引用。從而拋開了getElementById()和getElementByTagName()
Part13
- 1.事件流描述的是從頁面中接收事件的順序。
- 2.IE的事件流叫做事件冒泡。(所有現代瀏覽器都支持事件冒泡)
- 3.事件捕獲。相反,document對象首先接收到click事件,然后事件沿著DOM書依次向下。直到事件的實際目標。
- 4.DOM事件流。包括三個階段:事件捕獲階段、處于目標階段和事件冒泡階段。
- 5.事件處理程序:
HTML事件處理程序
DOM0級事件處理程序
DOM2級事件處理程序
IE級事件處理程序
跨瀏覽器的事件處理程序 - 6.建立在事件冒泡機制智商的事件委托技術,可以有效的減少事件處理程序的數量。
- 7.建議在瀏覽器卸載頁面之前移除頁面中的所有事件處理程序。
Part23 客戶端存儲
- cookie 的限制使其可以存儲少量的數據。
- Web Storage定義了兩種存儲數據的對象,sessionStorage 和localStorage
前者嚴格用于在一個瀏覽器會話中存儲數據,因為數據在瀏覽器關閉后會立即刪除。
后者用于跨會話持久化數據并遵循跨域安全策略。 - IndexedDB是一種類似SQL數據庫的結構化數據存儲機制。但他的數據不是保存在表中,而是保存在對象存儲空間中。
Part25 新興API
- requestAnimationFrame(): 優化JS動畫API,能夠在動畫運行期間發出信號,是瀏覽器能都自動優化屏幕重繪操作
- Page VIsibility API : 讓開發者知道用戶什么時候正在看著頁面,而什么時候頁面是隱藏的。
- Geolocation API : 在得到許可的情況下,可以確定用戶所在的位置。
- File API :可以讀取文件內容。用于顯示、處理、上傳。
- Web計時: 給出頁面加載和渲染過程的很多信息。對性能優化非常有價值。
- Web Workers :可以運行異步JavaScript代碼,避免阻塞用戶界面。