摘要:決定了注冊(cè)的事件是捕獲事件還是冒泡事件。瀏覽器會(huì)自動(dòng)進(jìn)行通信,實(shí)現(xiàn)通信的關(guān)鍵是后端。該方式只能用于二級(jí)域名相同的情況下,比如和適用于該方式。中的中的和瀏覽器中的不相同。
事件機(jī)制 事件觸發(fā)三階段
事件觸發(fā)有三個(gè)階段
window 往事件觸發(fā)處傳播,遇到注冊(cè)的捕獲事件會(huì)觸發(fā)
傳播到事件觸發(fā)處時(shí)觸發(fā)注冊(cè)的事件
從事件觸發(fā)處往 window 傳播,遇到注冊(cè)的冒泡事件會(huì)觸發(fā)
事件觸發(fā)一般來說會(huì)按照上面的順序進(jìn)行,但是也有特例,如果給一個(gè)目標(biāo)節(jié)點(diǎn)同時(shí)注冊(cè)冒泡和捕獲事件,事件觸發(fā)會(huì)按照注冊(cè)的順序執(zhí)行。
// 以下會(huì)先打印冒泡然后是捕獲 node.addEventListener("click",(event) =>{ console.log("冒泡") },false); node.addEventListener("click",(event) =>{ console.log("捕獲 ") },true)注冊(cè)事件
通常我們使用 addEventListener 注冊(cè)事件,該函數(shù)的第三個(gè)參數(shù)可以是布爾值,也可以是對(duì)象。對(duì)于布爾值 useCapture 參數(shù)來說,該參數(shù)默認(rèn)值為 false 。useCapture 決定了注冊(cè)的事件是捕獲事件還是冒泡事件。對(duì)于對(duì)象參數(shù)來說,可以使用以下幾個(gè)屬性
capture,布爾值,和 useCapture 作用一樣
once,布爾值,值為 true 表示該回調(diào)只會(huì)調(diào)用一次,調(diào)用后會(huì)移除監(jiān)聽
passive,布爾值,表示永遠(yuǎn)不會(huì)調(diào)用 preventDefault
一般來說,我們只希望事件只觸發(fā)在目標(biāo)上,這時(shí)候可以使用 stopPropagation 來阻止事件的進(jìn)一步傳播。通常我們認(rèn)為 stopPropagation 是用來阻止事件冒泡的,其實(shí)該函數(shù)也可以阻止捕獲事件。stopImmediatePropagation 同樣也能實(shí)現(xiàn)阻止事件,但是還能阻止該事件目標(biāo)執(zhí)行別的注冊(cè)事件。
node.addEventListener("click",(event) =>{ event.stopImmediatePropagation() console.log("冒泡") },false); // 點(diǎn)擊 node 只會(huì)執(zhí)行上面的函數(shù),該函數(shù)不會(huì)執(zhí)行 node.addEventListener("click",(event) => { console.log("捕獲 ") },true)事件代理
如果一個(gè)節(jié)點(diǎn)中的子節(jié)點(diǎn)是動(dòng)態(tài)生成的,那么子節(jié)點(diǎn)需要注冊(cè)事件的話應(yīng)該注冊(cè)在父節(jié)點(diǎn)上
事件代理的方式相對(duì)于直接給目標(biāo)注冊(cè)事件來說,有以下優(yōu)點(diǎn)
節(jié)省內(nèi)存
不需要給子節(jié)點(diǎn)注銷事件
跨域因?yàn)闉g覽器出于安全考慮,有同源策略。也就是說,如果協(xié)議、域名或者端口有一個(gè)不同就是跨域,Ajax 請(qǐng)求會(huì)失敗。
我們可以通過以下幾種常用方法解決跨域的問題
JSONPJSONP 的原理很簡(jiǎn)單,就是利用 標(biāo)簽沒有跨域限制的漏洞。通過 標(biāo)簽指向一個(gè)需要訪問的地址并提供一個(gè)回調(diào)函數(shù)來接收數(shù)據(jù)當(dāng)需要通訊時(shí)。
JSONP 使用簡(jiǎn)單且兼容性不錯(cuò),但是只限于 get 請(qǐng)求。
在開發(fā)中可能會(huì)遇到多個(gè) JSONP 請(qǐng)求的回調(diào)函數(shù)名是相同的,這時(shí)候就需要自己封裝一個(gè) JSONP,以下是簡(jiǎn)單實(shí)現(xiàn)
function jsonp(url, jsonpCallback, success) { let script = document.createElement("script"); script.src = url; script.async = true; script.type = "text/javascript"; window[jsonpCallback] = function(data) { success && success(data); }; document.body.appendChild(script); } jsonp( "http://xxx", "callback", function(value) { console.log(value); } );CORS
CORS需要瀏覽器和后端同時(shí)支持。IE 8 和 9 需要通過 XDomainRequest 來實(shí)現(xiàn)。
瀏覽器會(huì)自動(dòng)進(jìn)行 CORS 通信,實(shí)現(xiàn)CORS通信的關(guān)鍵是后端。只要后端實(shí)現(xiàn)了 CORS,就實(shí)現(xiàn)了跨域。
服務(wù)端設(shè)置 Access-Control-Allow-Origin 就可以開啟 CORS。 該屬性表示哪些域名可以訪問資源,如果設(shè)置通配符則表示所有網(wǎng)站都可以訪問資源。
document.domain該方式只能用于二級(jí)域名相同的情況下,比如 a.test.com 和 b.test.com 適用于該方式。
只需要給頁面添加 document.domain = "test.com" 表示二級(jí)域名都相同就可以實(shí)現(xiàn)跨域
postMessage這種方式通常用于獲取嵌入頁面中的第三方頁面數(shù)據(jù)。一個(gè)頁面發(fā)送消息,另一個(gè)頁面判斷來源并接收消息
// 發(fā)送消息端 window.parent.postMessage("message", "http://test.com"); // 接收消息端 var mc = new MessageChannel(); mc.addEventListener("message", (event) => { var origin = event.origin || event.originalEvent.origin; if (origin === "http://test.com") { console.log("驗(yàn)證通過") } });Event loop
眾所周知 JS 是門非阻塞單線程語言,因?yàn)樵谧畛?JS 就是為了和瀏覽器交互而誕生的。如果 JS 是門多線程的語言話,我們?cè)诙鄠€(gè)線程中處理 DOM 就可能會(huì)發(fā)生問題(一個(gè)線程中新加節(jié)點(diǎn),另一個(gè)線程中刪除節(jié)點(diǎn)),當(dāng)然可以引入讀寫鎖解決這個(gè)問題。
JS 在執(zhí)行的過程中會(huì)產(chǎn)生執(zhí)行環(huán)境,這些執(zhí)行環(huán)境會(huì)被順序的加入到執(zhí)行棧中。如果遇到異步的代碼,會(huì)被掛起并加入到 Task(有多種 task) 隊(duì)列中。一旦執(zhí)行棧為空,Event Loop 就會(huì)從 Task 隊(duì)列中拿出需要執(zhí)行的代碼并放入執(zhí)行棧中執(zhí)行,所以本質(zhì)上來說 JS 中的異步還是同步行為。
console.log("script start"); setTimeout(function() { console.log("setTimeout"); }, 0); console.log("script end");
以上代碼雖然 setTimeout 延時(shí)為 0,其實(shí)還是異步。這是因?yàn)?HTML5 標(biāo)準(zhǔn)規(guī)定這個(gè)函數(shù)第二個(gè)參數(shù)不得小于 4 毫秒,不足會(huì)自動(dòng)增加。所以 setTimeout 還是會(huì)在 script end 之后打印。
不同的任務(wù)源會(huì)被分配到不同的 Task 隊(duì)列中,任務(wù)源可以分為 微任務(wù)(microtask) 和 宏任務(wù)(macrotask)。在 ES6 規(guī)范中,microtask 稱為 jobs,macrotask 稱為 task。
console.log("script start"); setTimeout(function() { console.log("setTimeout"); }, 0); new Promise((resolve) => { console.log("Promise") resolve() }).then(function() { console.log("promise1"); }).then(function() { console.log("promise2"); }); console.log("script end"); // script start => Promise => script end => promise1 => promise2 => setTimeout
以上代碼雖然 setTimeout 寫在 Promise 之前,但是因?yàn)?Promise 屬于微任務(wù)而 setTimeout 屬于宏任務(wù),所以會(huì)有以上的打印。
微任務(wù)包括 process.nextTick ,promise ,Object.observe ,MutationObserver
宏任務(wù)包括 script , setTimeout ,setInterval ,setImmediate ,I/O ,UI rendering
很多人有個(gè)誤區(qū),認(rèn)為微任務(wù)快于宏任務(wù),其實(shí)是錯(cuò)誤的。因?yàn)楹耆蝿?wù)中包括了 script ,瀏覽器會(huì)先執(zhí)行一個(gè)宏任務(wù),接下來有異步代碼的話就先執(zhí)行微任務(wù)。
所以正確的一次 Event loop 順序是這樣的
執(zhí)行同步代碼,這屬于宏任務(wù)
執(zhí)行棧為空,查詢是否有微任務(wù)需要執(zhí)行
執(zhí)行所有微任務(wù)
必要的話渲染 UI
然后開始下一輪 Event loop,執(zhí)行宏任務(wù)中的異步代碼
通過上述的 Event loop 順序可知,如果宏任務(wù)中的異步代碼有大量的計(jì)算并且需要操作 DOM 的話,為了更快的 界面響應(yīng),我們可以把操作 DOM 放入微任務(wù)中。
Node 中的 Event loopNode 中的 Event loop 和瀏覽器中的不相同。
Node 的 Event loop 分為6個(gè)階段,它們會(huì)按照順序反復(fù)運(yùn)行
┌───────────────────────┐ ┌─>│ timers │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ │ │ I/O callbacks │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ │ │ idle, prepare │ │ └──────────┬────────────┘ ┌───────────────┐ │ ┌──────────┴────────────┐ │ incoming: │ │ │ poll │<──connections─── │ │ └──────────┬────────────┘ │ data, etc. │ │ ┌──────────┴────────────┐ └───────────────┘ │ │ check │ │ └──────────┬────────────┘ │ ┌──────────┴────────────┐ └──┤ close callbacks │ └───────────────────────┘timer
timers 階段會(huì)執(zhí)行 setTimeout 和 setInterval
一個(gè) timer 指定的時(shí)間并不是準(zhǔn)確時(shí)間,而是在達(dá)到這個(gè)時(shí)間后盡快執(zhí)行回調(diào),可能會(huì)因?yàn)橄到y(tǒng)正在執(zhí)行別的事務(wù)而延遲。
下限的時(shí)間有一個(gè)范圍:[1, 2147483647] ,如果設(shè)定的時(shí)間不在這個(gè)范圍,將被設(shè)置為1。
I/OI/O 階段會(huì)執(zhí)行除了 close 事件,定時(shí)器和 setImmediate 的回調(diào)
idle, prepareidle, prepare 階段內(nèi)部實(shí)現(xiàn)
pollpoll 階段很重要,這一階段中,系統(tǒng)會(huì)做兩件事情
執(zhí)行到點(diǎn)的定時(shí)器
執(zhí)行 poll 隊(duì)列中的事件
并且當(dāng) poll 中沒有定時(shí)器的情況下,會(huì)發(fā)現(xiàn)以下兩件事情
如果 poll 隊(duì)列不為空,會(huì)遍歷回調(diào)隊(duì)列并同步執(zhí)行,直到隊(duì)列為空或者系統(tǒng)限制
如果 poll 隊(duì)列為空,會(huì)有兩件事發(fā)生
如果有 setImmediate 需要執(zhí)行,poll 階段會(huì)停止并且進(jìn)入到 check 階段執(zhí)行 setImmediate
如果沒有 setImmediate 需要執(zhí)行,會(huì)等待回調(diào)被加入到隊(duì)列中并立即執(zhí)行回調(diào)
如果有別的定時(shí)器需要被執(zhí)行,會(huì)回到 timer 階段執(zhí)行回調(diào)。
checkcheck 階段執(zhí)行 setImmediate
close callbacksclose callbacks 階段執(zhí)行 close 事件
并且在 Node 中,有些情況下的定時(shí)器執(zhí)行順序是隨機(jī)的
setTimeout(() => { console.log("setTimeout"); }, 0); setImmediate(() => { console.log("setImmediate"); }) // 這里可能會(huì)輸出 setTimeout,setImmediate // 可能也會(huì)相反的輸出,這取決于性能 // 因?yàn)榭赡苓M(jìn)入 event loop 用了不到 1 毫秒,這時(shí)候會(huì)執(zhí)行 setImmediate // 否則會(huì)執(zhí)行 setTimeout
當(dāng)然在這種情況下,執(zhí)行順序是相同的
var fs = require("fs") fs.readFile(__filename, () => { setTimeout(() => { console.log("timeout"); }, 0); setImmediate(() => { console.log("immediate"); }); }); // 因?yàn)?readFile 的回調(diào)在 poll 中執(zhí)行 // 發(fā)現(xiàn)有 setImmediate ,所以會(huì)立即跳到 check 階段執(zhí)行回調(diào) // 再去 timer 階段執(zhí)行 setTimeout // 所以以上輸出一定是 setImmediate,setTimeout
上面介紹的都是 macrotask 的執(zhí)行情況,microtask 會(huì)在以上每個(gè)階段完成后立即執(zhí)行。
setTimeout(()=>{ console.log("timer1") Promise.resolve().then(function() { console.log("promise1") }) }, 0) setTimeout(()=>{ console.log("timer2") Promise.resolve().then(function() { console.log("promise2") }) }, 0) // 以上代碼在瀏覽器和 node 中打印情況是不同的 // 瀏覽器中一定打印 timer1, promise1, timer2, promise2 // node 中可能打印 timer1, timer2, promise1, promise2 // 也可能打印 timer1, promise1, timer2, promise2
Node 中的 process.nextTick 會(huì)先于其他 microtask 執(zhí)行。
setTimeout(() => { console.log("timer1"); Promise.resolve().then(function() { console.log("promise1"); }); }, 0); process.nextTick(() => { console.log("nextTick"); }); // nextTick, timer1, promise1存儲(chǔ) cookie,localStorage,sessionStorage,indexDB
特性 | cookie | localStorage | sessionStorage | indexDB |
---|---|---|---|---|
數(shù)據(jù)生命周期 | 一般由服務(wù)器生成,可以設(shè)置過期時(shí)間 | 除非被清理,否則一直存在 | 頁面關(guān)閉就清理 | 除非被清理,否則一直存在 |
數(shù)據(jù)存儲(chǔ)大小 | 4K | 5M | 5M | 無限 |
與服務(wù)端通信 | 每次都會(huì)攜帶在 header 中,對(duì)于請(qǐng)求性能影響 | 不參與 | 不參與 | 不參與 |
從上表可以看到,cookie 已經(jīng)不建議用于存儲(chǔ)。如果沒有大量數(shù)據(jù)存儲(chǔ)需求的話,可以使用 localStorage 和 sessionStorage 。對(duì)于不怎么改變的數(shù)據(jù)盡量使用 localStorage 存儲(chǔ),否則可以用 sessionStorage 存儲(chǔ)。
對(duì)于 cookie,我們還需要注意安全性。
屬性 | 作用 |
---|---|
value | 如果用于保存用戶登錄態(tài),應(yīng)該將該值加密,不能使用明文的用戶標(biāo)識(shí) |
http-only | 不能通過 JS 訪問 Cookie,減少 XSS 攻擊 |
secure | 只能在協(xié)議為 HTTPS 的請(qǐng)求中攜帶 |
same-site | 規(guī)定瀏覽器不能在跨域請(qǐng)求中攜帶 Cookie,減少 CSRF 攻擊 |
Service workers 本質(zhì)上充當(dāng)Web應(yīng)用程序與瀏覽器之間的代理服務(wù)器,也可以在網(wǎng)絡(luò)可用時(shí)作為瀏覽器和網(wǎng)絡(luò)間的代理。它們旨在(除其他之外)使得能夠創(chuàng)建有效的離線體驗(yàn),攔截網(wǎng)絡(luò)請(qǐng)求并基于網(wǎng)絡(luò)是否可用以及更新的資源是否駐留在服務(wù)器上來采取適當(dāng)?shù)膭?dòng)作。他們還允許訪問推送通知和后臺(tái)同步API。
目前該技術(shù)通常用來做緩存文件,提高首屏速度,可以試著來實(shí)現(xiàn)這個(gè)功能。
// index.js if (navigator.serviceWorker) { navigator.serviceWorker .register("sw.js") .then(function(registration) { console.log("service worker 注冊(cè)成功"); }) .catch(function(err) { console.log("servcie worker 注冊(cè)失敗"); }); } // sw.js // 監(jiān)聽 `install` 事件,回調(diào)中緩存所需文件 self.addEventListener("install", e => { e.waitUntil( caches.open("my-cache").then(function(cache) { return cache.addAll(["./index.html", "./index.js"]); }) ); }); // 攔截所有請(qǐng)求事件 // 如果緩存中已經(jīng)有請(qǐng)求的數(shù)據(jù)就直接用緩存,否則去請(qǐng)求數(shù)據(jù) self.addEventListener("fetch", e => { e.respondWith( caches.match(e.request).then(function(response) { if (response) { return response; } console.log("fetch source"); }) ); });
打開頁面,可以在開發(fā)者工具中的 Application 看到 Service Worker 已經(jīng)啟動(dòng)了
在 Cache 中也可以發(fā)現(xiàn)我們所需的文件已被緩存
當(dāng)我們重新刷新頁面可以發(fā)現(xiàn)我們緩存的數(shù)據(jù)是從 Service Worker 中讀取的
渲染機(jī)制瀏覽器的渲染機(jī)制一般分為以下幾個(gè)步驟
處理 HTML 并構(gòu)建 DOM 樹。
處理 CSS 構(gòu)建 CSSOM 樹。
將 DOM 與 CSSOM 合并成一個(gè)渲染樹。
根據(jù)渲染樹來布局,計(jì)算每個(gè)節(jié)點(diǎn)的位置。
調(diào)用 GPU 繪制,合成圖層,顯示在屏幕上。
在構(gòu)建 CSSOM 樹時(shí),會(huì)阻塞渲染,直至 CSSOM 樹構(gòu)建完成。并且構(gòu)建 CSSOM 樹是一個(gè)十分消耗性能的過程,所以應(yīng)該盡量保證層級(jí)扁平,減少過度層疊,越是具體的 CSS 選擇器,執(zhí)行速度越慢。
當(dāng) HTML 解析到 script 標(biāo)簽時(shí),會(huì)暫停構(gòu)建 DOM,完成后才會(huì)從暫停的地方重新開始。也就是說,如果你想首屏渲染的越快,就越不應(yīng)該在首屏就加載 JS 文件。并且 CSS 也會(huì)影響 JS 的執(zhí)行,只有當(dāng)解析完樣式表才會(huì)執(zhí)行 JS,所以也可以認(rèn)為這種情況下,CSS 也會(huì)暫停構(gòu)建 DOM。
Load 和 DOMContentLoaded 區(qū)別Load 事件觸發(fā)代表頁面中的 DOM,CSS,JS,圖片已經(jīng)全部加載完畢。
DOMContentLoaded 事件觸發(fā)代表初始的 HTML 被完全加載和解析,不需要等待 CSS,JS,圖片加載。
圖層一般來說,可以把普通文檔流看成一個(gè)圖層。特定的屬性可以生成一個(gè)新的圖層。不同的圖層渲染互不影響,所以對(duì)于某些頻繁需要渲染的建議多帶帶生成一個(gè)新圖層,提高性能。但也不能生成過多的圖層,會(huì)引起反作用。
通過以下幾個(gè)常用屬性可以生成新圖層
3D 變換:translate3d、translateZ
will-change
video、iframe 標(biāo)簽
通過動(dòng)畫實(shí)現(xiàn)的 opacity 動(dòng)畫轉(zhuǎn)換
position: fixed
重繪(Repaint)和回流(Reflow)重繪和回流是渲染步驟中的一小節(jié),但是這兩個(gè)步驟對(duì)于性能影響很大。
重繪是當(dāng)節(jié)點(diǎn)需要更改外觀而不會(huì)影響布局的,比如改變 color 就叫稱為重繪
回流是布局或者幾何屬性需要改變就稱為回流。
回流必定會(huì)發(fā)生重繪,重繪不一定會(huì)引發(fā)回流?;亓魉璧某杀颈戎乩L高的多,改變深層次的節(jié)點(diǎn)很可能導(dǎo)致父節(jié)點(diǎn)的一系列回流。
所以以下幾個(gè)動(dòng)作可能會(huì)導(dǎo)致性能問題:
改變 window 大小
改變字體
添加或刪除樣式
文字改變
定位或者浮動(dòng)
盒模型
很多人不知道的是,重繪和回流其實(shí)和 Event loop 有關(guān)。
當(dāng) Event loop 執(zhí)行完 Microtasks 后,會(huì)判斷 document 是否需要更新。因?yàn)闉g覽器是 60Hz 的刷新率,每 16ms 才會(huì)更新一次。
然后判斷是否有 resize 或者 scroll ,有的話會(huì)去觸發(fā)事件,所以 resize 和 scroll 事件也是至少 16ms 才會(huì)觸發(fā)一次,并且自帶節(jié)流功能。
判斷是否觸發(fā)了 media query
更新動(dòng)畫并且發(fā)送事件
判斷是否有全屏操作事件
執(zhí)行 requestAnimationFrame 回調(diào)
執(zhí)行 IntersectionObserver 回調(diào),該方法用于判斷元素是否可見,可以用于懶加載上,但是兼容性不好
更新界面
以上就是一幀中可能會(huì)做的事情。如果在一幀中有空閑時(shí)間,就會(huì)去執(zhí)行 requestIdleCallback 回調(diào)。
以上內(nèi)容來自于 HTML 文檔
減少重繪和回流
使用 translate 替代 top
使用 visibility 替換 display: none ,因?yàn)榍罢咧粫?huì)引起重繪,后者會(huì)引發(fā)回流(改變了布局)
把 DOM 離線后修改,比如:先把 DOM 給 display:none (有一次 Reflow),然后你修改100次,然后再把它顯示出來
不要把 DOM 結(jié)點(diǎn)的屬性值放在一個(gè)循環(huán)里當(dāng)成循環(huán)里的變量
for(let i = 0; i < 1000; i++) { // 獲取 offsetTop 會(huì)導(dǎo)致回流,因?yàn)樾枰カ@取正確的值 console.log(document.querySelector(".test").style.offsetTop) }
不要使用 table 布局,可能很小的一個(gè)小改動(dòng)會(huì)造成整個(gè) table 的重新布局
動(dòng)畫實(shí)現(xiàn)的速度的選擇,動(dòng)畫速度越快,回流次數(shù)越多,也可以選擇使用 requestAnimationFrame
CSS 選擇符從右往左匹配查找,避免 DOM 深度過深
將頻繁運(yùn)行的動(dòng)畫變?yōu)閳D層,圖層能夠阻止該節(jié)點(diǎn)回流影響別的元素。比如對(duì)于 video 標(biāo)簽,瀏覽器會(huì)自動(dòng)將該節(jié)點(diǎn)變?yōu)閳D層。
文章來源:
https://github.com/InterviewMap/CS-Interview-Knowledge-Map/blob/master/Browser/browser-ch.md
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/108942.html
摘要:是棧,它繼承于。滿二叉樹除了葉結(jié)點(diǎn)外每一個(gè)結(jié)點(diǎn)都有左右子葉且葉子結(jié)點(diǎn)都處在最底層的二叉樹。沒有鍵值相等的節(jié)點(diǎn)。這是數(shù)據(jù)庫選用樹的最主要原因。 在我們學(xué)習(xí)Java的時(shí)候,很多人會(huì)面臨我不知道繼續(xù)學(xué)什么或者面試會(huì)問什么的尷尬情況(我本人之前就很迷茫)。所以,我決定通過這個(gè)開源平臺(tái)來幫助一些有需要的人,通過下面的內(nèi)容,你會(huì)掌握系統(tǒng)的Java學(xué)習(xí)以及面試的相關(guān)知識(shí)。本來是想通過Gitbook的...
本文收集學(xué)習(xí)過程中使用到的資源。 持續(xù)更新中…… 項(xiàng)目地址 https://github.com/abc-club/f... 目錄 vue react react-native Weex typescript Taro nodejs 常用庫 css js es6 移動(dòng)端 微信公眾號(hào) 小程序 webpack GraphQL 性能與監(jiān)控 高質(zhì)文章 趨勢(shì) 動(dòng)效 數(shù)據(jù)結(jié)構(gòu)與算法 js core 代碼規(guī)范...
摘要:的屬性在瀏覽器的控制臺(tái)中,可以直接輸入來查看??梢栽跒g覽器的控制臺(tái)中看出哪些是類型的,下帶綠色對(duì)勾的即是,如圖只要是類型的在控制臺(tái)通過是獲取不到的,也不能進(jìn)行修改。當(dāng)會(huì)話過期或被放棄后,服務(wù)器將終止該會(huì)話。在中,用取代了。 本文由云+社區(qū)發(fā)表 在前端面試中,有一個(gè)必問的問題:請(qǐng)你談?wù)刢ookie和localStorage有什么區(qū)別??? localStorage是H5中的一種瀏覽器本地存...
閱讀 1807·2023-04-26 01:44
閱讀 1222·2021-11-12 10:34
閱讀 1611·2021-09-09 09:33
閱讀 1740·2019-08-30 15:44
閱讀 2903·2019-08-30 13:49
閱讀 2199·2019-08-29 15:26
閱讀 953·2019-08-26 13:30
閱讀 1420·2019-08-23 18:15