一、JavaScript高級第一天
1.JavaScript基礎(chǔ)知識復(fù)習(xí)
JavaScript的基本組成
* ECMAScript 語法規(guī)范
* DOM 操作dom元素的api
* BOM 操作瀏覽器對象的api
JavaScript數(shù)據(jù)類型
簡單數(shù)據(jù)類型
* string
* number
* boolean
* undefined
復(fù)雜數(shù)據(jù)類型
* Object
* Array
* Date
* RegExp
* Function
* String
* Number
* Boolean
* null
* Math
部分關(guān)鍵字的使用
* in
- 判斷屬性是否存在于對象中
- for in 遍歷對象的 鍵
* typeof 判斷對象的類型 返回值是string類型的 引用類型中扣泊,除了function其他的對象都是object類型
* delete
- 刪除對象的屬性
- 刪除未使用var聲明的變量
- 返回值為boolean 表示是否刪除成功
- 注意:刪除的屬性如果不存在近范,返回true
- 刪除的如果是原型中的屬性,返回true 但是刪除不成功
* break continue
- break 用來終止循環(huán)
- continue 用來跳出當(dāng)前循環(huán)延蟹,繼續(xù)下次循環(huán)
* === 和 ==
- === 要判斷數(shù)據(jù)類型和值是否相等
- == 值判斷值是否相等
* || 和 &&
- 表達(dá)式1 || 表達(dá)式2 如果 表達(dá)式1 就 返回 表達(dá)式1 否則 返回 表達(dá)式2
- 表達(dá)式1 && 表達(dá)式2 如果 表達(dá)式1 就 返回 表達(dá)式2 否則 返回 表達(dá)式1
值類型和引用類型
* 值類型: 存儲的是數(shù)據(jù)本身的值就是值類型的數(shù)據(jù)
* 引用類型:存儲的是數(shù)據(jù)的地址的值就是引用類型的數(shù)據(jù)评矩,數(shù)據(jù)自己在內(nèi)存中單獨存儲
* 值類型的賦值:直接將存儲的數(shù)據(jù)復(fù)制一份賦值給新的變量 兩個變量獨立存在互不影響
* 引用類型賦值:將存儲的數(shù)據(jù)的地址復(fù)制一份賦值給新的額便令 兩個變量指向同一個對象,相互影響
異常處理
* 異常的最大的特征:一旦發(fā)生異常阱飘,后面的代碼都不會再執(zhí)行
* 異常處理語句 try catch finally
```js
try{
//可能出現(xiàn)異常的代碼
}
catch(e){
//e就是出現(xiàn)異常的異常信息
//出現(xiàn)異常后的處理代碼
}
finally{
//不管有沒有出現(xiàn)異常斥杜,都會執(zhí)行的代碼
//一般用來釋放資源
}
```
* 如何手動拋出異常: throw 任何東西, catch中會抓到該東西
2.面向?qū)ο蟮幕窘榻B
面向?qū)ο笫鞘裁?
面向?qū)ο笫且环N思維方式.
是將解決問題的關(guān)注點放到解決問題所需要的一些列對象上沥匈。
面向過程是什么蔗喂?
面向過程是一種思維方式.
是將解決問題的關(guān)注點放到解決問題的詳細(xì)的步驟上。
面向過程和面向?qū)ο蟮年P(guān)系
面向?qū)ο笫菍γ嫦蜻^程的封裝8牢酢H鹾恪!
什么是對象棋恼?
萬物皆對象
JavaScript中什么是對象
無序鍵值對兒的集合就是
二返弹、JavaScript高級第二天
1.面向?qū)ο蟮娜筇匦?/h3>
* 封裝
* 繼承
自己沒有的,拿別人過來用爪飘,就是繼承
* 多態(tài)
父類引用指向子類的對象(JavaScript中用不到)
2.創(chuàng)建對象的四種方式
a. 使用字面量創(chuàng)建對象
```js
var o = {key:value, key:value...}
```
用一個創(chuàng)建一個义起,不能復(fù)用,造成代碼冗余师崎,資源浪費
b. 使用內(nèi)置構(gòu)造函數(shù)創(chuàng)建對象
```js
var o = new Object();
var o = new Array();
```
創(chuàng)建出來的對象都是空的對象默终,要手動的去為對象添加屬性。造成代碼重復(fù)
c. 封裝簡單的工廠函數(shù)(不推薦使用)
```js
function createObj(){
var obj = {};
obj.xx=xxx;
return obj;
}
```
d. 自定義構(gòu)造函數(shù)
```
function 構(gòu)造函數(shù)名{
this.xxx=xxx;
//....
}
```
0.構(gòu)造函數(shù)名首字母要大寫
1.構(gòu)造函數(shù)一般和new關(guān)鍵字一起使用
2.構(gòu)造函數(shù)返回值默認(rèn)為新創(chuàng)建好對象 如果手動返回基本數(shù)據(jù)類型犁罩,不影響默認(rèn)返回值齐蔽,如果返回的是對象,那么新創(chuàng)建出來的對象將不會返回床估,取而代之的是return后面的對象
構(gòu)造函數(shù)(constructor)的執(zhí)行步驟
1.使用new關(guān)鍵字創(chuàng)建對象
2.調(diào)用構(gòu)造函數(shù)含滴,將new創(chuàng)建出來的對象賦值給構(gòu)造函數(shù)內(nèi)的this
3.使用this給新創(chuàng)建出來的對象增加成員
4.默認(rèn)返回新創(chuàng)建出來的這個對象
3.原型
構(gòu)造函數(shù)存在問題
構(gòu)造函數(shù)中的方法,每新創(chuàng)建一個對象的時候丐巫,該對象都會重新的創(chuàng)建一次這個方法谈况,每個獨享獨占一個方法
但是該方法內(nèi)容完全相同勺美,所以造成資源浪費
1.解決辦法1
將構(gòu)造函數(shù)內(nèi)的方法,進(jìn)行提取碑韵,放在構(gòu)造函數(shù)外面赡茸,在構(gòu)造函數(shù)內(nèi)部進(jìn)行引用賦值
那么創(chuàng)建出來的對象,都會指向構(gòu)造函數(shù)外面的這個函數(shù)祝闻,達(dá)到共享的目的
問題:全局變量增多占卧,造成全局變量污染,代碼結(jié)構(gòu)混亂联喘,不容易維護(hù)
2.解決辦法2
使用原型
4.原型
原型是什么屉栓?
在構(gòu)造函數(shù)創(chuàng)建出來的時候,系統(tǒng)會默認(rèn)的創(chuàng)建并關(guān)聯(lián)一個對象耸袜,這個對象就是原型,原型對象默認(rèn)是空對象
默認(rèn)的原型對象中會有一個屬性constructor指向該構(gòu)造函數(shù)
原型的作用
原型對象中的成員牲平,可以被使用和它關(guān)聯(lián)的構(gòu)造函數(shù)創(chuàng)建出來的所有對象共享
原型對象的使用
1. 使用對象的動態(tài)特性堤框,為原型對象添加成員
2. 直接替換原型對象
注意事項:
直接替換原型對象,會導(dǎo)致替換之前創(chuàng)建的對象的原型和替換之后創(chuàng)建的對象的原型不一致
原型的使用該注意事項
1.使用對象訪問屬性的時候纵柿,會現(xiàn)在對象中查找蜈抓,如果找到了就直接使用
如果沒有找到,就去原型中查找
2.使用對象設(shè)置屬性的時候昂儒,只會在對象本身中查找沟使,不會去原型中查找,如果在對象本身中沒有找到這個屬性
則給該對象新增一個屬性渊跋,如果在對象中有這個屬性,修改這個屬性
3.如果在原型對象中有引用類型的屬性,那么使用對象進(jìn)行修改該屬性內(nèi)容寺旺,則其他所有跟這個原型對象相關(guān)的對象都會受到影響
Person.prototype.car = {};
var p = new Person( );
p.car = {}; //這是修改屬性
p.car.brand= ""; //這是修改屬性的內(nèi)容
4.一般情況下不會將屬性添加到原型對象中
只會將需要共享的方法男窟,添加到原型對象中
proto
1.這個屬性不是標(biāo)準(zhǔn)屬性,所以存在通用性問題
2.一般不推薦使用這個屬性
3.調(diào)試的時候蒿囤,可以使用這個屬性
4.這個屬性是原型中的屬性
* 封裝
* 繼承
自己沒有的,拿別人過來用爪飘,就是繼承
* 多態(tài)
父類引用指向子類的對象(JavaScript中用不到)
a. 使用字面量創(chuàng)建對象
```js
var o = {key:value, key:value...}
```
用一個創(chuàng)建一個义起,不能復(fù)用,造成代碼冗余师崎,資源浪費
b. 使用內(nèi)置構(gòu)造函數(shù)創(chuàng)建對象
```js
var o = new Object();
var o = new Array();
```
創(chuàng)建出來的對象都是空的對象默终,要手動的去為對象添加屬性。造成代碼重復(fù)
c. 封裝簡單的工廠函數(shù)(不推薦使用)
```js
function createObj(){
var obj = {};
obj.xx=xxx;
return obj;
}
```
d. 自定義構(gòu)造函數(shù)
```
function 構(gòu)造函數(shù)名{
this.xxx=xxx;
//....
}
```
0.構(gòu)造函數(shù)名首字母要大寫
1.構(gòu)造函數(shù)一般和new關(guān)鍵字一起使用
2.構(gòu)造函數(shù)返回值默認(rèn)為新創(chuàng)建好對象 如果手動返回基本數(shù)據(jù)類型犁罩,不影響默認(rèn)返回值齐蔽,如果返回的是對象,那么新創(chuàng)建出來的對象將不會返回床估,取而代之的是return后面的對象
構(gòu)造函數(shù)(constructor)的執(zhí)行步驟
1.使用new關(guān)鍵字創(chuàng)建對象
2.調(diào)用構(gòu)造函數(shù)含滴,將new創(chuàng)建出來的對象賦值給構(gòu)造函數(shù)內(nèi)的this
3.使用this給新創(chuàng)建出來的對象增加成員
4.默認(rèn)返回新創(chuàng)建出來的這個對象
構(gòu)造函數(shù)中的方法,每新創(chuàng)建一個對象的時候丐巫,該對象都會重新的創(chuàng)建一次這個方法谈况,每個獨享獨占一個方法
但是該方法內(nèi)容完全相同勺美,所以造成資源浪費
1.解決辦法1
將構(gòu)造函數(shù)內(nèi)的方法,進(jìn)行提取碑韵,放在構(gòu)造函數(shù)外面赡茸,在構(gòu)造函數(shù)內(nèi)部進(jìn)行引用賦值
那么創(chuàng)建出來的對象,都會指向構(gòu)造函數(shù)外面的這個函數(shù)祝闻,達(dá)到共享的目的
問題:全局變量增多占卧,造成全局變量污染,代碼結(jié)構(gòu)混亂联喘,不容易維護(hù)
2.解決辦法2
使用原型
在構(gòu)造函數(shù)創(chuàng)建出來的時候,系統(tǒng)會默認(rèn)的創(chuàng)建并關(guān)聯(lián)一個對象耸袜,這個對象就是原型,原型對象默認(rèn)是空對象
默認(rèn)的原型對象中會有一個屬性constructor指向該構(gòu)造函數(shù)
原型對象中的成員牲平,可以被使用和它關(guān)聯(lián)的構(gòu)造函數(shù)創(chuàng)建出來的所有對象共享
1. 使用對象的動態(tài)特性堤框,為原型對象添加成員
2. 直接替換原型對象
注意事項:
直接替換原型對象,會導(dǎo)致替換之前創(chuàng)建的對象的原型和替換之后創(chuàng)建的對象的原型不一致
1.使用對象訪問屬性的時候纵柿,會現(xiàn)在對象中查找蜈抓,如果找到了就直接使用
如果沒有找到,就去原型中查找
2.使用對象設(shè)置屬性的時候昂儒,只會在對象本身中查找沟使,不會去原型中查找,如果在對象本身中沒有找到這個屬性
則給該對象新增一個屬性渊跋,如果在對象中有這個屬性,修改這個屬性
3.如果在原型對象中有引用類型的屬性,那么使用對象進(jìn)行修改該屬性內(nèi)容寺旺,則其他所有跟這個原型對象相關(guān)的對象都會受到影響
Person.prototype.car = {};
var p = new Person( );
p.car = {}; //這是修改屬性
p.car.brand= ""; //這是修改屬性的內(nèi)容
4.一般情況下不會將屬性添加到原型對象中
只會將需要共享的方法男窟,添加到原型對象中
1.這個屬性不是標(biāo)準(zhǔn)屬性,所以存在通用性問題
2.一般不推薦使用這個屬性
3.調(diào)試的時候蒿囤,可以使用這個屬性
4.這個屬性是原型中的屬性
替換原型時候的注意事項:
在新替換的原型中客们,沒有constructor屬性,會影響三角結(jié)構(gòu)關(guān)系的合理性
so材诽,在新替換的原型中底挫,手動添加constructor屬性,以保證關(guān)系的合理性脸侥,賦值為關(guān)聯(lián)的構(gòu)造函數(shù)
三建邓、JavaScript 高級第三天
1.繼承
混入式繼承
for in
使用for in遍歷對象1的屬性,將所有的屬性添加到另外一個對象2上
這時候就可以稱 對象2 繼承自 對象1
原型繼承
* 利用對象的動態(tài)特性湿痢,為原型對象添加成員
* 直接替換原型對象
1.替換前的對象涝缝,在替換之后扑庞,所有的成員都丟失
2.替換原型對象的時候,需要手動去指定原型對象的construtor屬性
* 利用混入給原型對象添加成員
經(jīng)典繼承
var 對象1 = Object.create(對象2);
這個時候拒逮,創(chuàng)建出來的對象1繼承自對象2
Object.create方法存在兼容性問題
如何解決罐氨?
1.檢測瀏覽器是否支持Object.create方法,如果不支持滩援,直接手動給Object添加create方法
2.自定義函數(shù)栅隐,在函數(shù)內(nèi)部判斷瀏覽器是否支持Object.create方法,如果不支持玩徊,則手動創(chuàng)建對象返回租悄,否則直接調(diào)用
function create(obj){
if(Object.create){
return Object.create(obj);
}else{
function F(){
}
F.prototype = obj;
return new F();
}
}
2.原型鏈
什么是原型鏈
每個構(gòu)造函數(shù)都有原型對象,每個對象都有構(gòu)造函數(shù)恩袱,每個構(gòu)造函數(shù)的原型對象都是對象泣棋,也就有構(gòu)造函數(shù)
然后就形成一個鏈?zhǔn)降慕Y(jié)構(gòu),我們稱之為原型鏈
原型繼承是什么畔塔?
通過修改原型鏈的結(jié)構(gòu)潭辈,實現(xiàn)繼承的方式就是原型繼承
對象和原型的成員關(guān)系
function Person(){};
var p = new Person();
p對象中包含的成員有:Person.prototype中的成員和自身擁有成員
Person.prototype中的成員有:Object.prototype的成員和自身的成員
p對象可以訪問Person.prototype和Object.prototype中的所有成員
Object.prototype的成員
- constructor :指向和該原型相關(guān)的構(gòu)造函數(shù)
- hasOwnProperty 方法: 判斷對象本身是否擁有某個屬性
- properIsEnumerable 方法: 1.判斷屬性是否屬于對象本身,2.判斷屬性是否可以被遍歷
- toString toLocaleString: 將對象轉(zhuǎn)換成字符串 toLocalString轉(zhuǎn)換成字符串的時候應(yīng)用的本地的設(shè)置格式
- valueOf 方法:在對象參與運算的時候澈吨,首先調(diào)用valueOf方法獲取對象的值把敢,如果該值無法參與運算,將會調(diào)用toString方法
- _ proto_ 屬性: 指向當(dāng)前對象的原型對象
3.Function
Function可以初始化一個構(gòu)造函數(shù),用來初始化函數(shù)對象
3種創(chuàng)建函數(shù)的方式
* 直接聲明函數(shù)
* 函數(shù)表達(dá)式
* new Function()
可以用Function來創(chuàng)建函數(shù):
語法:
var 函數(shù)名 = new Function(); //創(chuàng)建一個空的函數(shù)
var 函數(shù)名 = new Function("函數(shù)體") //創(chuàng)建一個沒有參數(shù)的函數(shù)
var 函數(shù)名 = new Function("參數(shù)1","參數(shù)2", "參數(shù)3",..."函數(shù)體")
//當(dāng)給Fucntion傳多個參數(shù)的時候谅辣,最后一個參數(shù)為函數(shù)體修赞,前面的參數(shù)為創(chuàng)建出來的函數(shù)的形參
//Function接收的所有的參數(shù)都是字符串類型的!I=住柏副!
4.arguments對象
arguments對象是函數(shù)內(nèi)部的一個對象,在函數(shù)調(diào)用的時候蚣录,系統(tǒng)會默認(rèn)的將所有傳入的實參存入該對象
注意:不管有沒有形參搓扯,實參都會被存入該對象
arguments.callee調(diào)用函數(shù)本身
5.eval
可以將字符串轉(zhuǎn)換成js代碼并執(zhí)行
注意:當(dāng)使用eval解析JSON格式字符串的時候,要注意包归,會將{}解析為代碼段
1.可以在JSON格式字符串前面拼接 "var 變量名 ="
eval("var 變量名 =" + JSON格式的字符串);
2.可以在JSON格式字符串前后拼接()
eval("("+JSON格式的字符串+")")
6.靜態(tài)成員和實例成員
靜態(tài)成員
通過構(gòu)造函數(shù)去訪問的屬性和方法就是靜態(tài)成員
實例成員
通過對象(實例)去訪問的屬性和方法就是實例成員
7.Function和eval比較
相同點 都可以將字符串轉(zhuǎn)為js代碼
不同點 Function創(chuàng)建出來的是函數(shù)锨推,并不會直接調(diào)用,只有手動調(diào)用函數(shù)才會執(zhí)行公壤。而eval把字符串轉(zhuǎn)為代碼后直接執(zhí)行
四换可、JavaScript高級第四天
原型相關(guān)知識復(fù)習(xí)
1.原型鏈
2.函數(shù)的原型鏈
可以把Funciton當(dāng)做一個構(gòu)造函數(shù),其他構(gòu)造函數(shù)都是這個Function構(gòu)造函數(shù)的實例
再用對象原型鏈的方式厦幅,去分析這個原型關(guān)系
3.instansof
判斷一個構(gòu)造函數(shù)的原型是不是存在于該對象的原型鏈上
javascript中所有的對象 都會有 Object.prototype
所以 所有的對象 instanceof Object 都是true
歌曲列表管理案例
遞歸
自己調(diào)用自己
化歸思想
化繁為簡沾鳄,化未知為已知
遞歸的兩個要素
1.自己調(diào)用自己
2.有遞歸結(jié)束條件
五、JavaScript高級第五天
使用遞歸獲取后代元素
1.作用域
什么是作用域
變量起作用的范圍
1 設(shè)置值的時候确憨,也是訪問變量
2. 獲取值的時候译荞,是訪問變量
3.并不是在函數(shù)內(nèi)部寫了變量瓤的,這個變量就屬于這個函數(shù)的作用域, 而是必須使用var來聲明變量吞歼,這個變量才會屬于這個作用域
什么是塊級作用域
JS中沒有塊級作用域圈膏,使用代碼塊限定的作用域就是塊級作用域
JS中的作用域叫做 詞法作用域
詞法作用域
在代碼寫好的時候,就能確定變量的作用域篙骡,這種作用域就是詞法作用域
動態(tài)作用域.(是詞法作用域就不可能是動態(tài)作用域)
在js當(dāng)中稽坤,只有函數(shù)能創(chuàng)造作用域
var num = 123;
function f1(){
console.log(num); //如果是動態(tài)作用域打印的就是456 如果是詞法作用域 打印123
}
function f2(){
var num = 456;
f1();
}
f2();
變量提升
JS代碼的運行分兩個階段
* 預(yù)解析階段
* 變量名和函數(shù)提升
將var聲明的變量名和function開頭的函數(shù)進(jìn)行提升
提升到當(dāng)前作用域的最上方
* 執(zhí)行階段
注意:
1.變量和函數(shù)同名的時候
只提升函數(shù),忽略變量名
2.函數(shù)同名的時候
都提升糯俗,但是后面的函數(shù)會覆蓋前面的函數(shù)
3.函數(shù)表達(dá)式尿褪,只會提升變量名,不會提后面的函數(shù)
4.變量提升只會將變量和函數(shù)提升到當(dāng)前作用域的最上方
```js
funciton foo(){
var num =123;
}
```
5.變量提升是分塊 <script> 的
```html
<script>
foo()
function foo(){
console.log("第一個script標(biāo)簽內(nèi)的函數(shù)")
};
</script>
<script>
foo()
function foo(){
console.log("第2個script標(biāo)簽內(nèi)的函數(shù)")
}
</script>
```
6.條件式函數(shù)聲明 能否被提升得湘,取決于瀏覽器杖玲, 不推薦使用!L哉天揖!
```
foo();//會報錯,因為未被提升
if(true){
function foo(){
}
}
```
2.作用域鏈
只要是函數(shù)都有作用域跪帝,函數(shù)內(nèi)部的作用域可以訪問函數(shù)外部的作用域
當(dāng)多個函數(shù)嵌套的時候,就會形成一個鏈?zhǔn)降慕Y(jié)構(gòu)些阅,這個就是作用域鏈
繪制作用域鏈圖的步驟
1.先繪制0級作用域鏈
2.在全局作用域中查找伞剑,變量和函數(shù)的聲明,找到之后市埋,將所有的變量和函數(shù)用小方格放在0級作用域鏈上
3.再從0級作用域鏈上的函數(shù)引出1級作用域鏈
4.再去每一個1級作用域鏈中查找變量和函數(shù)的聲明黎泣,找到之后.....
5.以此重復(fù),就畫好了整個作用域鏈
變量的搜索規(guī)則
1.首先在訪問變量的作用域中查找該變量缤谎,如果找到直接使用
2.如果沒有找到抒倚,去上一級作用域中繼續(xù)查找,如果如果找到直接使用
3.如果沒有找到坷澡,繼續(xù)去上一級作用域中繼續(xù)查找托呕,直到全局作用域
4.如果找到了就用,如果沒有直到就報錯
3.閉包
閉包是什么
一個封閉的對外不公開的包裹結(jié)構(gòu)或空間
js中的閉包是函數(shù)
閉包要解決的問題
1频敛、在函數(shù)外部訪問不到函數(shù)內(nèi)部的數(shù)據(jù)
2项郊、要解決的問題就是需要在外部間接的訪問函數(shù)內(nèi)部的數(shù)據(jù)
閉包的基本結(jié)構(gòu)
function outer(){
var data = "數(shù)據(jù)";
return function(){
return data;
}
}
function outer(){
var data = "數(shù)據(jù)";
var data1 = "數(shù)據(jù)1";
return {
getData:function(){
return data;
},
getData1:function(){
return data1;
}
}
}
function outer(){
var data = "數(shù)據(jù)";
return {
getData:function(){
return data;
},
setData:function(value){
data = value;
return data;
}
}
}
4.閉包的作用
如果把數(shù)據(jù)放在全局作用域內(nèi),那么所有人都可以隨意修改斟赚,這個數(shù)據(jù)就不再可靠着降。
閉包可以創(chuàng)建一個私有空間,在這個空間內(nèi)部的數(shù)據(jù)拗军,外部無法直接訪問
外部空間想要訪問函數(shù)內(nèi)部的數(shù)據(jù)任洞,只能通過閉包提供的指定的方法蓄喇,在這個方法內(nèi)部
可以設(shè)置一些校驗規(guī)則,讓數(shù)據(jù)變得更加的安全交掏。
六妆偏、JavaScript高級第六天
1.閉包練習(xí)
setTimeout的執(zhí)行時機(jī)
所有的主任務(wù)的代碼執(zhí)行完畢之后,去檢查所有的setTimeout回調(diào)函數(shù)耀销,如果到時間了就執(zhí)行
用閉包來解決回調(diào)函數(shù)在調(diào)用的時候訪問的是全局的變量
在閉包中創(chuàng)建一個變量楼眷,來單獨存儲當(dāng)前的回調(diào)函數(shù)需要的數(shù)據(jù),
在調(diào)用的時候就會去使用這個單獨的數(shù)據(jù)熊尉,而不是去訪問全局變量
注冊點擊事件的時候
點擊事件在觸發(fā)的時候訪問的是全局的變量
在閉包中創(chuàng)建一個變量罐柳,來單獨存儲當(dāng)前的事件處理函數(shù)需要的數(shù)據(jù),
在調(diào)用的時候就會去使用這個單獨的數(shù)據(jù)狰住,而不是去訪問全局變量
2.閉包緩存
緩存:將常用的數(shù)據(jù)進(jìn)行存儲张吉,以提升性能
硬件緩存
瀏覽器緩存
CDN
內(nèi)存型數(shù)據(jù)庫
如何用閉包實現(xiàn)緩存
1、寫一個閉包在閉包中創(chuàng)建一個對象催植,用來做緩存的存儲對象
2肮蛹、在閉包中創(chuàng)建一個對象,用來做緩存的存儲對象
3创南、在閉包中創(chuàng)建一個數(shù)組伦忠,用來存儲換中的鍵
4、返回一個函數(shù)稿辙,這個函數(shù)需要兩個參數(shù)昆码,一個是key 一個是value
5、在返回的函數(shù)中,判斷傳入的value是否為undefined
6邻储、如果為Undefined 則表示是獲取值赋咽,就直接返回在第一步創(chuàng)建的緩存對象中指定的鍵對應(yīng)的值
7、如果不為Undefined 則表示是設(shè)置值
8吨娜、在緩存對象中設(shè)置指定的key的值為value
9脓匿、把key加入存儲key的數(shù)組
10、判斷key數(shù)組是不是超出了緩存大小限制
11宦赠、如果超出限制陪毡,刪除數(shù)組第一個元素(使用shift),獲取到刪除的key
12勾扭、使用刪除的key刪除緩存對象中存儲的值(delete)
3.使用緩存解決斐波那契數(shù)列的性能問題
就是將已經(jīng)計算過的數(shù)字緩存進(jìn)一個數(shù)組中缤骨,下次再來訪問的時候,直接在數(shù)組中進(jìn)行查找尺借,如果找到直接使用绊起,如果沒有找到,計算后將數(shù)字存入數(shù)組燎斩,然后返回該數(shù)字
4.沙箱模式
沙箱模式就是一個封閉的獨立的環(huán)境
沙箱模式的基本模型
(function(){
//變量定義
//邏輯代碼
//如果需要虱歪,向window對象添加成員蜂绎,以暴露接口
})()
第三方框架
插件
獨立的組件
沙箱的優(yōu)勢:1、沙箱模式使用的是IIFE笋鄙,不會再外界暴露任何的全局變量师枣,也就不會造成全局變量污染
2、沙箱中的所有數(shù)據(jù)萧落,都是和外界完全隔離的践美,外界無法對其進(jìn)行修改,也就保證了代碼的安全性
沙箱的原理:函數(shù)可以構(gòu)建作用域找岖!上級作用域不能直接訪問下級作用域中的數(shù)據(jù)
5.函數(shù)的四種調(diào)用模式
函數(shù)模式
this--->window方法模式
this---->調(diào)用方法的對象構(gòu)造函數(shù)模式
this----->new出來的對象
工廠模式
寄生模式-
上下文模式
- this----->指定的是誰就是誰
- call 函數(shù).call(對象,arg1,arg2,arg3,...argn)
apply 函數(shù).apply(對象,數(shù)組)
都可以用來改變this的指向為參數(shù)的第一個值
call是使用單獨的每一個參數(shù)來傳參
apply是使用數(shù)組進(jìn)行傳參的陨倡,這個數(shù)組在調(diào)用的時候,會被意義拆解许布,當(dāng)做函數(shù)的每一個采參數(shù)call在函數(shù)的形參個數(shù)確定的情況下使用
apply在函數(shù)的形參個數(shù)不確定的情況下使用
this指向不同
七兴革、JS高級總復(fù)習(xí)
1.Javascript基礎(chǔ)復(fù)習(xí)
2.面向?qū)ο?/h3>
- 把解決問題的重點放在解決問題相關(guān)的對象上
- 封裝/繼承/多態(tài)
- 對象:無序的鍵值對
- 屬性:數(shù)值類型的
- 方法:函數(shù)類型的
- 創(chuàng)建對象的方法
- 字面量:用完之后不可復(fù)用
- 內(nèi)置對象創(chuàng)建:a)創(chuàng)建的是空對象,需要手動添加屬性 b)動態(tài)特性:創(chuàng)建好對象后,可以給對象添加屬性和方法
- 工廠函數(shù):定義一個對象,給他動態(tài)添加屬性,返回
- 自定義構(gòu)造函數(shù):a)也是函數(shù)的一種蜜唾,一般用來初始化對象 b)和new一起出現(xiàn)杂曲,new創(chuàng)建一個對象,構(gòu)造函數(shù)初始化對象 c)返回new創(chuàng)建的對象 d)如果return的基本類型袁余,不影響擎勘,仍返回new對象 / 返回Object類型,返回這個Object
- 自定義構(gòu)造函數(shù)的執(zhí)行過程:a)先使用new創(chuàng)建對象 b)把new創(chuàng)建出來的對象交給構(gòu)造函數(shù)的this
c) 在構(gòu)造函數(shù)內(nèi)部通過this給對象封裝方法
- 原型
- 在構(gòu)造函數(shù)創(chuàng)建出來的時候默認(rèn)會創(chuàng)建一個與對象與之關(guān)聯(lián)颖榜,這個對象就是原型對象
- 訪問 構(gòu)造函數(shù).prototype / 對象._ proto _
- 原型的使用:直接替換/混入式添加屬性和方法/經(jīng)典繼承
- 原型鏈:每個對象都有原型對象棚饵,原型對象又有原型對象
3.Function
- 創(chuàng)建函數(shù)
4.遞歸
- 化歸思想
- 案例:求和、階乘朱转、斐波那契數(shù)列、獲取所有頁面節(jié)點
5.作用域
- 詞法作用域
- 變量提升
- JS執(zhí)行階段
- 預(yù)解析階段
- 執(zhí)行階段
6.作用域鏈
- 外部無法訪問內(nèi)部作用域
- 內(nèi)部可訪問外部
7.閉包
- 封閉的對外不公開的空間
- 外面訪問不到
- 外部訪問只能通過內(nèi)部的接口
- 作用:保護(hù)數(shù)據(jù)
- 案例:返回多個值/設(shè)置及獲取积暖、歌曲播放列表藤为、解決斐波那契數(shù)列問題、閉包對緩存實現(xiàn)了一個保護(hù)作用
- jQuery實現(xiàn)緩存
- 定義一個對象存儲數(shù)據(jù)
- 定義一個數(shù)組存儲鍵:a)記錄順序 b)記錄長度夺刑,超容量判斷
8.沙箱模式
- 一個封閉的對外隔離的環(huán)境
- 避免外界竊取內(nèi)部的數(shù)據(jù)
- 使用自調(diào)用(IIFE)函數(shù)實現(xiàn)
- 限制作用域
- 自調(diào)用函數(shù)沒有名字
- 代碼結(jié)構(gòu)
- 最上面:定義變量
- 中間:邏輯代碼
- 下面:暴露接口(有利于代碼壓縮)
1.最后及加上window
2.給函數(shù)一個形參
3.形參.變量 = 變量
- 作業(yè):封裝第三方插件缅疟、封裝框架
9.函數(shù)調(diào)用模式
- 函數(shù)調(diào)用模式
- this指向window
- 方法調(diào)用模式
- this指向與之關(guān)聯(lián)的對象
- 構(gòu)造函數(shù)調(diào)用模式
- this指向new創(chuàng)建的對象
- 上下文調(diào)用模式
- call(對象,[],[],..[])
- apply(對象遍愿,[])
- 可以用apply實現(xiàn)借用構(gòu)造函數(shù)
- 在當(dāng)前函數(shù)使用其他函數(shù).apply()
10.注冊事件兼容性
- addEventListenter(事件存淫,處理函數(shù))
- attachEvent(on 事件,處理函數(shù))
- 回調(diào)函數(shù)的this的指向與其他兩個不同
- on事件 = 處理函數(shù)
- 案例:
- 歌曲管理案例
- 方法寫在原型
- 屬性寫在構(gòu)造函數(shù)內(nèi)
- Tab欄切換案例
- 屬性:數(shù)值類型的
- 方法:函數(shù)類型的
- 字面量:用完之后不可復(fù)用
- 內(nèi)置對象創(chuàng)建:a)創(chuàng)建的是空對象,需要手動添加屬性 b)動態(tài)特性:創(chuàng)建好對象后,可以給對象添加屬性和方法
- 工廠函數(shù):定義一個對象,給他動態(tài)添加屬性,返回
- 自定義構(gòu)造函數(shù):a)也是函數(shù)的一種蜜唾,一般用來初始化對象 b)和new一起出現(xiàn)杂曲,new創(chuàng)建一個對象,構(gòu)造函數(shù)初始化對象 c)返回new創(chuàng)建的對象 d)如果return的基本類型袁余,不影響擎勘,仍返回new對象 / 返回Object類型,返回這個Object
- 自定義構(gòu)造函數(shù)的執(zhí)行過程:a)先使用new創(chuàng)建對象 b)把new創(chuàng)建出來的對象交給構(gòu)造函數(shù)的this
c) 在構(gòu)造函數(shù)內(nèi)部通過this給對象封裝方法
- 在構(gòu)造函數(shù)創(chuàng)建出來的時候默認(rèn)會創(chuàng)建一個與對象與之關(guān)聯(lián)颖榜,這個對象就是原型對象
- 訪問 構(gòu)造函數(shù).prototype / 對象._ proto _
- 原型的使用:直接替換/混入式添加屬性和方法/經(jīng)典繼承
- 原型鏈:每個對象都有原型對象棚饵,原型對象又有原型對象
- 預(yù)解析階段
- 執(zhí)行階段
- 定義一個對象存儲數(shù)據(jù)
- 定義一個數(shù)組存儲鍵:a)記錄順序 b)記錄長度夺刑,超容量判斷
- 最上面:定義變量
- 中間:邏輯代碼
- 下面:暴露接口(有利于代碼壓縮)
1.最后及加上window
2.給函數(shù)一個形參
3.形參.變量 = 變量
- this指向window
- this指向與之關(guān)聯(lián)的對象
- this指向new創(chuàng)建的對象
- call(對象,[],[],..[])
- apply(對象遍愿,[])
- 可以用apply實現(xiàn)借用構(gòu)造函數(shù)
- 在當(dāng)前函數(shù)使用其他函數(shù).apply()
- 回調(diào)函數(shù)的this的指向與其他兩個不同
- 歌曲管理案例
- 方法寫在原型
- 屬性寫在構(gòu)造函數(shù)內(nèi)
- Tab欄切換案例