01.Cookie,SessionStorage啡邑,LocalStorage
生命周期:Cookie的生命周期默認(rèn)關(guān)閉瀏覽器后失效;SessionStorage僅在當(dāng)前窗口下有效,關(guān)閉窗口或瀏覽器將被清除;LocalStorage除非被清除切厘,否則永久保存。
容量:Cookie 4KB 20~50懊缺;SessionSorage 5MB;LocalStorage 5MB
網(wǎng)絡(luò)請求:Cookie每次都會攜帶在HTTP頭中培他,如果使用Cookie保存過多數(shù)據(jù)會帶來性能問題鹃两;SessionStorage、LocalStorage 僅在瀏覽器中保存舀凛,不參與和服務(wù)器的通信俊扳,不會像Cookie那樣保存在請求頭中發(fā)送給服務(wù)器。
使用場景:Cookie 判斷用戶是否登錄猛遍;SessionSorage 表單數(shù)據(jù)馋记;LocalStorage 購物車. Cookie在本地驗證完登錄号坡,發(fā)送到服務(wù)器后還可以再驗證一次,雙重驗證更保險梯醒。SessionSorage宽堆,注冊時需要填表單,數(shù)據(jù)較多茸习,如果沒有關(guān)閉窗口返回上一頁時還可以存在畜隶。LocalStorage容量比較大,除非手動清除否則永遠(yuǎn)存在号胚,上一次添加的購物車商品還可以存在籽慢。
// 保存數(shù)據(jù)到 sessionStorage
sessionStorage.setItem('key', 'value');
// 從 sessionStorage 獲取數(shù)據(jù)
let data = sessionStorage.getItem('key');
// 從 sessionStorage 刪除保存的數(shù)據(jù)
sessionStorage.removeItem('key');
// 從 sessionStorage 刪除所有保存的數(shù)據(jù)
sessionStorage.clear();
02.同源策略
同源策略(same origin policy)是一種約定,是瀏覽器最核心也最基本的安全功能猫胁。協(xié)議箱亿、域名、端口都相同就是同源弃秆,否則為跨域届惋。
協(xié)議+一級域名+二級域名+端口號 相同 才叫同源,否則為跨域驾茴。
http://www.it666.com:80/index.html
協(xié)議:http://
一級域名 :it666.com
二級域名:www
端口號:80
資源路徑:index.html
同源策略帶來的影響:一般情況下盼樟,瀏覽器只允許Ajax請求同源的數(shù)據(jù),不同源的數(shù)據(jù)是拿不到的锈至。但一般情況下為了提升網(wǎng)頁的性能晨缴,網(wǎng)頁和數(shù)據(jù)都是單獨存儲在不同服務(wù)器上的,這時通過Ajax請求數(shù)據(jù)就會拿不到跨域數(shù)據(jù)峡捡。
跨域解決方法:JSONP讓網(wǎng)頁從別的地址(跨域的地址)那里獲取資料击碗,即跨域讀取數(shù)據(jù)。
JSONP實現(xiàn)跨域訪問的原理:
- 在同一界面中可以定義多個script標(biāo)簽
- 同一個界面中多個script標(biāo)簽中的數(shù)據(jù)可以互相訪問
- 可以通過script標(biāo)簽的src屬性導(dǎo)入其他資源
- 通過src屬性導(dǎo)入其他資源的本質(zhì)就是將資源拷貝到script標(biāo)簽中
- script的src屬性不僅能導(dǎo)入本地資源们拙,還能導(dǎo)入遠(yuǎn)程資源
- 由于script的src屬性沒有同源限制稍途,所以可以通過script的src屬性來請求跨域數(shù)據(jù)
JSONP實現(xiàn)跨域訪問優(yōu)化
優(yōu)化1:企業(yè)開發(fā)中通過JSONP來獲取跨域的數(shù)據(jù),一般情況下服務(wù)器返回的不是一個變量砚婆,而是一個函數(shù)的調(diào)用械拍。
優(yōu)化2:自己先定義一個函數(shù),然后將函數(shù)名以參數(shù)的方式傳遞給src装盯。就是我定義什么函數(shù)坷虑,那邊就調(diào)用什么函數(shù)。
優(yōu)化3:由于script標(biāo)簽?zāi)J(rèn)是同步的埂奈,前面的script標(biāo)簽沒有加載完數(shù)據(jù)迄损,后面的script標(biāo)簽不會被執(zhí)行。所以請求數(shù)據(jù)的script標(biāo)簽必須放在定義函數(shù)的后面账磺。為了打破這種順序關(guān)系限制芹敌,我們可以采取異步的script標(biāo)簽痊远。通過js代碼創(chuàng)建一個script標(biāo)簽,把oScript動態(tài)加載到document中氏捞。通過js代碼創(chuàng)建一個script標(biāo)簽是異步的碧聪,不用等待src這個資源加載完畢就會繼續(xù)往后執(zhí)行,往后執(zhí)行遇到test函數(shù)時已經(jīng)讀取了幌衣,這時資源加載完畢就會識別到已經(jīng)有了一個test函數(shù)矾削,所以不會報錯。
let oScript = document.createElement("script")
oScript.src = "http://127.0.0.1:80/jQuery/Ajax/20-jsonp.php?cb=test";
document.body.appendChild(oScript)
// src在test函數(shù)前面豁护,但不會報錯哼凯,就是說這樣也會找到test函數(shù)
function test(data){
console.log(data);
}
jQuery 中的JSONP封裝
$.ajax({
url: "http://127.0.0.1:80...",
data: { // 發(fā)送獲取跨域數(shù)據(jù)的請求時同時把數(shù)據(jù)傳遞過去
"teacher": "lnj",
"age": 34
}
dataType: "jsonp", // 告訴jQuery需要請求跨域的數(shù)據(jù)
jsonp: "cb", // 告訴jQuery服務(wù)器在獲取回調(diào)函數(shù)名稱的時候需要什么key來獲取
jsonpCallback: "lnj", // 告訴jQuery服務(wù)器在獲取回調(diào)函數(shù)名稱的時候,回調(diào)函數(shù)的名稱是什么
success: function (msg) {
console.log(msg);
}
})
03.應(yīng)用程序楚里、進程断部、線程,串行班缎、并行
應(yīng)用程序:應(yīng)用程序是.exe后綴蝴光,一個應(yīng)用程序通過多次打開,可以開啟多個對應(yīng)的進程达址。程序是通過編譯器編寫好的存儲在硬盤上的一個二進制文件蔑祟,會占用磁盤空間但不會占用系統(tǒng)資源。
進程:進程是程序在操作系統(tǒng)中的一次執(zhí)行過程沉唠,是系統(tǒng)進行資源分配和調(diào)度的基本單位疆虚。一個進程中至少有一個線程,這個線程叫做主線程满葛。進程和線程是一對多關(guān)系径簿。
線程:線程是進程中的一個執(zhí)行實例,是程序執(zhí)行的最小單元嘀韧。比如啟動迅雷這個程序篇亭,系統(tǒng)會創(chuàng)建一個迅雷進程,并且默認(rèn)會有一個主線程锄贷,用于執(zhí)行迅雷默認(rèn)的業(yè)務(wù)邏輯译蒂。當(dāng)我們利用迅雷下載多個任務(wù)時,就會發(fā)現(xiàn)多個任務(wù)都在同時下載谊却,此時為了能夠同時執(zhí)行下載的操作蹂随,迅雷會創(chuàng)建多個線程,并將不同的下載任務(wù)放到不同的線程中執(zhí)行因惭。
串行:計算機中,一個線程要執(zhí)行多個指令绩衷,只能一個一個排隊執(zhí)行蹦魔。同一時刻只能有一條指令在一個CPU上執(zhí)行激率,后面的指令必須等待前面的指令執(zhí)行完才能執(zhí)行。
并行:同一時刻有多條指令可以在多個CPU上同時執(zhí)行勿决。
04.JS串行和事件循環(huán)
JS是單線程的乒躺,前面代碼沒有執(zhí)行完后面的代碼是不會輸出的。
同步代碼和異步代碼:除了事件綁定的函數(shù)和回調(diào)函數(shù)以外的都是同步代碼低缩。事件綁定的函數(shù)和回調(diào)函數(shù)是異步代碼嘉冒,不會立即執(zhí)行。事件綁定的函數(shù)直到事件觸發(fā)了才會執(zhí)行咆繁,回調(diào)函數(shù)直到條件滿足了才會執(zhí)行讳推。
事件循環(huán):js會自動將異步代碼添加到數(shù)組里,這個數(shù)組放在所有代碼的末尾玩般。當(dāng)執(zhí)行完所有同步代碼后银觅,js會遍歷這個數(shù)組里的所有異步代碼,看看哪個滿足條件坏为,依次執(zhí)行究驴。
1.程序運行會從上至下依次執(zhí)行所有的同步代碼
2.在執(zhí)行的過程中如果遇到異步代碼會將異步代碼放到事件循環(huán)中
3.當(dāng)所有的同步代碼執(zhí)行完后,JS會不斷檢測 事件循環(huán)中的異步代碼是否滿足條件匀伏,一旦滿足條件就會執(zhí)行滿足條件的異步代碼
05.Promise基本概念
-
promise是ES6中新增的異步編程解決方案洒忧,在代碼中的表現(xiàn)是一個對象.
企業(yè)開發(fā)中為了保存異步代碼的執(zhí)行順序,就會出現(xiàn)回調(diào)函數(shù)層次嵌套,如果回調(diào)函數(shù)太多,代碼的可讀性和維護性會大大降低
promise對象可以將異步操作以同步流程來表示,避免了回調(diào)函數(shù)的層層嵌套
-
如何創(chuàng)建promise對象:
promise 對象不是異步的,只要創(chuàng)建promise對象就會立即執(zhí)行promise里面存放的代碼
let p = new Promise(function(resolve, reject){
console.log("2")
resolve();
})
-
Promise對象的三種狀態(tài)
pending: 默認(rèn)狀態(tài),只要沒告訴promise任務(wù)是成功還是失敗就是pending狀態(tài)
fulfilled(resolved): 一旦調(diào)用了resolve函數(shù)就是resolved
rejected: 一旦調(diào)用了reject函數(shù),狀態(tài)就會變?yōu)閞ejected
注意: 狀態(tài)一旦發(fā)生改變就不可逆轉(zhuǎn)
-
promise如何實現(xiàn)通過同步的流程來表示異步的操作的?
如果狀態(tài)改變成功就會自動執(zhí)行狀態(tài)所對應(yīng)的回調(diào)函數(shù)
resolved -> then()
rejected -> catch()
-
then方法
then接受兩個參數(shù),一個參數(shù)是狀態(tài)成功時執(zhí)行的回調(diào)函數(shù),另一個參數(shù)是狀態(tài)為失敗時的回調(diào)函數(shù);
在修改promise狀態(tài)時,可以傳遞參數(shù)給then方法中的回調(diào)函數(shù)够颠;
當(dāng)狀態(tài)為成功時,所有的then方法都會被觸發(fā)熙侍;
then方法每次執(zhí)行完畢時都會返回一個新的promise對象;
可以通過上一個promise對象的then方法給下一個promise的then方法傳遞參數(shù)摧找。注意:無論是在上一個promise對象成功的回調(diào)函數(shù)中還是失敗的回調(diào)函數(shù)中傳遞參數(shù)核行,都會傳遞給下一個promise對象成功的回調(diào)中;
上一個promise對象的then方法給下一個promise的then方法傳遞參數(shù)時蹬耘,除了傳遞基本數(shù)據(jù)之外芝雪,還可以傳遞promise對象。
-
catch方法
- 不使用鏈?zhǔn)骄幊痰脑蚴亲厶Γ绻鹥romise的狀態(tài)是失敗但沒有對應(yīng)失敗的監(jiān)聽就會報錯
- then方法每次執(zhí)行完畢都會返回一個新的promise對象惩系,新的promise對象會繼承原有的promise狀態(tài)
- 如果新的promise狀態(tài)是失敗,沒有對應(yīng)失敗的監(jiān)聽也會報錯
Promise特點
- 創(chuàng)建時必須傳入一個函數(shù)如筛,否則會報錯
- 會給傳入的函數(shù)設(shè)置兩個回調(diào)函數(shù)
- 剛創(chuàng)建的Promise對象狀態(tài)是pending
- 狀態(tài)一旦發(fā)生改變就不可再次改變
- 可以通過then來監(jiān)聽狀態(tài)的改變
- 如果添加監(jiān)聽時狀態(tài)已經(jīng)改變堡牡,立即執(zhí)行監(jiān)聽的回調(diào)
- 如果添加監(jiān)聽時狀態(tài)還未改變,那么狀態(tài)改變時再執(zhí)行監(jiān)聽回調(diào)
- 同一個promise對象可以添加多個then監(jiān)聽杨刨,狀態(tài)改變時所有的監(jiān)聽按照添加順序執(zhí)行
06.異常處理機制
JS中的異常晤柄,簡單來講就是有錯誤出現(xiàn),由于JS是單線程的因此前面的代碼一旦出現(xiàn)錯誤妖胀,程序就會被中斷芥颈,后面的代碼就不會被執(zhí)行惠勒。
使用try{}catch{}來處理異常可以保證程序不被中斷爬坑,后續(xù)代碼還可以繼續(xù)執(zhí)行并拿到發(fā)生錯誤代碼的原因纠屋。
try{
可能遇到的意外代碼
}catch(e){
捕獲錯誤的代碼塊
}
07.fetch
-
什么是fetch?
和Ajax一樣都是用于請求網(wǎng)絡(luò)數(shù)據(jù)的
fetch是ES6中新增的基于Promise的網(wǎng)絡(luò)請求方法
-
fetch的基本使用
fetch(url, {options}) .then() .catch()
08.axios
// 超過2秒的請求時間服務(wù)器沒返回盾计,就報錯售担。全局的
axios.defaults.timeout = 2000
企業(yè)開發(fā)中項目分為:開發(fā)階段和部署階段 ,這兩個階段項目存儲的位置是不同的署辉。項目上線前存儲在企業(yè)的內(nèi)部測試服務(wù)器上族铆,項目上線后存儲在企業(yè)的正式服務(wù)器上。兩臺服務(wù)器不同則IP地址也不同涨薪,如果axios發(fā)送請求的url寫死了的話骑素,那么后期更改將會是巨大的麻煩。
為了解決這個問題刚夺,我們可以配置一個全局URL根地址献丑,項目上線時只需修改根地址即可。前部分不用改侠姑,只用改后面部分
axios.defaults.baseURL = "http://127.0.0.1";
09.Symbol
什么是Symbol创橄?
Symbol是ES6中新增的一種數(shù)據(jù)類型,被劃分到了基本數(shù)據(jù)類型中莽红。
基本數(shù)據(jù)類型:字符串string妥畏,數(shù)值Number,布爾boolean安吁,undefined醉蚁,null,Symbol
引用數(shù)據(jù)類型:ObjectSymbol的作用
用來表示一個獨一無二的值為什么需要Symbol?
在企業(yè)開發(fā)中如果需要對一些第三方的插件鬼店、框架進行自定義的時候网棍,可能會因為添加了同名的屬性或方法將框架中原有的屬性或方法覆蓋掉。為了避免這種情況發(fā)生妇智,我們就可以使用Symbol作為屬性或者方法的名稱滥玷。如何區(qū)分Symbol?
通過Symbol生成獨一無二的值時可以設(shè)置一個標(biāo)記巍棱,這個標(biāo)記僅僅用于區(qū)分惑畴,沒有其他任何含義-
Symbol注意點:
-
通過Symbol生成獨一無二值時需要在后面加上(),但是前面不能加new航徙,因為他不是引用類型
let x = Symbol();
-
通過Symbol生成獨一無二的值時傳入的字符串僅僅是一個標(biāo)記如贷,方便閱讀代碼,沒有其他任何意義
let x = Symbol("name");
做類型轉(zhuǎn)換時不能轉(zhuǎn)換成數(shù)值
不能做任何運算
-
Symbol生成的值作為屬性或方法時,一定要保存下來杠袱,否則后續(xù)無法使用泻红。因為Symbol在兩個地方都創(chuàng)建了一個獨一無二的值。
image-20230320213446059.png for循環(huán)無法遍歷Symbol的屬性和方法
-
10.Iterator
迭代器
- 只要一個數(shù)據(jù)自帶了Iterator接口霞掺,那么這個數(shù)據(jù)就有一個叫做[Symbol.iterator]的屬性
- [Symbol.iterator]的屬性會返回一個函數(shù)
- [Symbol.iterator]的屬性返回的函數(shù)執(zhí)行之后會返回一個對象
- [Symbol.iterator]函數(shù)返回的對象中又有一個名稱叫做next的方法
- next方法每次執(zhí)行都會返回一個對象{value:1, done:false} value表示迭代的值,done表示是否已經(jīng)迭代完成
注意:
-
解構(gòu)賦值也用到了iterator接口
let arr = new MyArray(1, 3) // 1. 解構(gòu)賦值 中也用到了iterator接口 let [x, y ,z] = arr; console.log(x, y, z);
-
擴展運算符也用到了iterator接口
let arr1 = new MyArray(1, 3) let arr2 = new MyArray(2, 4) // 擴展運算符將兩個數(shù)組合并成一個數(shù)組 let arr3 = [...arr1, ...arr2] console.log(arr3);
11.Generator函數(shù)
-
是啥讹躯?
Generator函數(shù) 是ES6提供的一種異步編程解決方案菩彬,Generator函數(shù)內(nèi)部可以封裝多個狀態(tài),因此可以理解成是一個狀態(tài)機潮梯。
-
如何定義
只需在普通函數(shù)的function后面加上*
-
Generator函數(shù)和普通函數(shù)的區(qū)別
- 調(diào)用Generator函數(shù)后骗灶,無論函數(shù)有沒有返回值,都會返回一個可迭代對象
- 調(diào)用Generator函數(shù)后秉馏,函數(shù)中封裝的代碼不會立即被執(zhí)行
-
真正讓Generator函數(shù)有價值的是yield關(guān)鍵字
- 在Generator函數(shù)內(nèi)部使用yield關(guān)鍵字定義狀態(tài)
- yield關(guān)鍵字可以讓Generator函數(shù)內(nèi)部的邏輯被切割成多個部分
- 通過調(diào)用迭代器對象next方法執(zhí)行一個部分代碼耙旦,執(zhí)行哪個部分就會返回哪個部分定義的狀態(tài)
在調(diào)用next方法時候可以傳遞一個參數(shù),這個參數(shù)會傳遞給上一個yield
12.async函數(shù)
await等待promise執(zhí)行完畢萝究,才將promise里面的東西放到res1里
13.異步請求
在獲取輪播圖數(shù)據(jù)之前就設(shè)置loop:true的話免都,會導(dǎo)致loop失效,原因是從服務(wù)器那邊請求數(shù)據(jù)是個異步操作帆竹。
解決方法:等到獲取數(shù)據(jù)之后再設(shè)置loop