日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

web前端面经

發(fā)布時(shí)間:2023/12/8 HTML 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 web前端面经 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

注冊(cè)登錄是怎么實(shí)現(xiàn)的

1.登陸注冊(cè)要做成受控組件,組件定義state,和表單綁定2.redux-saga調(diào)用數(shù)據(jù)請(qǐng)求,發(fā)送action修改數(shù)據(jù),useEffect中dispatch發(fā)送數(shù)據(jù)請(qǐng)求,后端比對(duì)用戶名是否重復(fù),返回state3.前端根據(jù)返回的信息成功跳轉(zhuǎn)登陸頁4.登陸發(fā)送數(shù)據(jù)請(qǐng)求,數(shù)據(jù)庫對(duì)比用戶名密碼是否正確, 根據(jù)后端返回的結(jié)果進(jìn)入首頁5.setCookie將用戶登錄名密碼token存cookie中 通過JWT(Json web token)6.免密登陸 getCookie獲取token 發(fā)給后端對(duì)比 根據(jù)返回結(jié)果是否自動(dòng)登陸7.注冊(cè)通過Ant Design ,validator中進(jìn)行表單正則的驗(yàn)證8.用戶體驗(yàn) 注冊(cè)的時(shí)候跳轉(zhuǎn)其他頁面的時(shí)候給用戶提示是否需要跳轉(zhuǎn),避免因?yàn)樘D(zhuǎn)后導(dǎo)致注冊(cè)信息沒有了 用組件內(nèi)后置守衛(wèi)做如果輸入框都沒有填信息,不攔截跳轉(zhuǎn)如果用戶輸入信息,彈窗提示,點(diǎn)確定,跳轉(zhuǎn),點(diǎn)取消,不跳轉(zhuǎn)

項(xiàng)目中遇到什么困難,怎么解決的?

1.react中配置二級(jí)路由 地址變化 但是界面不更新 使用dva/router中的withRouter高階組件解決的2.圖表聯(lián)動(dòng)怎么實(shí)現(xiàn)我們只需要把當(dāng)前被選中圖表的事件,直接發(fā)給其他圖表即可,然后判斷被選中的圖表是哪個(gè)作為區(qū)分onTouchEvent(event)普通事件傳遞3.產(chǎn)品經(jīng)理要求智能匹配產(chǎn)品 找網(wǎng)上類似功能的網(wǎng)站 查看源碼 和主管討論需要一個(gè)設(shè)計(jì)一個(gè)投資習(xí)慣和風(fēng)險(xiǎn)承受能力測試,從后端獲取這個(gè)客戶測試的結(jié)果 以及客戶平常投資的習(xí)慣 生成不同的關(guān)鍵字根據(jù)關(guān)鍵字從數(shù)據(jù)庫中匹配產(chǎn)品 展示界面4.后臺(tái)管理系統(tǒng)遇到遇到什么奇葩的需求

后臺(tái)管理系統(tǒng)和普通App面向用戶的區(qū)別

toB和toC的項(xiàng)目面向企業(yè)內(nèi)部和面向用戶的項(xiàng)目的區(qū)別后臺(tái)管理系統(tǒng)權(quán)限比較細(xì) App高并發(fā)比較多 做性能優(yōu)化

正則表達(dá)式

\d 匹配數(shù)字 \D 匹配非數(shù)字 \w 匹配數(shù)字字母下劃線 \W 匹配非數(shù)字字母下劃線 \n 匹配一個(gè)換行符 \s 匹配任何不可見字符包括空格、制表符、換頁符等等 \S 匹配任何可見字符 ^ 匹配輸入字行首 $匹配輸入行尾 *(0到多次)匹配前面的子表達(dá)式任意次 +(1到多) 匹配前面的子表達(dá)式一次或多次(大于等于1次) ?(0或1)匹配前面的子表達(dá)式零次或一次 {n}n是一個(gè)非負(fù)整數(shù),匹配確定的n次 {n,}n是一個(gè)非負(fù)整數(shù)。至少匹配n次

Ajax

我對(duì) ajax 的理解是,它是一種異步通信的方法,通過直接由 js 腳本向服務(wù)器發(fā)起 http 通信,然后根據(jù)服務(wù)器返回的數(shù)據(jù),更新網(wǎng)頁的相應(yīng)部分,而不用刷新整個(gè)頁面的一種方法。 創(chuàng)建步驟:創(chuàng)建xhr對(duì)象->配置Ajax請(qǐng)求地址通過open方法->發(fā)送請(qǐng)求通過send方法->監(jiān)聽請(qǐng)求,接收響應(yīng) //1:創(chuàng)建Ajax對(duì)象 var xhr = window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHTTP');// 兼容IE6及以下版本 //2:配置 Ajax請(qǐng)求地址 xhr.open('get','index.xml',true); //3:發(fā)送請(qǐng)求 xhr.send(null); // 嚴(yán)謹(jǐn)寫法 //4:監(jiān)聽請(qǐng)求,接受響應(yīng) xhr.onreadysatechange=function(){if(xhr.readySate==4&&xhr.status==200 || xhr.status==304)console.log(xhr.responseXML) }

js 延遲加載的方式

js 的加載、解析和執(zhí)行會(huì)阻塞頁面的渲染過程,因此我們希望 js 腳本能夠盡可能的延遲加載,提高頁面的渲染速度。 我了解到的幾種方式是:1、將 js 腳本放在文檔的底部,來使 js 腳本盡可能的在最后來加載執(zhí)行。 2、給 js 腳本添加 defer 屬性,這個(gè)屬性會(huì)讓腳本的加載與文檔的解析同步解析,然后在文檔解析完成后再執(zhí)行這個(gè)腳本文件,這樣的話就能使頁面的渲染不被阻塞。多個(gè)設(shè)置了 defer 屬性的腳本按規(guī)范來說最后是順序執(zhí)行的,但是在一些瀏覽器中可能不是這樣。 3、給 js 腳本添加 async屬性,這個(gè)屬性會(huì)使腳本異步加載,不會(huì)阻塞頁面的解析過程,但是當(dāng)腳本加載完成后立即執(zhí)行 js腳本,這個(gè)時(shí)候如果文檔沒有解析完成的話同樣會(huì)阻塞。多個(gè) async 屬性的腳本的執(zhí)行順序是不可預(yù)測的,一般不會(huì)按照代碼的順序依次執(zhí)行。 4、動(dòng)態(tài)創(chuàng)建 DOM 標(biāo)簽的方式,我們可以對(duì)文檔的加載事件進(jìn)行監(jiān)聽,當(dāng)文檔加載完成后再動(dòng)態(tài)的創(chuàng)建 script 標(biāo)簽來引入 js 腳本。

模塊化開發(fā)的理解

我對(duì)模塊的理解是,一個(gè)模塊是實(shí)現(xiàn)一個(gè)特定功能的一組方法。在最開始的時(shí)候,js 只實(shí)現(xiàn)一些簡單的功能, 所以并沒有模塊的概念,但隨著程序越來越復(fù)雜,代碼的模塊化開發(fā)變得越來越重要。由于函數(shù)具有獨(dú)立作用域的特點(diǎn),最原始的寫法是使用函數(shù)來作為模塊,幾個(gè)函數(shù)作為一個(gè)模塊, 但是這種方式容易造成全局變量的污染,并且模塊間沒有聯(lián)系。后面提出了對(duì)象寫法,通過將函數(shù)作為一個(gè)對(duì)象的方法來實(shí)現(xiàn),這樣解決了直接使用函數(shù)作為模塊的一些缺點(diǎn), 但是這種辦法會(huì)暴露所有的所有的模塊成員,外部代碼可以修改內(nèi)部屬性的值。現(xiàn)在最常用的是立即執(zhí)行函數(shù)的寫法,通過利用閉包來實(shí)現(xiàn)模塊私有作用域的建立,同時(shí)不會(huì)對(duì)全局作用域造成污染。

js 的幾種模塊規(guī)范

js 中現(xiàn)在比較成熟的有四種模塊加載方案:第一種是 CommonJS 方案,它通過 require 來引入模塊,通過 module.exports 定義模塊的輸出接口。這種模塊加載方案是服務(wù)器端的解決方案,它是以同步的方式來引入模塊的,因?yàn)樵诜?wù)端文件都存儲(chǔ)在本地磁盤,所以讀取非常快,所以以同步的方式加載沒有問題。但如果是在瀏覽器端,由于模塊的加載是使用網(wǎng)絡(luò)請(qǐng)求,因此使用異步加載的方式更加合適。第二種是 AMD 方案,這種方案采用異步加載的方式來加載模塊,模塊的加載不影響后面語句的執(zhí)行,所有依賴這個(gè)模塊的語句都定義在一個(gè)回調(diào)函數(shù)里,等到加載完成后再執(zhí)行回調(diào)函數(shù)。require.js 實(shí)現(xiàn)了 AMD 規(guī)范。第三種是 CMD 方案,這種方案和 AMD 方案都是為了解決異步模塊加載的問題,sea.js 實(shí)現(xiàn)了 CMD 規(guī)范。它和require.js的區(qū)別在于模塊定義時(shí)對(duì)依賴的處理不同和對(duì)依賴模塊的執(zhí)行時(shí)機(jī)的處理不同。第四種方案是 ES6 提出的方案,使用 import 和 export 的形式來導(dǎo)入導(dǎo)出模塊。

AMD和CMD規(guī)范的區(qū)別?

它們之間的主要區(qū)別有兩個(gè)方面。 第一個(gè)方面是在模塊定義時(shí)對(duì)依賴的處理不同。AMD推崇依賴前置,在定義模塊的時(shí)候就要聲明其依賴的模塊。而 CMD 推崇就近依賴,只有在用到某個(gè)模塊的時(shí)候再去 require。 第二個(gè)方面是對(duì)依賴模塊的執(zhí)行時(shí)機(jī)處理不同。首先 AMD 和 CMD 對(duì)于模塊的加載方式都是異步加載,不過它們的區(qū)別在于模塊的執(zhí)行時(shí)機(jī),AMD 在依賴模塊加載完成后就直接執(zhí)行依賴模塊,依賴模塊的執(zhí)行順序和我們書寫的順序不一定一致。而 CMD在依賴模塊加載完成后并不執(zhí)行,只是下載而已,等到所有的依賴模塊都加載好后,進(jìn)入回調(diào)函數(shù)邏輯,遇到 require 語句 的時(shí)候才執(zhí)行對(duì)應(yīng)的模塊,這樣模塊的執(zhí)行順序就和我們書寫的順序保持一致了。

ES6模塊與CommonJS 模塊、AMD、CMD的差異

1.CommonJS 模塊輸出的是一個(gè)值的拷貝, ES6 模塊輸出的是值的引用。 CommonJS 模塊輸出的是值的,也就是說,一旦輸出一個(gè)值,模塊內(nèi)部的變化就影響不到這個(gè)值。 ES6 模塊的運(yùn)行機(jī)制與 CommonJS 不一樣。JS 引擎對(duì)腳本靜態(tài)分析的時(shí)候,遇到模塊加載命令 import,就會(huì)生成一個(gè)只讀引用。等到腳本真正執(zhí)行時(shí),再根據(jù)這個(gè)只讀引用,到被加載的那個(gè)模塊里面去取值。 2.CommonJS 模塊是運(yùn)行時(shí)加載,ES6 模塊是編譯時(shí)輸出接口。CommonJS 模塊就是對(duì)象,即在輸入時(shí)是先加載整個(gè)模塊,生成一個(gè)對(duì)象,然后再從這個(gè)對(duì)象上面讀取方法,這種加載稱為“運(yùn)行時(shí)加載”。 而 ES6 模塊不是對(duì)象,它的對(duì)外接口只是一種靜態(tài)定義,在代碼靜態(tài)解析階段就會(huì)生成。

requireJS的核心原理

require.js 的核心原理是通過動(dòng)態(tài)創(chuàng)建 script 腳本來異步引入模塊,然后對(duì)每個(gè)腳本的 load 事件進(jìn)行監(jiān)聽,如果每個(gè)腳本都加載完成了,再調(diào)用回調(diào)函數(shù)

js的原理(運(yùn)行機(jī)制)

首先js是單線程運(yùn)行的,在代碼執(zhí)行的時(shí)候,通過將不同函數(shù)的執(zhí)行上下文壓入執(zhí)行棧中來保證代碼的有序執(zhí)行。 在執(zhí)行同步代碼的時(shí)候,如果遇到了異步事件,js引擎并不會(huì)一直等待其返回結(jié)果,而是會(huì)將這個(gè)事件掛起,繼續(xù)執(zhí)行執(zhí)行棧中的其他任務(wù)所有任務(wù)可以分成兩種,一種是同步任務(wù)(synchronous),另一種是異步任務(wù)(asynchronous)。 同步任務(wù)指的是,在主線程上排隊(duì)執(zhí)行的任務(wù),只有前一個(gè)任務(wù)執(zhí)行完畢,才能執(zhí)行后一個(gè)任務(wù); 異步任務(wù)指的是,不進(jìn)入主線程、而進(jìn)入"任務(wù)隊(duì)列"(task queue)的任務(wù),只有等主線程任務(wù)執(zhí)行完畢,"任務(wù)隊(duì)列"開始通知主線程,請(qǐng)求執(zhí)行任務(wù),該任務(wù)才會(huì)進(jìn)入主線程執(zhí)行。當(dāng)同步事件執(zhí)行完畢后,再將異步事件對(duì)應(yīng)的回調(diào)加入到與當(dāng)前執(zhí)行棧中不同的另一個(gè)任務(wù)隊(duì)列中等待執(zhí)行。 任務(wù)隊(duì)列可以分為宏任務(wù)對(duì)列和微任務(wù)對(duì)列,當(dāng)當(dāng)前執(zhí)行棧中的事件執(zhí)行完畢后,js 引擎首先會(huì)判斷微任務(wù)對(duì)列中是否有任務(wù)可以執(zhí)行,如果有就將微任務(wù)隊(duì)首的事件壓入棧中執(zhí)行。 當(dāng)微任務(wù)對(duì)列中的任務(wù)都執(zhí)行完成后再去判斷宏任務(wù)對(duì)列中的任務(wù)。異步運(yùn)行機(jī)制如下: (1)所有同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧(execution context stack)。 (2)主線程之外,還存在一個(gè)"任務(wù)隊(duì)列"(task queue)。只要異步任務(wù)有了運(yùn)行結(jié)果,就在"任務(wù)隊(duì)列"之中放置一個(gè)事件。 (3)一旦"執(zhí)行棧"中的所有同步任務(wù)執(zhí)行完畢,系統(tǒng)就會(huì)讀取"任務(wù)隊(duì)列",看看里面有哪些事件。那些對(duì)應(yīng)的異步任務(wù),于是結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開始執(zhí)行。 (4)主線程不斷重復(fù)上面的第三步。

arguments 的對(duì)象

arguments對(duì)象是函數(shù)中傳遞的參數(shù)值的集合。它是一個(gè)類似數(shù)組的對(duì)象,因?yàn)樗幸粋€(gè)length屬性, 我們可以使用數(shù)組索引表示法arguments[1]來訪問單個(gè)值,但它沒有數(shù)組中的內(nèi)置方法, 如:forEach、reduce、filter和map。我們可以使用Array.prototype.slice將arguments對(duì)象轉(zhuǎn)換成一個(gè)數(shù)組。Array.prototype.slice.call(arguments)

V8 引擎的垃圾回收機(jī)制

v8的垃圾回收機(jī)制基于分代回收機(jī)制,這個(gè)機(jī)制又基于世代假說,這個(gè)假說有兩個(gè)特點(diǎn),一是新生的對(duì)象容易早死,另一個(gè)是不死的對(duì)象會(huì)活得更久。基于這個(gè)假說,v8 引擎將內(nèi)存分為了新生代和老生代。 新創(chuàng)建的對(duì)象或者只經(jīng)歷過一次的垃圾回收的對(duì)象被稱為新生代。經(jīng)歷過多次垃圾回收的對(duì)象被稱為老生代。 新生代被分為 From 和 To 兩個(gè)空間,To 一般是閑置的。當(dāng) From 空間滿了的時(shí)候會(huì)執(zhí)行 Scavenge(斯蓋V橘) 算法進(jìn)行垃圾回收。當(dāng)我們執(zhí)行垃圾回收算法的時(shí)候應(yīng)用邏輯將會(huì)停止,等垃圾回收結(jié)束后再繼續(xù)執(zhí)行。這個(gè)算法分為三步: (1)首先檢查 From 空間的存活對(duì)象,如果對(duì)象存活則判斷對(duì)象是否滿足晉升到老生代的條件,如果滿足條件則晉升到老生代。如果不滿足條件則移動(dòng) To 空間。 (2)如果對(duì)象不存活,則釋放對(duì)象的空間。 (3)最后將 From 空間和 To 空間角色進(jìn)行交換。 新生代對(duì)象晉升到老生代有兩個(gè)條件: (1)第一個(gè)是判斷是對(duì)象否已經(jīng)經(jīng)過一次 Scavenge 回收。若經(jīng)歷過,則將對(duì)象從 From 空間復(fù)制到老生代中;若沒有經(jīng)歷,則復(fù)制到 To 空間。 (2)第二個(gè)是 To 空間的內(nèi)存使用占比是否超過限制。當(dāng)對(duì)象從 From 空間復(fù)制到 To 空間時(shí),若 To 空間使用超過 25%,則對(duì)象直接晉升到老生代中。設(shè)置 25% 的原因主要是因?yàn)樗惴ńY(jié)束后,兩個(gè)空間結(jié)束后會(huì)交換位置,如果 To 空間的內(nèi)存太小,會(huì)影響后續(xù)的內(nèi)存分配。老生代采用了標(biāo)記清除法和標(biāo)記壓縮法。 標(biāo)記清除法首先會(huì)對(duì)內(nèi)存中存活的對(duì)象進(jìn)行標(biāo)記,標(biāo)記結(jié)束后清除掉那些沒有標(biāo)記的對(duì)象。由于標(biāo)記清除后會(huì)造成很多的內(nèi)存碎片,不便于后面的內(nèi)存分配。所以了解決內(nèi)存碎片的問題引入了標(biāo)記壓縮法。 由于在進(jìn)行垃圾回收的時(shí)候會(huì)暫停應(yīng)用的邏輯,對(duì)于新生代方法由于內(nèi)存小,每次停頓的時(shí)間不會(huì)太長,但對(duì)于老生代來說每次垃圾回收的時(shí)間長,停頓會(huì)造成很大的影響。 為了解決這個(gè)問題 V8 引入了增量標(biāo)記的方法,將一次停頓進(jìn)行的過程分為了多步,每次執(zhí)行完一小步就讓運(yùn)行邏輯執(zhí)行一會(huì),就這樣交替運(yùn)行

垃圾回收機(jī)制的兩種方法

現(xiàn)在各大瀏覽器通常用采用的垃圾回收有兩種方法:標(biāo)記清除、引用計(jì)數(shù)。1、標(biāo)記清除這是javascript中最常用的垃圾回收方式。當(dāng)變量進(jìn)入執(zhí)行環(huán)境是,就標(biāo)記這個(gè)變量為“進(jìn)入環(huán)境”。從邏輯上講,永遠(yuǎn)不能釋放進(jìn)入環(huán)境的變量所占用的內(nèi)存,因?yàn)橹灰獔?zhí)行流進(jìn)入相應(yīng)的環(huán)境,就可能會(huì)用到他們。當(dāng)變量離開環(huán)境時(shí),則將其標(biāo)記為“離開環(huán)境”。垃圾收集器在運(yùn)行的時(shí)候會(huì)給存儲(chǔ)在內(nèi)存中的所有變量都加上標(biāo)記。然后,它會(huì)去掉環(huán)境中的變量以及被環(huán)境中的變量引用的標(biāo)記。而在此之后再被加上標(biāo)記的變量將被視為準(zhǔn)備刪除的變量,原因是環(huán)境中的變量已經(jīng)無法訪問到這些變量了。最后。垃圾收集器完成內(nèi)存清除工作,銷毀那些帶標(biāo)記的值,并回收他們所占用的內(nèi)存空間。2、引用計(jì)數(shù)另一種不太常見的垃圾回收策略是引用計(jì)數(shù)。引用計(jì)數(shù)的含義是跟蹤記錄每個(gè)值被引用的次數(shù)。當(dāng)聲明了一個(gè)變量并將一個(gè)引用類型賦值給該變量時(shí),則這個(gè)值的引用次數(shù)就是1。相反,如果包含對(duì)這個(gè)值引用的變量又取得了另外一個(gè)值,則這個(gè)值的引用次數(shù)就減1。當(dāng)這個(gè)引用次數(shù)變成0時(shí),則說明沒有辦法再訪問這個(gè)值了,因而就可以將其所占的內(nèi)存空間給收回來。這樣,垃圾收集器下次再運(yùn)行時(shí),它就會(huì)釋放那些引用次數(shù)為0的值所占的內(nèi)存。

會(huì)造成內(nèi)存泄漏的操作

1.意外的全局變量 2.被遺忘的計(jì)時(shí)器或回調(diào)函數(shù) 3.脫離 DOM 的引用 4.閉包第一種情況是我們由于使用未聲明的變量,而意外的創(chuàng)建了一個(gè)全局變量,而使這個(gè)變量一直留在內(nèi)存中無法被回收。 第二種情況是我們?cè)O(shè)置了setInterval定時(shí)器,而忘記取消它,如果循環(huán)函數(shù)有對(duì)外部變量的引用的話,那么這個(gè)變量會(huì)被一直留在內(nèi)存中,而無法被回收。 第三種情況是我們獲取一個(gè)DOM元素的引用,而后面這個(gè)元素被刪除,由于我們一直保留了對(duì)這個(gè)元素的引用,所以它也無法被回收。 第四種情況是不合理的使用閉包,從而導(dǎo)致某些變量一直被留在內(nèi)存當(dāng)中。

ECMAScript(ES)

ECMAScript 是編寫腳本語言的標(biāo)準(zhǔn),ECMA(European Computer Manufacturers Association)規(guī)定一下他的標(biāo)準(zhǔn),因?yàn)楫?dāng)時(shí)有java語言了,又想強(qiáng)調(diào)這個(gè)東西是讓ECMA這個(gè)人定的規(guī)則,所以就這樣一個(gè)神奇的東西誕生了,這個(gè)東西的名稱就叫做ECMAScript。 javaScript = ECMAScript + DOM + BOM

ES2015(ES6)新特性

塊作用域 類 箭頭函數(shù) 模板字符串 對(duì)象解構(gòu) Promise 模塊 Symbol 代理(proxy)Set 函數(shù)默認(rèn)參數(shù) rest 擴(kuò)展運(yùn)算符 數(shù)組和對(duì)象的擴(kuò)展

ES2016(ES7)新特性

求冪運(yùn)算符(**)(因顆錄此) Array.prototype.includes()方法數(shù)組原型的方法,查找一個(gè)數(shù)值是否在數(shù)組中,只能判斷一些簡單類型的數(shù)據(jù),對(duì)于復(fù)雜類型的數(shù)據(jù)無法判斷。該方法接受兩個(gè)參數(shù),分別是查詢的數(shù)據(jù)和初始的查詢索引值。

ES2017(ES8)新特性

async await函數(shù)參數(shù)列表結(jié)尾允許逗號(hào)es2017允許函數(shù)對(duì)象的定義調(diào)用時(shí)參數(shù)可以加入尾逗號(hào),以及json對(duì)象array對(duì)象都允許Object.values()values: [obj],返回obj自身可枚舉屬性的屬性值的集合(安吹斯) Object.entries()entries:[obj], 與values類似,返回的一個(gè)2元素的數(shù)組Object.getOwnPropertyDescriptors()getOwnpropertyDescriptors: [obj],返回obj對(duì)象的屬性描述符(get 哦 潑破踢 迪斯虧不踢斯) String padding: padStart()和padEnd(),填充字符串達(dá)到當(dāng)前長度在字符串首位開始添加string直到滿足length為止并返回新的字符串ShareArrayBuffer和Atomics對(duì)象,用于從共享內(nèi)存位置讀取和寫入 (夏爾 啊銳 八法兒) (啊偷沒此)

ES2018(ES9)新特性

異步迭代 Promise.finally()(飯的嘞) Rest/Spread 屬性 (銳斯特)(斯破銳的) 正則表達(dá)式命名捕獲組(Regular Expression Named Capture Groups) 正則表達(dá)式反向斷言(lookbehind) 正則表達(dá)式dotAll模式 正則表達(dá)式 Unicode 轉(zhuǎn)義 (右內(nèi)扣的) 非轉(zhuǎn)義序列的模板字符串

ES2019(ES10)新特性

行分隔符(U + 2028)和段分隔符(U + 2029)符號(hào)現(xiàn)在允許在字符串文字中,與JSON匹配 更加友好的JSON.stringify 新增了Array的flat()方法和flatMap()方法 新增了String的trimStart()方法和trimEnd()方法 Object.fromEntries() Symbol.prototype.description String.prototype.matchAll Function.prototype.toString()現(xiàn)在返回精確字符,包括空格和注釋 簡化try{} catch{},修改catch綁定 新的基本數(shù)據(jù)類型BigInt globalThis import() Legacy RegEx 私有的實(shí)例方法和訪問器

ES2020(ES11)新特性

私有變量ES11在類中新增私有變量控制符#,在內(nèi)部變量或者函數(shù)前添加一個(gè)hash符號(hào)#,可以將它們?cè)O(shè)置為私有屬性,只能在類的內(nèi)部可以使用。 空值合并運(yùn)算符空值合并操作符就是 ?? :如果左側(cè)的值為null或者undefined就返回左側(cè)的值,如果沒有就返回右側(cè)的值 可選鏈操作符可選鏈操作符 (?.) :如果左側(cè)表達(dá)式有值,就會(huì)繼續(xù)訪問右側(cè)的字段 BigInt使用BigInt的方式有兩種:1.在數(shù)字后面加n2.使用BigInt函數(shù) 動(dòng)態(tài)導(dǎo)入globalThis提供一種標(biāo)準(zhǔn)化的方式去訪問全局對(duì)象,可以在任意上下文中獲取全局對(duì)象自身,并且不用擔(dān)心環(huán)境的問題 Promise.all缺陷與Promise.allSettledpromise.all可以并發(fā)執(zhí)行異步任務(wù),如果其中某個(gè)任務(wù)執(zhí)行出現(xiàn)了異常,所有任務(wù)都會(huì)over,Promise會(huì)直接進(jìn)入reject狀態(tài)使用Promise.allSettled,它會(huì)創(chuàng)建一個(gè)新的promise,在所有promise完成后返回一個(gè)包含每個(gè)promise結(jié)果的數(shù)組

var,let和const的區(qū)別

1.var聲明的變量會(huì)掛載在window上,而let和const聲明的變量不會(huì): 2.var聲明變量存在變量提升,let和const不存在變量提升 3.let和const聲明形成塊作用域 4.同一作用域下let和const不能聲明同名變量,而var可以const 一旦聲明必須賦值,不能使用null占位。聲明后不能再修改如果聲明的是復(fù)合類型數(shù)據(jù),可以修改其屬性暫存死區(qū) var a = 100; if(1){a = 10;//在當(dāng)前塊作用域中存在a使用let/const聲明的情況下,給a賦值10時(shí),只會(huì)在當(dāng)前作用域找變量a,// 而這時(shí),還未到聲明時(shí)候,所以控制臺(tái)Error:a is not definedlet a = 1; }

var和let在for循環(huán)的一些不同表現(xiàn)

在var中執(zhí)行的時(shí)候: 因?yàn)関ar是沒有塊級(jí)作用域的,所以在for循環(huán)中聲明的i會(huì)存在于test()函數(shù)作用域中。每一次for循環(huán)就會(huì)聲明一次i,但后面聲明的變量會(huì)覆蓋前面聲明的變量。 在let中執(zhí)行的時(shí)候:因?yàn)閴K級(jí)作用域的原因,let聲明的i都會(huì)存在于for塊級(jí)作用域中,每一次for循環(huán)都會(huì)生成一個(gè)塊級(jí)作用域。

箭頭函數(shù)

箭頭函數(shù)表達(dá)式的語法比函數(shù)表達(dá)式更簡潔箭頭函數(shù)沒有自己的this值。箭頭函數(shù)里的this指向的是父級(jí)的this. 箭頭函數(shù)表達(dá)式更適用于那些本來需要匿名函數(shù)的地方,并且它不能用作構(gòu)造函數(shù)。在箭頭函數(shù)版本中,當(dāng)只有一個(gè)表達(dá)式或值需要返回,我們只需要()括號(hào), 不需要 return 語句,箭頭函數(shù)就會(huì)有一個(gè)隱式的返回。如果我們?cè)谝粋€(gè)箭頭函數(shù)中有一個(gè)參數(shù),則可以省略括號(hào)。箭頭函數(shù)不能訪問arguments對(duì)象。所以調(diào)用第一個(gè)getArgs函數(shù)會(huì)拋出一個(gè)錯(cuò)誤。 相反,我們可以使用rest參數(shù)來獲得在箭頭函數(shù)中傳遞的所有參數(shù)。

模板字符串

模板字符串是在 JS 中創(chuàng)建字符串的一種新方法。我們可以通過使用反引號(hào)使模板字符串化。在ES5版本中,我們需要添加\n以在字符串中添加新行。在模板字符串中,我們不需要這樣做。在 ES5 版本中,如果需要在字符串中添加表達(dá)式或值,則需要使用`+`運(yùn)算符。 在模板字符串s中,我們可以使用${expr}嵌入一個(gè)表達(dá)式,這使其比 ES5 版本更整潔。

對(duì)象解構(gòu)

對(duì)象解構(gòu)是從對(duì)象或數(shù)組中獲取或提取值的一種新的、更簡潔的方法 我們還可以為屬性取別名 let { firstName: fName, position } = employee; 當(dāng)然如果屬性值為 undefined 時(shí),我們還可以指定默認(rèn)值 let { firstName = "Mark" } = employee;

Set及應(yīng)用場景

一、創(chuàng)建Set對(duì)象實(shí)例 Set 對(duì)象允許你存儲(chǔ)任何類型的唯一值,無論是原始值或者是對(duì)象引用 1.構(gòu)造函數(shù) (伊特波)語法:new Set([iterable])參數(shù):iterable 如果傳遞一個(gè)可迭代對(duì)象,它的所有元素將被添加到新的Set中;如果不指定此參數(shù)或其值為null,則新的 Set為空二、Set實(shí)例屬性size屬性將會(huì)返回Set對(duì)象中元素的個(gè)數(shù)三、Set實(shí)例方法 1.add() 方法用來向一個(gè) Set 對(duì)象的末尾添加一個(gè)指定的值語法:mySet.add(value)參數(shù):value 必需,需要添加到 Set 對(duì)象的元素的值 2.delete() 方法可以從一個(gè) Set 對(duì)象中刪除指定的元素語法:mySet.delete(value)參數(shù):value 將要?jiǎng)h除的元素返回值:成功刪除返回 true,否則返回 false 3.clear() 方法用來清空一個(gè) Set 對(duì)象中的所有元素語法:mySet.clear() 4.has() 方法返回一個(gè)布爾值來指示對(duì)應(yīng)的值value是否存在Set對(duì)象中語法:mySet.has(value)參數(shù):value 必須,是否存在于Set的值返回值:如果指定的值(value)存在于Set對(duì)象當(dāng)中,返回true; 否則返回 false 5.entries() (安吹斯)語法:mySet.entries()返回值:一個(gè)新的包含 [value, value] 形式的數(shù)組迭代器對(duì)象,value 是給定集合中的每個(gè)元素,迭代器 對(duì)象元素的順序即集合對(duì)象中元素插入的順序 6.values()語法:mySet.values() 或者 mySet.keys()返回值:返回一個(gè) Iterator(因特瑞特) 對(duì)象,這個(gè)對(duì)象以插入Set對(duì)象的順序包含了原 Set 對(duì)象里的每個(gè)元素 7.forEach()語法:mySet.forEach(callback[, thisArg]) (this傲歌)參數(shù):callback 每個(gè)元素都會(huì)執(zhí)行的函數(shù)thisArg 當(dāng)執(zhí)行callback函數(shù)時(shí)候,可以當(dāng)作this來使用 5、什么是WeakSet()? 和Set結(jié)構(gòu)類似,也是不重復(fù)的值的集合,但WeakSet的成員只能是對(duì)象(null 除外)。 而且 WeakMap 的鍵名所指向的對(duì)象,不計(jì)入垃圾回收機(jī)制。應(yīng)用場景: 1、簡單數(shù)組去重 2、JSON數(shù)組去重JSON數(shù)組是比較常見的一種數(shù)據(jù)結(jié)構(gòu),形如[{…},…{…}]假如你需要統(tǒng)計(jì)某個(gè)屬性中不同的值。step1:先使用.map將JSON數(shù)組變成簡單數(shù)組,然后用set執(zhí)行去重step2: 由于生成的Set屬于可迭代對(duì)象,所以可以使用數(shù)組解構(gòu)符進(jìn)行解構(gòu) 3、二維數(shù)組去重我們可以將Set用作存儲(chǔ)每項(xiàng)的唯一值,結(jié)合reduce進(jìn)行對(duì)比,得出無重復(fù)的項(xiàng)目。當(dāng)然,上面的代碼缺點(diǎn)還是不少的。因?yàn)橹皇呛唵蔚貙⑵滢D(zhuǎn)變成字符串作為對(duì)比的鍵,所以不能區(qū)分[1,2]、[‘1’ ,‘2’]、[‘1,2’]等子數(shù)組。 4、數(shù)組之間的對(duì)比Set的特性不單單可以可以用于單數(shù)組,對(duì)于數(shù)組之間的比較也是十分在行。什么是WeakSet()?和Set結(jié)構(gòu)類似,也是不重復(fù)的值的集合,但WeakSet的成員只能是對(duì)象。WeakSet的API:add() //增delete() //刪has() //是否存在為什么WeakSet不可遍歷?因?yàn)閃eakSet的成員都是弱引用,隨時(shí)可能消失,成員是不穩(wěn)定的。WeakSet的用處:使用ws儲(chǔ)存DOM節(jié)點(diǎn),就不用擔(dān)心節(jié)點(diǎn)從文檔移除時(shí),會(huì)引發(fā)內(nèi)存泄漏(即在被移除的節(jié)點(diǎn)上綁定的click等事件)。

Proxy

Proxy 可以理解成,在目標(biāo)對(duì)象之前架設(shè)一層“攔截”,外界對(duì)該對(duì)象的訪問,都必須先通過這層攔截,因此提供了一種機(jī)制,可以對(duì)外界的訪問進(jìn)行過濾和改寫。Proxy 這個(gè)詞的原意是代理,用在這里表示由它來“代理”某些操作,可以譯為“代理器”

函數(shù)式編程

函數(shù)式編程(通常縮寫為FP)是通過編寫純函數(shù),避免共享狀態(tài)、可變數(shù)據(jù)、副作用 來構(gòu)建軟件的過程。數(shù)式編程是聲明式 的而不是命令式 的,應(yīng)用程序的狀態(tài)是通過純函數(shù)流動(dòng)的。與面向?qū)ο缶幊绦纬蓪?duì)比,面向?qū)ο笾袘?yīng)用程序的狀態(tài)通常與對(duì)象中的方法共享和共處。 函數(shù)式編程是一種編程范式 ,這意味著它是一種基于一些基本的定義原則(如上所列)思考軟件構(gòu)建的方式。當(dāng)然,編程范式的其他示例也包括面向?qū)ο缶幊毯瓦^程編程。 函數(shù)式的代碼往往比命令式或面向?qū)ο蟮拇a更簡潔,更可預(yù)測,更容易測試

高階函數(shù)

首先高階函數(shù)肯定是函數(shù),不同的是輸入的參數(shù)和返回的值這兩項(xiàng)中的一項(xiàng)必須是函數(shù)才能叫高階函數(shù)。 這個(gè)問題在回答的時(shí)候可以稍微拓展一下,介紹一下常用的的高階函數(shù), 比如:map、flatMap、filter、reduce、fold。

為什么函數(shù)被稱為一等公民

在JavaScript中,函數(shù)不僅擁有一切傳統(tǒng)函數(shù)的使用方式(聲明和調(diào)用),而且可以做到像簡單值一樣:賦值(var func = function(){})、 傳參(function func(x,callback){callback();})、 返回(function(){return function(){}}),這樣的函數(shù)也稱之為第一級(jí)函數(shù)(First-class Function)。不僅如此,JavaScript中的函數(shù)還充當(dāng)了類的構(gòu)造函數(shù)的作用,同時(shí)又是一個(gè)Function類的實(shí)例(instance)(因斯疼斯)。這樣的多重身份讓JavaScript的函數(shù)變得非常重要。

. new操作符的實(shí)現(xiàn)

1、創(chuàng)建一個(gè)空對(duì)象 {} 2、將構(gòu)造函數(shù)中的this指向新創(chuàng)建的對(duì)象 (原型鏈)obj.__proto__ = Dog.prototype // 設(shè)置原型鏈 3、鏈接該對(duì)象到另一個(gè)對(duì)象 __proto__ 4、如果該函數(shù)沒有返回對(duì)象,則返回this

回調(diào)函數(shù)?回調(diào)函數(shù)有什么缺點(diǎn)

回調(diào)函數(shù)是一個(gè)匿名函數(shù),它作為一個(gè)參數(shù)傳遞給其他的代碼,其作用是在需要的時(shí)候方便調(diào)用這段(回調(diào)函數(shù))代碼。可以讓異步代碼同步執(zhí)行。 回調(diào)函數(shù)有一個(gè)致命的弱點(diǎn),就是容易寫出回調(diào)地獄(Callback hell)

instanceof的原理

instanceof 可以正確的判斷對(duì)象的類型,因?yàn)閮?nèi)部機(jī)制是通過判斷對(duì)象的原型鏈中是不是能找到類型的 prototype。 實(shí)現(xiàn) instanceof:首先獲取類型的原型 然后獲得對(duì)象的原型 然后一直循環(huán)判斷對(duì)象的原型是否等于類型的原型,直到對(duì)象原型為 null,因?yàn)樵玩溩罱K為 nullfunction myInstanceof(left, right) {let prototype = right.prototypeleft = left.__proto__while (true) {if (left === null || left === undefined)return falseif (prototype === left)return trueleft = left.__proto__} }

設(shè)計(jì)模式

設(shè)計(jì)模式是一套被反復(fù)使用的、多數(shù)人知曉的、經(jīng)過分類編目的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。使用設(shè)計(jì)模式是為了重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 1、單例模式 2、工廠模式 3、觀察者模式 4、代理模式 5、策略模式 6、迭代器模式單例模式(Singleton Pattern)單例模式中Class的實(shí)例個(gè)數(shù)最多為1。當(dāng)需要一個(gè)對(duì)象去貫穿整個(gè)系統(tǒng)執(zhí)行某些任務(wù)時(shí),單例模式就派上了用場。而除此之外的場景盡量避免單例模式的使用,因?yàn)閱卫J綍?huì)引入全局狀態(tài),而一個(gè)健康的系統(tǒng)應(yīng)該避免引入過多的全局狀態(tài)。工廠模式工廠模式定義一個(gè)用于創(chuàng)建對(duì)象的接口,這個(gè)接口由子類決定實(shí)例化哪一個(gè)類。該模式使一個(gè)類的實(shí)例化延遲到了子類。而子類可以重寫接口方法以便創(chuàng)建的時(shí)候指定自己的對(duì)象類型。 使用場景:如果你不想讓某個(gè)子系統(tǒng)與較大的那個(gè)對(duì)象之間形成強(qiáng)耦合,而是想運(yùn)行時(shí)從許多子系統(tǒng)中進(jìn)行挑選的話,那么工廠模式是一個(gè)理想的選擇 class Product {constructor(name) {this.name = name}init() {console.log('init')}} class Factory {create(name) {return new Product(name)} } // use let factory = new Factory() let p = factory.create('p1') p.init() https://juejin.im/post/6844904200917221389#heading-81

js的基本數(shù)據(jù)類型、值是如何存儲(chǔ)的

JavaScript一共有8種數(shù)據(jù)類型 7種基本數(shù)據(jù)類型: Undefined、Null、Boolean、Number、String、Symbol(es6新增,表示獨(dú)一無二的值)和BigInt(es10新增)1種引用數(shù)據(jù)類型 Object(Object本質(zhì)上是由一組無序的名值對(duì)組成的)。 里面包含 function、Array、Date等。JavaScript不支持任何創(chuàng)建自定義類型的機(jī)制,而所有值最終都將是上述 8 種數(shù)據(jù)類型之一。 原始數(shù)據(jù)類型:直接存儲(chǔ)在棧(stack)中,占據(jù)空間小、大小固定,屬于被頻繁使用數(shù)據(jù),所以放入棧中存儲(chǔ)。 引用數(shù)據(jù)類型:同時(shí)存儲(chǔ)在棧(stack)和堆(heap)中,占據(jù)空間大、大小不固定。引用數(shù)據(jù)類型在棧中存儲(chǔ)了指針,該指針指向堆中該實(shí)體的起始地址。當(dāng)解釋器尋找引用值時(shí),會(huì)首先檢索其在棧中的地址,取得地址后從堆中獲得實(shí)體。

&& 、||和!! 運(yùn)算符

&& 叫邏輯與,在其操作數(shù)中找到第一個(gè)虛值表達(dá)式并返回它,如果沒有找到任何虛值表達(dá)式,則返回最后一個(gè)真值表達(dá)式。它采用短路來防止不必要的工作。 || 叫邏輯或,在其操作數(shù)中找到第一個(gè)真值表達(dá)式并返回它。這也使用了短路來防止不必要的工作。在支持 ES6 默認(rèn)函數(shù)參數(shù)之前,它用于初始化函數(shù)中的默認(rèn)參數(shù)值。 !! 運(yùn)算符可以將右側(cè)的值強(qiáng)制轉(zhuǎn)換為布爾值,這也是將值轉(zhuǎn)換為布爾值的一種簡單方法

js的數(shù)據(jù)類型的轉(zhuǎn)換

在 JS 中類型轉(zhuǎn)換只有三種情況,分別是:轉(zhuǎn)換為布爾值(調(diào)用Boolean()方法) 轉(zhuǎn)換為數(shù)字(調(diào)用Number()、parseInt()和parseFloat()方法) 轉(zhuǎn)換為字符串(調(diào)用.toString()或者String()方法)

js 內(nèi)置對(duì)象

js 中的內(nèi)置對(duì)象主要指的是 在程序執(zhí)行前存在全局作用域里的由 js定義的一些全局值屬性、函數(shù)和用來實(shí)例化其他對(duì)象的構(gòu)造函數(shù)對(duì)象。 一般我們經(jīng)常用到的如全局變量值 NaN、undefined, 全局函數(shù)如 parseInt()、parseFloat() 用來實(shí)例化對(duì)象的構(gòu)造函數(shù)如 Date、Object 等, 還有提供數(shù)學(xué)計(jì)算的單體內(nèi)置對(duì)象如 Math 對(duì)象。

null 和 undefined 的區(qū)別

首先 Undefined 和 Null 都是基本數(shù)據(jù)類型,這兩個(gè)基本數(shù)據(jù)類型分別都只有一個(gè)值,就是 undefined 和 null。 undefined 代表的含義是未定義, null 代表的含義是空對(duì)象(其實(shí)不是真的對(duì)象,請(qǐng)看下面的注意!)。一般變量聲明了但還沒有定義的時(shí)候會(huì)返回 undefined,null 主要用于賦值給一些可能會(huì)返回對(duì)象的變量,作為初始化。 當(dāng)我們對(duì)兩種類型使用 typeof 進(jìn)行判斷的時(shí)候,Null 類型化會(huì)返回 “object”,這是一個(gè)歷史遺留的問題。當(dāng)我們使用雙等 號(hào)對(duì)兩種類型的值進(jìn)行比較時(shí)會(huì)返回 true,使用三個(gè)等號(hào)時(shí)會(huì)返回 false。

{}和[]的valueOf和toString的結(jié)果

{} 的 valueOf 結(jié)果為 {} ,toString 的結(jié)果為 "[object Object]" [] 的 valueOf 結(jié)果為 [] ,toString 的結(jié)果為 ""

js 的作用域和作用域鏈

作用域: 作用域是定義變量的區(qū)域,它有一套訪問變量的規(guī)則,這套規(guī)則來管理瀏覽器引擎如何在當(dāng)前作用域以及嵌套的作用域中根據(jù)變量(標(biāo)識(shí)符)進(jìn)行變量查找。作用域鏈: 作用域鏈的作用是保證對(duì)執(zhí)行環(huán)境有權(quán)訪問的所有變量和函數(shù)的有序訪問,通過作用域鏈,我們可以訪問到外層環(huán)境的變量和函數(shù)。作用域鏈的本質(zhì)上是一個(gè)指向變量對(duì)象的指針列表。變量對(duì)象是一個(gè)包含了執(zhí)行環(huán)境中所有變量和函數(shù)的對(duì)象。作用域鏈的前端始終都是當(dāng)前執(zhí)行上下文的變量對(duì)象。全局執(zhí)行上下文的變量對(duì)象(也就是全局對(duì)象)始終是作用域鏈的最后一個(gè)對(duì)象。 當(dāng)我們查找一個(gè)變量時(shí),如果當(dāng)前執(zhí)行環(huán)境中沒有找到,我們可以沿著作用域鏈向后查找。

js 創(chuàng)建對(duì)象的方式

我們一般使用字面量的形式直接創(chuàng)建對(duì)象,但是這種創(chuàng)建方式對(duì)于創(chuàng)建大量相似對(duì)象的時(shí)候,會(huì)產(chǎn)生大量的重復(fù)代碼。但 js和一般的面向?qū)ο蟮恼Z言不同,在 ES6 之前它沒有類的概念。但是我們可以使用函數(shù)來進(jìn)行模擬,從而產(chǎn)生出可復(fù)用的對(duì)象創(chuàng)建方式,我了解到的方式有這么幾種:(1)第一種是工廠模式,工廠模式的主要工作原理是用函數(shù)來封裝創(chuàng)建對(duì)象的細(xì)節(jié),從而通過調(diào)用函數(shù)來達(dá)到復(fù)用的目的。但是它有一個(gè)很大的問題就是創(chuàng)建出來的對(duì)象無法和某個(gè)類型聯(lián)系起來,它只是簡單的封裝了復(fù)用代碼,而沒有建立起對(duì)象和類型間的關(guān)系。(2)第二種是構(gòu)造函數(shù)模式。js 中每一個(gè)函數(shù)都可以作為構(gòu)造函數(shù),只要一個(gè)函數(shù)是通過 new 來調(diào)用的,那么我們就可以把它稱為構(gòu)造函數(shù)。執(zhí)行構(gòu)造函數(shù)首先會(huì)創(chuàng)建一個(gè)對(duì)象,然后將對(duì)象的原型指向構(gòu)造函數(shù)的 prototype 屬性,然后將執(zhí)行上下文中的 this 指向這個(gè)對(duì)象,最后再執(zhí)行整個(gè)函數(shù),如果返回值不是對(duì)象,則返回新建的對(duì)象。因?yàn)?this 的值指向了新建的對(duì)象,因此我們可以使用 this 給對(duì)象賦值。構(gòu)造函數(shù)模式相對(duì)于工廠模式的優(yōu)點(diǎn)是,所創(chuàng)建的對(duì)象和構(gòu)造函數(shù)建立起了聯(lián)系,因此我們可以通過原型來識(shí)別對(duì)象的類型。但是構(gòu)造函數(shù)存在一個(gè)缺點(diǎn)就是,造成了不必要的函數(shù)對(duì)象的創(chuàng)建,因?yàn)樵?js 中函數(shù)也是一個(gè)對(duì)象,因此如果對(duì)象屬性中如果包含函數(shù)的話,那么每次我們都會(huì)新建一個(gè)函數(shù)對(duì)象,浪費(fèi)了不必要的內(nèi)存空間,因?yàn)楹瘮?shù)是所有的實(shí)例都可以通用的。(3)第三種模式是原型模式,因?yàn)槊恳粋€(gè)函數(shù)都有一個(gè) prototype 屬性,這個(gè)屬性是一個(gè)對(duì)象,它包含了通過構(gòu)造函數(shù)創(chuàng)建的所有實(shí)例都能共享的屬性和方法。因此我們可以使用原型對(duì)象來添加公用屬性和方法,從而實(shí)現(xiàn)代碼的復(fù)用。這種方式相對(duì)于構(gòu)造函數(shù)模式來說,解決了函數(shù)對(duì)象的復(fù)用問題。但是這種模式也存在一些問題,一個(gè)是沒有辦法通過傳入?yún)?shù)來初始化值,另一個(gè)是如果存在一個(gè)引用類型如 Array 這樣的值,那么所有的實(shí)例將共享一個(gè)對(duì)象,一個(gè)實(shí)例對(duì)引用類型值的改變會(huì)影響所有的實(shí)例。(4)第四種模式是組合使用構(gòu)造函數(shù)模式和原型模式,這是創(chuàng)建自定義類型的最常見方式。因?yàn)闃?gòu)造函數(shù)模式和原型模式分開使用都存在一些問題,因此我們可以組合使用這兩種模式,通過構(gòu)造函數(shù)來初始化對(duì)象的屬性,通過原型對(duì)象來實(shí)現(xiàn)函數(shù)方法的復(fù)用。這種方法很好的解決了兩種模式單獨(dú)使用時(shí)的缺點(diǎn),但是有一點(diǎn)不足的就是,因?yàn)槭褂昧藘煞N不同的模式,所以對(duì)于代碼的封裝性不夠好。(5)第五種模式是動(dòng)態(tài)原型模式,這一種模式將原型方法賦值的創(chuàng)建過程移動(dòng)到了構(gòu)造函數(shù)的內(nèi)部,通過對(duì)屬性是否存在的判斷,可以實(shí)現(xiàn)僅在第一次調(diào)用函數(shù)時(shí)對(duì)原型對(duì)象賦值一次的效果。這一種方式很好地對(duì)上面的混合模式進(jìn)行了封裝。(6)第六種模式是寄生構(gòu)造函數(shù)模式,這一種模式和工廠模式的實(shí)現(xiàn)基本相同,我對(duì)這個(gè)模式的理解是,它主要是基于一個(gè)已有的類型,在實(shí)例化時(shí)對(duì)實(shí)例化的對(duì)象進(jìn)行擴(kuò)展。這樣既不用修改原來的構(gòu)造函數(shù),也達(dá)到了擴(kuò)展對(duì)象的目的。它的一個(gè)缺點(diǎn)和工廠模式一樣,無法實(shí)現(xiàn)對(duì)象的識(shí)別。

對(duì)this、call、apply和bind的理解

1、在瀏覽器里,在全局范圍內(nèi)this 指向window對(duì)象; 2、在函數(shù)中,this永遠(yuǎn)指向最后調(diào)用他的那個(gè)對(duì)象; 3、構(gòu)造函數(shù)中,this指向new出來的那個(gè)新的對(duì)象; 4、call、apply、bind中的this被強(qiáng)綁定在指定的那個(gè)對(duì)象上; 5、箭頭函數(shù)中this比較特殊,箭頭函數(shù)this為父作用域的this,不是調(diào)用時(shí)的this.要知道前四種方式,都是調(diào)用時(shí)確定,也就是動(dòng)態(tài)的,而箭頭函數(shù)的this指向是靜態(tài)的,聲明的時(shí)候就確定了下來; 6、apply、call、bind都是js給函數(shù)內(nèi)置的一些API,調(diào)用他們可以為函數(shù)指定this的執(zhí)行,同時(shí)也可以傳參。

什么是 DOM 和 BOM

DOM指的是文檔對(duì)象模型,它指的是把文檔當(dāng)做一個(gè)對(duì)象來對(duì)待,這個(gè)對(duì)象主要定義了處理網(wǎng)頁內(nèi)容的方法和接口。 BOM指的是瀏覽器對(duì)象模型,它指的是把瀏覽器當(dāng)做一個(gè)對(duì)象來對(duì)待,這個(gè)對(duì)象主要定義了與瀏覽器進(jìn)行交互的法和接口。BOM的核心是 window,而 window 對(duì)象具有雙重角色,它既是通過 js 訪問瀏覽器窗口的一個(gè)接口, 又是一個(gè) Global(全局)(歌樓波)對(duì)象。 這意味著在網(wǎng)頁中定義的任何對(duì)象,變量和函數(shù),都作為全局對(duì)象的一個(gè)屬性或者方法存在。 window 對(duì)象含有 location 對(duì)象、navigator(那V給特)對(duì)象、screen(斯歌銳)對(duì)象等子對(duì)象, 并且 DOM 的最根本的對(duì)象 document 對(duì)象也是 BOM 的 window 對(duì)象的子對(duì)象。

三種事件模型

事件 是用戶操作網(wǎng)頁時(shí)發(fā)生的交互動(dòng)作或者網(wǎng)頁本身的一些操作,現(xiàn)代瀏覽器一共有三種事件模型。 DOM0級(jí)模型: 這種模型不會(huì)傳播,所以沒有事件流的概念,同元素 綁定多個(gè)事件,只會(huì)綁定最后一次的事件,前面的會(huì)被覆蓋。IE 事件模型:在該事件模型中,一次事件共有兩個(gè)過程,事件處理階段,和事件冒泡階段。事件處理階段會(huì)首先執(zhí)行目標(biāo)元素綁定的監(jiān)聽事件。然后是事件冒泡階段,冒泡指的是事件從目標(biāo)元素冒泡到 document,依次檢查經(jīng)過的節(jié)點(diǎn)是否綁定了事件監(jiān)聽函數(shù),如果有則執(zhí)行。這種模型通過 attachEvent 來添加監(jiān)聽函數(shù),可以添加多個(gè)監(jiān)聽函數(shù),會(huì)按順序依次執(zhí)行。detachEvent刪除事件DOM2 級(jí)事件模型: 在該事件模型中,一次事件共有三個(gè)過程,第一個(gè)過程是事件捕獲階段事件處理階段,和事件冒泡階段。捕獲指的是事件從 document 一直向下傳播到目標(biāo)元素,依次檢查經(jīng)過的節(jié)點(diǎn)是否綁定了事件監(jiān)聽函數(shù),如果有則執(zhí)行。。這種事件模型,事件綁定的函數(shù)是 addEventListener,其中第三個(gè)參數(shù)可以指定事件是否在捕獲階段執(zhí)行。取消事件removeEventListener

事件委托(代理)

本質(zhì)上是利用了事件冒泡的機(jī)制。 并且父節(jié)點(diǎn)可以通過事件對(duì)象獲取到目標(biāo)節(jié)點(diǎn),因此可以把子節(jié)點(diǎn)的監(jiān)聽函數(shù)定義在父節(jié)點(diǎn)上, 由父節(jié)點(diǎn)的監(jiān)聽函數(shù)統(tǒng)一處理多個(gè)子元素的事件,這種方式稱為事件委托 支持為同一個(gè)DOM元素注冊(cè)多個(gè)同類型事件,可將事件分成事件捕獲和事件冒泡機(jī)制

事件傳播

事件傳播有三個(gè)階段: 捕獲階段–事件從 window 開始,然后向下到每個(gè)元素,直到到達(dá)目標(biāo)元素事件或event.target。 目標(biāo)階段–事件已達(dá)到目標(biāo)元素。 冒泡階段–事件從目標(biāo)元素冒泡,然后上升到每個(gè)元素,直到到達(dá) window。什么是事件捕獲 當(dāng)事件發(fā)生在 DOM 元素上時(shí),該事件并不完全發(fā)生在那個(gè)元素上。在捕獲階段,事件從window開始,一直到觸發(fā)事件的元素。 什么是事件冒泡? 事件冒泡剛好與事件捕獲相反,當(dāng)前元素---->body ----> html---->document ---->window。當(dāng)事件發(fā)生在DOM元素上時(shí),該事件并不完全發(fā)生在那個(gè)元素上。在冒泡階段,事件冒泡,或者事件發(fā)生在它的父代,祖父母,祖父母的父代,直到到達(dá)window為止。

DOM 操作

(1)創(chuàng)建新節(jié)點(diǎn)createDocumentFragment() //創(chuàng)建一個(gè)DOM片段 (科瑞A特)(法歌們特)createElement() //創(chuàng)建一個(gè)具體的元素createTextNode() //創(chuàng)建一個(gè)文本節(jié)點(diǎn)(2)添加、移除、替換、插入appendChild(node) removeChild(node)replaceChild(new,old) (銳普利斯)insertBefore(new,old) (因色特比佛)(3)獲取、查找getElementById();getElementsByName();getElementsByTagName();getElementsByClassName();querySelector(); (斯來科特)querySelectorAll();(4)屬性操作getAttribute(key); (去比又特)setAttribute(key, value);hasAttribute(key);removeAttribute(key);

數(shù)據(jù)檢測類型判斷

檢測方法4種1、Object.prototype.toString.call()作用: 可以檢測所有數(shù)據(jù)類型所有數(shù)據(jù)類型都可以檢測,而且非常正確語法: Object.prototype.toString.call( 'xxx'/11/[ ] )返回值: [object Xxx], Xxx 就是對(duì)象的類型2、constructor作用: 可以檢測基本數(shù)據(jù)類型和引用數(shù)據(jù)類型弊端: 把類的原型進(jìn)行重寫, 很有可能把之前的constructor覆蓋 檢測出來的結(jié)果就會(huì)不準(zhǔn)確語法: ("xx")/([])/(function(){}).constructor === String/Array/Function 返回值: true/false 3、instanceOf原理: 判斷對(duì)象類型,基于原型鏈去判斷(obj instanceof Object)左邊對(duì)象的原型鏈proto上是否有右邊構(gòu)造函數(shù)的proptotype屬性作用: 判斷左邊的對(duì)象是否是右邊構(gòu)造函數(shù)的實(shí)例弊端: 用于引用類型的檢測, 對(duì)于基本數(shù)據(jù)類型不生效語法: " "/[ ]/true instanceOf String/Array/Boolean返回值: true/false 4、typeOf作用: 用于檢測基本數(shù)據(jù)類型和函數(shù)弊端: 引用數(shù)據(jù)類型(Arrary/function/object)只會(huì)返回Object, 不起作用語法: typeOf " "/[ ]/xx返回值: "string"/"boolean"/"object" (無法區(qū)分)

原型/原型鏈

原型: Javascript規(guī)定,每一個(gè)函數(shù)都有一個(gè)prototype對(duì)象屬性,指向另一個(gè)對(duì)象 prototype就是調(diào)用構(gòu)造函數(shù)所創(chuàng)建的那個(gè)實(shí)例對(duì)象的原型原型鏈: 實(shí)例對(duì)象與原型之間的連接,叫做原型鏈。 JS在創(chuàng)建對(duì)象的時(shí)候,都有一個(gè)叫做__proto__的內(nèi)置屬性,用于指向創(chuàng)建它的函數(shù)對(duì)象的原型對(duì)象prototype。獲取原型的方法 p.proto p.constructor.prototype Object.getPrototypeOf(p)

prototype、proto、constructor三者的關(guān)系

1、prototype: 每一個(gè)函數(shù)都有一個(gè)prototype這個(gè)屬性,而這個(gè)屬性指向一個(gè)對(duì)象,這個(gè)對(duì)象我們叫做原型對(duì)象 作用:節(jié)約內(nèi)存擴(kuò)展屬性和方法可以實(shí)現(xiàn)類之間的繼承 2、__proto__: 每一個(gè)對(duì)象都有一個(gè)__proto__屬性,__proto__指向創(chuàng)建自己的那個(gè)構(gòu)造函數(shù)的原型對(duì)象對(duì)象可以直接訪問__proto__里面的屬性和方法 3、constructor: 指向創(chuàng)建自己的那個(gè)構(gòu)造函數(shù) ,是原型上的方法總結(jié): 當(dāng)我們創(chuàng)建一個(gè)構(gòu)造函數(shù)的時(shí)候這個(gè)構(gòu)造函數(shù)自帶了一個(gè)prototype屬性,而這個(gè)屬性指向一個(gè)對(duì)象,也就是原型對(duì)象。 這個(gè)原型對(duì)象里面有一個(gè)constructor構(gòu)造器,它的作用是指向創(chuàng)建自己的構(gòu)造函數(shù)。 除此之外 prototype還可以存放公共的屬性和方法。 當(dāng)我們實(shí)例化一個(gè)對(duì)象的時(shí)候(被new調(diào)用的時(shí)候),這個(gè)對(duì)象自帶了一個(gè) proto 屬性, 這個(gè)proto 指向創(chuàng)建自己的構(gòu)造函數(shù)的原型對(duì)象。可以使用這個(gè)原型對(duì)象里面的屬性和方法

constructor與class的區(qū)別

傳統(tǒng)的javascript中只有對(duì)象,沒有類的概念。它是基于原型的面向?qū)ο笳Z言。 原型對(duì)象特點(diǎn)就是將自身的屬性共享給新對(duì)象。 ES6引入了Class(類)這個(gè)概念,通過class關(guān)鍵字可以定義類。 該關(guān)鍵字的出現(xiàn)使得其在對(duì)象寫法上更加清晰,更像是一種面向?qū)ο蟮恼Z言constructor: constructor()方法是類的默認(rèn)方法,通過new命令生成對(duì)象實(shí)例時(shí),自動(dòng)調(diào)用該方法。 一個(gè)類必須有constructor()方法,如果沒有顯式定義,一個(gè)空的 constructor()方法會(huì)被默認(rèn)添加。

構(gòu)造函數(shù)與普通函數(shù)的區(qū)別

1. 返回值類型的區(qū)別:構(gòu)造函數(shù)是沒有返回值類型的,普通函數(shù)是有返回值類型的,即使函數(shù)沒有返回值,返回值類型也要寫上void。 2. 函數(shù)名的區(qū)別:構(gòu)造函數(shù)的函數(shù)名必須要與類名一致,普通函數(shù)的函數(shù)名只要符合標(biāo)識(shí)符的命名規(guī)則即可。 3. 調(diào)用方式的區(qū)別:構(gòu)造函數(shù)是在創(chuàng)建對(duì)象的時(shí)候由jvm調(diào)用的。普通函數(shù)是由我們使用對(duì)象調(diào)用的,一個(gè)對(duì)象可以對(duì)象多次普通的函數(shù), 4. 作用上的區(qū)別:構(gòu)造函數(shù)的作用用于初始化一個(gè)對(duì)象。普通函數(shù)是用于描述一類事物的公共行為的。

跨域出現(xiàn)的原因/解決方法

1. 為什么出現(xiàn)了跨域 2. 跨域解決方式有哪些?原因:由于瀏覽器的同源策略,即屬于不同域的?面之間不能相互訪問各自的?面內(nèi)容。哪些情況下產(chǎn)生跨域 1、域名不同 2、端口號(hào)不同 3、協(xié)議不同(http/https) 4、域名和域名對(duì)應(yīng)ip 5、主域名相同(127.0.01 和 localhost) 多域名匹配一個(gè)ip地址 6、子域名不同(一級(jí)和二級(jí)域名)解決方法1、后端設(shè)置白名單 后端不存在跨域(后端代碼脫離瀏覽器,后端是服務(wù)器端) 利用后端(自己公司的后端)去獲取接口數(shù)據(jù),將數(shù)據(jù)傳給前端 2、jsonp 原理:利用瀏覽器的"漏洞" src不受同源策略的影響,可以請(qǐng)求任何鏈接 。動(dòng)態(tài)創(chuàng)建script標(biāo)簽,將事先寫好的函數(shù)名傳給服務(wù)器,供服務(wù)器使用 (1)script標(biāo)簽src屬性不存在跨域 (2)get方式--傳遞函數(shù)名 --弊端 (3)callback回調(diào)函數(shù)(傳遞函數(shù)名) 3、反向代理 proxy webpack配置(采用Socket協(xié)議) "proxy": {"/index.php": {"target": "http://qinqin.net","changeOrigin": true}} 4、CORS解決跨域(xhr2)(后端)后端配置響應(yīng)頭,如果需要有特殊的約定字符,前端需要配置請(qǐng)求頭 CORS是一個(gè)W3C標(biāo)準(zhǔn),全稱是"跨域資源共享"(Cross-origin resource sharing)。它允許瀏覽器向跨源(協(xié)議 + 域名 + 端口)服務(wù)器,發(fā)出XMLHttpRequest請(qǐng)求,從而克服了AJAX只能同源使用的限制。 需要服務(wù)器(提供接口的源碼里面)添加下面兩句話。 header('Access-Control-Allow-Origin:*'); header('Access-Control-Allow-Method:POST,GET');jsonp是一種非正式傳輸協(xié)議,用于解決跨域問題流程: 1、創(chuàng)建一個(gè)全局函數(shù) 2、創(chuàng)建一個(gè)script標(biāo)簽 3、給script添加src 4、給src添加回調(diào)函數(shù)test(callback=test) callback是傳給后端的一個(gè)參數(shù) 5、將script放到?面上 6、script請(qǐng)求完成,將自己從?面上刪除

閉包原理/優(yōu)點(diǎn)/缺點(diǎn)/使用場景

1. 什么是閉包 what 函數(shù)嵌套函數(shù) 能夠讀取其他函數(shù)內(nèi)部變量的函數(shù) 2. 優(yōu)缺點(diǎn)優(yōu)點(diǎn): 1、使用閉包是不會(huì)污染全局環(huán)境,2、方便進(jìn)行模塊化開發(fā),缺點(diǎn): 就是不恰當(dāng)使用會(huì)造成內(nèi)存泄漏 【解決方式:清除變量】 3. 閉包的應(yīng)用場景函數(shù)防抖計(jì)數(shù)器閉包原理:定義在一個(gè)函數(shù)內(nèi)部的函數(shù)(函數(shù)嵌套函數(shù)),閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來的一座橋梁。 打破了作用域鏈的規(guī)則 閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù) 優(yōu)點(diǎn): 1、使用閉包是不會(huì)污染全局環(huán)境, 2、方便進(jìn)行模塊化開發(fā), 3、減少形參個(gè)數(shù),延長了形參的生命周期,壞處: 1、就是不恰當(dāng)使用會(huì)造成內(nèi)存泄漏 閉包的不適用于返回閉包的函數(shù)是個(gè)特別大的函數(shù),很多高級(jí)應(yīng)用都要依靠閉包實(shí)現(xiàn).使用場景 1、通過循環(huán)給頁面上多個(gè)dom節(jié)點(diǎn)綁定事件 2、封裝私有變量(計(jì)數(shù)器) 3、延續(xù)局部變量的壽命 4、高階組件 5、函數(shù)防抖模塊化的就是以閉包為基礎(chǔ)構(gòu)建的;

內(nèi)存泄漏

1、意外的全局變量 2、被遺忘的定時(shí)器 3、沒有清除的dom應(yīng)用 ,故要及時(shí)清除, 4、濫用閉包清除內(nèi)存泄漏方法有兩種,一是標(biāo)記清除,二便是引用計(jì)數(shù)清除。

promise/async&await

Promise是es6新增的,異步編程的一種解決方案,用來取代回調(diào)函數(shù)和事件,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大。Promise 對(duì)象用于延遲(deferred) 計(jì)算和異步(asynchronous)計(jì)算。一個(gè)Promise對(duì)象代表著一個(gè)還未完成,但預(yù)期將來會(huì)完成的操作。Promise 對(duì)象是一個(gè)返回值的代理,這個(gè)返回值在promise對(duì)象創(chuàng)建時(shí)未必已知。它允許你為異步操作的成功或失敗指定處理方法。這使得異步方法可以像同步方法那樣返回值:異步方法會(huì)返回一個(gè)包含了原返回值的 promise 對(duì)象來替代原返回值。有三種狀態(tài):pending(進(jìn)行中)、fulfilled(resolve已成功)和rejected(銳杰克騰德)(已失敗)promise的特點(diǎn): (1)對(duì)象的狀態(tài)不受外界影響。Promise對(duì)象代表一個(gè)異步操作。 (2)一旦狀態(tài)設(shè)定,就不會(huì)再變,任何時(shí)候都可以得到這個(gè)結(jié)果。Promise對(duì)象的狀態(tài)改變,只有兩種可能:從pending變?yōu)閞esolve和從pending變?yōu)閞ejected。只要這兩種情況發(fā)生,狀態(tài)就凝固了promise的方法: promise實(shí)例方法:Promise.prototype.then Promise.prototype.catch一:resolve函數(shù)的作用是,將Promise對(duì)象的狀態(tài)從“未完成”變?yōu)椤俺晒Α?#xff08;即從 pending 變?yōu)?resolved),在異步操作成功時(shí)調(diào)用,并將異步操作的結(jié)果,作為參數(shù)傳遞出去;二:reject函數(shù)的作用是,將Promise對(duì)象的狀態(tài)從“未完成”變?yōu)椤笆 ?#xff08;即從 pending 變?yōu)?rejected),在異步操作失敗時(shí)調(diào)用,并將異步操作報(bào)出的錯(cuò)誤,作為參數(shù)傳遞出去。三:Promise.prototype.finallyfinally方法用于指定不管 Promise 對(duì)象最后狀態(tài)如何,都會(huì)執(zhí)行的操作。該方法是 ES2018 引入標(biāo)準(zhǔn)的。promise的靜態(tài)方法 Promise.all():用于將多個(gè) Promise 實(shí)例,包裝成一個(gè)新的 Promise 實(shí)例,接受一個(gè)數(shù)組作為參數(shù),只有數(shù)組里面的每個(gè)狀態(tài)都變成resolve,則新的 Promise 實(shí)例狀態(tài)才會(huì)變成resolve.Promise.race():將Promise對(duì)象數(shù)組中最先執(zhí)行完成的內(nèi)容通過后面then傳出promise的基本使用: 通過new promise創(chuàng)建一個(gè)promise對(duì)象,里面有一個(gè)參數(shù),參數(shù)是一個(gè)回調(diào)函數(shù), 回調(diào)函數(shù)中有2個(gè)參數(shù):resolve、reject resolve()當(dāng)異步執(zhí)行成功的時(shí)候調(diào)用的方法,reject()當(dāng)異步失敗的時(shí)候調(diào)用的方法。 除此之外promise有一個(gè)then方法,當(dāng)成功的時(shí)候執(zhí)行第一個(gè)回調(diào)函數(shù),當(dāng)失敗的時(shí)候執(zhí)行第二個(gè)回調(diào)函數(shù)。 第二個(gè)回調(diào)函數(shù)也可以通過promise對(duì)象.catch調(diào)用 Promise.all():當(dāng)所有的異步代碼都執(zhí)行完畢以后才會(huì)執(zhí)行.then中的操作 Promise.race():只要有一個(gè)promise執(zhí)行完畢后就會(huì)執(zhí)行.then操作promise的三種狀態(tài): 1.pending - 進(jìn)行中 2.fulfilled - 成功 3.rejected - 失敗鏈?zhǔn)秸{(diào)用: promise俗稱鏈?zhǔn)秸{(diào)用,它是es6中最重要的特性之一 簡單的說可以不停的then調(diào)用嵌套在調(diào)用(異步之后,鏈?zhǔn)秸{(diào)用方式執(zhí)行回調(diào)),這種操作方式稱為promiseasync異步能干什么? 就是用來修飾函數(shù),使該函數(shù)異步執(zhí)行,不阻礙后續(xù)函數(shù)的執(zhí)行 同時(shí)我們注意到,async修飾的函數(shù)也帶有then catch方法, 因此,經(jīng)async修飾的函數(shù)也 是一個(gè)promise await只能放在async中,且只能修飾promise對(duì)象 1. promise的誕生是為了簡化函數(shù)嵌套調(diào)用流程,也便于后續(xù)維護(hù) 2. async/await定義了異步函數(shù),并在其內(nèi)部可通過await等待promise對(duì)象,阻塞后 續(xù)的執(zhí)行 await關(guān)鍵字必須在async函數(shù)里面 await會(huì)阻塞當(dāng)前直到完成 async返回reject的方法,當(dāng)拋出異常等同于reject async / await與 Promise的主要區(qū)別是: Promise代碼完全都是Promise的API(then、catch等等),操作本身的語義反而不容易看出來, async / await函數(shù)的實(shí)現(xiàn)最簡潔,最符合語義,幾乎沒有語義不相關(guān)的代碼 async / await 函數(shù)就是 Generator 函數(shù)的語法糖async/await函數(shù)的優(yōu)勢(shì) 1. 使用async函數(shù)可以讓代碼簡潔很多,不需要像Promise一樣需要些then,不需要寫匿名函數(shù)處理Promise的resolve值,也不需要定義多余的data變量,還避免了嵌套代碼 2. 使用aync/await的話,catch能處理JSON.parse錯(cuò)誤 promise中不能處理 3. 條件語句也和錯(cuò)誤捕獲是一樣的,在 Async 中也可以像平時(shí)一般使用條件語句promise的狀態(tài)處理的原理:

promise.all和promise.race

Pomise.all的使用Promise.all可以將多個(gè)Promise實(shí)例包裝成一個(gè)新的Promise實(shí)例。同時(shí),成功和失敗的返回值是不同的,成功的時(shí)候返回的是一個(gè)結(jié)果數(shù)組,而失敗的時(shí)候則返回最先被reject失敗狀態(tài)的值。Promise.all獲得的成功結(jié)果的數(shù)組里面的數(shù)據(jù)順序和Promise.all接收到的數(shù)組順序是一致的,在前端開發(fā)請(qǐng)求數(shù)據(jù)的過程中,偶爾會(huì)遇到發(fā)送多個(gè)請(qǐng)求并根據(jù)請(qǐng)求順序獲取和使用數(shù)據(jù)的場景,使用Promise.all毫無疑問可以解決這個(gè)問題。Promise.race的使用Promise.race就是賽跑的意思,意思就是說,Promise.race([p1, p2, p3])里面哪個(gè)結(jié)果獲得的快,就返回那個(gè)結(jié)果,不管結(jié)果本身是成功狀態(tài)還是失敗狀態(tài)。

Generator

Generator 的中文名稱是生成器,它是ECMAScript6中提供的新特性。 在過去,封裝一段運(yùn)算邏輯的單元是函數(shù)。函數(shù)只存在“沒有被調(diào)用”或者“被調(diào)用”的情況, 不存在一個(gè)函數(shù)被執(zhí)行之后還能暫停的情況,而Generator的出現(xiàn)讓這種情況成為可能。通過 function* 來定義的函數(shù)稱之為“生成器函數(shù)”(generator function),它的特點(diǎn)是可以中斷函數(shù)的執(zhí)行, 每次執(zhí)行yield語句之后,函數(shù)即暫停執(zhí)行,直到調(diào)用返回的生成器對(duì)象的next()函數(shù)它才會(huì)繼續(xù)執(zhí)行。也就是說 Generator 函數(shù)是一個(gè)狀態(tài)機(jī),封裝了多個(gè)內(nèi)部狀態(tài)。 執(zhí)行 Generator 函數(shù)返回一個(gè)遍歷器對(duì)象(一個(gè)指向內(nèi)部狀態(tài)的指針對(duì)象), 調(diào)用遍歷器對(duì)象的next方法,使得指針移向下一個(gè)狀態(tài)。每次調(diào)用next方法, 內(nèi)部指針就從函數(shù)頭部或上一次停下來的地方開始執(zhí)行,直到遇到下一個(gè)yield表達(dá)式(或return語句)為止。yield關(guān)鍵字 真正讓Generator具有價(jià)值的是yield關(guān)鍵字,這個(gè)yield關(guān)鍵字讓 Generator內(nèi)部的邏輯能夠切割成多個(gè)部分。 發(fā)現(xiàn)函數(shù)執(zhí)行到第一個(gè)yield關(guān)鍵字的時(shí)候就停止了。要讓業(yè)務(wù)邏輯繼續(xù)執(zhí)行完,需要反復(fù)調(diào)用.next() 可以簡單地理解為yield關(guān)鍵字將程序邏輯劃分成幾部分,每次.next()執(zhí)行時(shí)執(zhí)行一部分。 這使得程序的執(zhí)行單元再也不是函數(shù),復(fù)雜的邏輯可以通過yield來暫停。.next()調(diào)用時(shí),返回一個(gè)對(duì)象,這個(gè)對(duì)象具備兩個(gè)屬性。 其中一個(gè)屬性是布爾型的done。它表示這個(gè)Generator對(duì)象的邏輯塊是否執(zhí)行完成。 另一個(gè)屬性是value,它來自于yield語句后的表達(dá)式的結(jié)果。通過.next()傳遞參數(shù),可以賦值給yield關(guān)鍵字前面的變量聲明。

堆/棧

1、堆——引用類型地址傳遞堆:動(dòng)態(tài)分配的內(nèi)存,大小不定,不會(huì)自動(dòng)釋放。存放引用類型的值 先進(jìn)后出FILO引用類型: Object(Arrary, Date, Math,Function, Object)訪問方法: JS不能直接訪問內(nèi)存中的值, 只能操作對(duì)象的地址, 所以產(chǎn)生深/淺拷貝問題棧--基本類型值傳遞 2、棧——自動(dòng)分配內(nèi)存空間,系統(tǒng)自動(dòng)釋放,存放基本類型的值和引用類型的地址先進(jìn)先出FIFO基本類型: Undefined、Null、Boolean、Number 和 String, Symbol(ES6新增)訪問方法: 按值訪問, 直接操作內(nèi)存中的值

深/淺拷貝及方法

深/淺拷貝針對(duì)的是引用類型淺拷貝 淺拷貝只復(fù)制指向某個(gè)對(duì)象的指針,而不復(fù)制對(duì)象本身,新舊對(duì)象還是共享同一塊內(nèi)存。 新舊互相影響,改變的是地址 新值===原值,只能拷貝一層數(shù)組方法: slice截取, concat拼接, filter過濾, map 對(duì)象方法: Object.assign({},obj), Object.create(obj)展開運(yùn)算符: {...obj},[...arr] 深拷貝 深拷貝會(huì)另外創(chuàng)造一個(gè)一模一樣的對(duì)象,新對(duì)象跟原對(duì)象不共享內(nèi)存,修改新對(duì)象不會(huì)改到原對(duì)象 新舊互不影響,改變的是值 新值=/=原值,可以拷貝多層1、JSON序列化JSON.parse(JSON.stringify(obj))對(duì)象-->字符串-->對(duì)象這個(gè)方式的弊端:1、如果obj里面有時(shí)間對(duì)象,則JSON.stringify后再JSON.parse的結(jié)果,時(shí)間將只是字符串的形式,而不是對(duì) 象的形式2、如果obj里有RegExp(正則表達(dá)式的縮寫)、Error對(duì)象,則序列化的結(jié)果將只得到空對(duì)象;3、如果obj里有函數(shù),undefined,則序列化的結(jié)果會(huì)把函數(shù)或 undefined丟失;4、如果obj里有NaN、Infinity和-Infinity,則序列化的結(jié)果會(huì)變成null5、JSON.stringify()只能序列化對(duì)象的可枚舉的自有屬性,不可枚舉的不能被復(fù)制可枚舉:可枚舉性(enumerable)用來控制所描述的屬性,是否將被包括在for...in循環(huán)之中。具體來說,如果一個(gè)屬性的enumerable為false,下面三個(gè)操作不會(huì)取到該屬性。for..in循環(huán)、Object.keys方法、JSON.stringify方法 2、原生實(shí)現(xiàn)遞歸+淺拷貝3、工具實(shí)現(xiàn)【第三方封裝庫】 loadsh _.cloneDeep(obj).DeepClone()用于 Model / Entity / ... ... 等引用類型對(duì)象的深度克隆特性說明1.不需要對(duì)對(duì)象做任何特殊處理,直接 .DeepClone() 即可得到該對(duì)象的深度克隆2.不受對(duì)象層次深度限制,均可實(shí)現(xiàn)深度克隆(下面會(huì)給出幾個(gè)簡單示例 ... ...) Immutable Object.create()

set和map

Set:它類似于數(shù)組,但是成員的值都是唯一的,沒有重復(fù)的值。 Set本身是一個(gè)構(gòu)造函數(shù),用來生成 Set 數(shù)據(jù)結(jié)構(gòu),數(shù)組作為參數(shù)。不說set 數(shù)據(jù)結(jié)構(gòu)Set new set()存儲(chǔ)數(shù)據(jù) set.size得到存儲(chǔ)的數(shù)據(jù)長度 has()判斷某個(gè)值是否存在set中 foreach遍歷set不說map : new map map.set map.get map.delete都是用來存儲(chǔ)數(shù)據(jù)用的,但是存儲(chǔ)的數(shù)據(jù)格式不同 set 直接存儲(chǔ) 任意類型數(shù)據(jù) map 存儲(chǔ)數(shù)據(jù)的時(shí)候,必須以key,value的形式, set 使用forEach 遍歷的時(shí)候,key和value值是一樣的 而map 遍歷的時(shí)候,key就是存進(jìn)去的對(duì)象的key,value就是存在的值for循環(huán)這種寫法比較麻煩,因此數(shù)組提供內(nèi)置的forEach方法。forEach沒有返回值,無法中途跳出forEach循環(huán),break命令或return命令都不能奏效。for...in循環(huán)主要是為遍歷對(duì)象而設(shè)計(jì)的,不適用于遍歷數(shù)組**for...of循環(huán)相比上面幾種做法,有一些顯著的優(yōu)點(diǎn)。 有著同for...in一樣的簡潔語法,但是沒有for...in那些缺點(diǎn)。 不同于forEach方法,它可以與break、continue和return配合使用。 提供了遍歷所有數(shù)據(jù)結(jié)構(gòu)的統(tǒng)一操作接口。

宏任務(wù)和微任務(wù)

js 是單線程執(zhí)行的,js中的任務(wù)按順序一個(gè)一個(gè)的執(zhí)行,但是一個(gè)任務(wù)耗時(shí)太長,那么后面的任務(wù)就需要等待,為了解決這種情況,將任務(wù)分為了同步任務(wù)和異步任務(wù),而異步任務(wù)又可以分為微任務(wù)和宏任務(wù)概念 1.宏任務(wù):當(dāng)前調(diào)用棧中執(zhí)行的代碼成為宏任務(wù)。(主代碼快,定時(shí)器等等)。 2.微任務(wù):當(dāng)前(此次事件循環(huán)中)宏任務(wù)執(zhí)行完,在下一個(gè)宏任務(wù)開始之前需要執(zhí)行的任務(wù),可以理解為回調(diào)事件。(promise.then,proness.nextTick等等)。 3.宏任務(wù)中的事件放在callback queue中,由事件觸發(fā)線程維護(hù);微任務(wù)的事件放在微任務(wù)隊(duì)列中,由js引擎線程維護(hù)。運(yùn)行機(jī)制 1. 在執(zhí)行棧中執(zhí)行一個(gè)宏任務(wù)。 2. 執(zhí)行過程中遇到微任務(wù),將微任務(wù)添加到微任務(wù)隊(duì)列中。 3. 當(dāng)前宏任務(wù)執(zhí)行完畢,立即執(zhí)行微任務(wù)隊(duì)列中的任務(wù)。 4. 當(dāng)前微任務(wù)隊(duì)列中的任務(wù)執(zhí)行完畢,檢查渲染,GUI線程接管渲染。 5. 渲染完畢后,js線程接管,開啟下一次事件循環(huán),執(zhí)行下一次宏任務(wù)(事件隊(duì)列中取)。微任務(wù):process.nextTick、MutationObserver、Promise.then catch finally 宏任務(wù):I/O、setTimeout、setInterval、setImmediate、requestAnimationFramejs執(zhí)行順序,(先執(zhí)行宏任務(wù)列,微任務(wù)隊(duì)列) 先同步再異步,在此基礎(chǔ)上先宏任務(wù)再微任務(wù)流程:同步和異步任務(wù)分別進(jìn)入不同的執(zhí)行“場所”,同步進(jìn)入主線程,異步進(jìn)入Event Table并注冊(cè)函數(shù)。當(dāng)指定的事情完成時(shí),Event Table會(huì)將這個(gè)函數(shù)移入Event Queue。主線程內(nèi)的任務(wù)執(zhí)行完畢為空,回去了Event Queue讀取對(duì)應(yīng)的函數(shù),進(jìn)入主線程。上述過程會(huì)不斷重復(fù),也就是常說的Event Loop(事件循環(huán))。但是,JS異步還有一個(gè)機(jī)制,就是遇到宏任務(wù),先執(zhí)行宏任務(wù),將宏任務(wù)放入event queue,然后再執(zhí)行微任務(wù),將微任務(wù)放入eventqueue,但是,這兩個(gè)queue不是一個(gè)queue。當(dāng)你往外拿的時(shí)候先從微任務(wù)里拿這個(gè)回調(diào)函數(shù),然后再從宏任務(wù)的queue拿宏任務(wù)的回調(diào)函數(shù),

js異步操作

1、定時(shí)器都是異步操作 2、事件綁定都是異步操作 3、AJAX中一般我們都采取異步操作(也可以同步) 4、回調(diào)函數(shù)可以理解為異步(不是嚴(yán)謹(jǐn)?shù)漠惒讲僮?#xff09; 5、promise 6、generator(ES6) 通過yield關(guān)鍵字可以讓任務(wù)在需要的地方暫停,每一步的值可以通過next獲取 7、async/await(ES7) await得到的就是async異步返回值,底層原理還是promise中的resolve方法 8、設(shè)計(jì)模式-發(fā)布訂閱模式 9、事件監(jiān)聽

表單只能輸入數(shù)字

正則 type number

Proxy和Reflect

Proxy用于修改某些操作的默認(rèn)行為,即對(duì)編程語言層面進(jìn)行修改,屬于“元編程”,Proxy意思為“代理”,即在訪問對(duì)象之前建立一道“攔截”,任何訪問該對(duì)象的操作之前都會(huì)通過這道“攔截”,即執(zhí)行Proxy里面定義的方法let pro = new Proxy(target,handler)其中 new Proxy相當(dāng)于創(chuàng)建了一個(gè)Proxy實(shí)例,target為所要攔截的目標(biāo)對(duì)象,handler也是一個(gè)對(duì)象,里面定義的是對(duì)攔截對(duì)象所要進(jìn)行的攔截方法Proxy也可以作為其他對(duì)象的原型對(duì)象使用上述實(shí)例將pro作為obj的原型對(duì)象使用,雖然obj本身沒有name這個(gè)屬性,但是根據(jù)原型鏈,會(huì)在pro上讀取到name屬性,之后會(huì)執(zhí)行相對(duì)應(yīng)的攔截操作。let pro = new Proxy(target,handler); let obj = Object.create(pro);

Proxy常用的攔截方法

get(target,name,property)方法 用于攔截某個(gè)讀取屬性的操作,第一個(gè)參數(shù)為目標(biāo)對(duì)象,第二個(gè)參數(shù)為屬性名稱,第三個(gè)屬性為操作所針對(duì)的對(duì)象(可選參數(shù))set(target,name,value,property) 用于攔截某個(gè)屬性的賦值操作,第一個(gè)參數(shù)為目標(biāo)對(duì)象,第二個(gè)參數(shù)為屬性名,第三個(gè)參數(shù)為屬性值,第四個(gè)參數(shù)為操作行為所針對(duì)的對(duì)象(可選參數(shù))has(target,key) 用來攔截對(duì)象是否具有某個(gè)屬性值的操作,第一個(gè)參數(shù)為目標(biāo)對(duì)象,第二個(gè)參數(shù)為屬性名Reflect(銳付萊克特)對(duì)象: Reflect設(shè)計(jì)的目的是為了優(yōu)化Object的一些操作方法以及合理的返回Object操作返回的結(jié)果,對(duì)于一些命令式的Object行為,Reflect對(duì)象可以將其變?yōu)楹瘮?shù)式的行為Reflect(target,name,property) Reflect.has(obj,"name") Reflect.get(target,name,property)

瀏覽器優(yōu)化

減少請(qǐng)求數(shù)量圖片處理雪碧圖gulp Base64 使用字體圖標(biāo)來代替圖片 - 自定義字體 @font-face{} 在安卓下可以使用webp格式的圖片減小資源大小 - webpack優(yōu)化HTML壓縮CSS壓縮JS壓縮與混亂圖片壓縮優(yōu)化網(wǎng)絡(luò)連接cdnCDN即內(nèi)容分發(fā)網(wǎng)絡(luò),它能夠?qū)崟r(shí)地根據(jù)網(wǎng)絡(luò)流量和各節(jié)點(diǎn)的連接、負(fù)載狀用戶可就近取得所需內(nèi)容,解決 Internet網(wǎng)絡(luò)擁擠的狀況,提高用戶訪問網(wǎng)站的響應(yīng)速度優(yōu)化資源加載資源加載位置1、CSS文件放在head中,先外鏈,后本頁2、JS文件放在body底部,先外鏈,后本頁3、body中間盡量不寫style標(biāo)簽和script標(biāo)簽資源加載時(shí)機(jī)1、異步script標(biāo)簽2、模塊按需加載需要根據(jù)路由來加載當(dāng)前頁面需要的業(yè)務(wù)模塊3、資源懶加載與資源預(yù)加載減少重繪回流當(dāng)render tree中的一部分(或全部)因?yàn)樵氐囊?guī)模尺寸,布局,隱藏等改變而需要重新構(gòu)建。這就稱為回流當(dāng)render tree中的一些元素需要更新屬性,而這些屬性只是影響元素的外觀,風(fēng)格,而不會(huì)影響布局的,比如 background-color。則就叫稱為重繪。回流必將引起重繪,而重繪不一定會(huì)引起回流。css3硬件加速(GPU加速)六.【DOM優(yōu)化】 1、緩存DOM 2、減少DOM深度及DOM數(shù)量 3、批量操作DOM 4、批量操作CSS樣式 5、在內(nèi)存中操作DOM 6、DOM元素離線更新 7、DOM讀寫分離 8、事件代理 9、防抖和節(jié)流 10、及時(shí)清理環(huán)境

請(qǐng)求頭

Accept(艾可塞克特) 告訴WEB服務(wù)器自己接受什么介質(zhì)類型,*/* 表示任何類型,type/* 表示該類型下的所有子類型,type/sub-type。Accept-Charset(恰斯特) 瀏覽器告訴服務(wù)器自己能接收的字符集。Accept-Encoding(因扣定) 瀏覽器申明自己接收的編碼方法,通常指定壓縮方法,是否支持壓縮,支持什么壓縮方法(gzip,deflate)Accept-Language 瀏覽器申明自己接收的語言。語言跟字符集的區(qū)別:中文是語言,中文有多種字符集,比如big5,gb2312,gbk等等。Authorization(哦瑟惹C遜) 當(dāng)客戶端接收到來自WEB服務(wù)器的 WWW-Authenticate 響應(yīng)時(shí),用該頭部來回應(yīng)自己的身份驗(yàn)證信息給WEB服務(wù)器。If-Match 如果對(duì)象的 ETag 沒有改變,其實(shí)也就意味著對(duì)象沒有改變,才執(zhí)行請(qǐng)求的動(dòng)作,獲取文檔。If-None-Match 如果對(duì)象的 ETag 改變了,其實(shí)也就意味著對(duì)象也改變了,才執(zhí)行請(qǐng)求的動(dòng)作,獲取文檔。(莫得反得) If-Modified-Since(森恩斯) 如果請(qǐng)求的對(duì)象在該頭部指定的時(shí)間之后修改了,才執(zhí)行請(qǐng)求的動(dòng)作(比如返回對(duì)象),否則返回代碼304,告訴瀏覽器該對(duì)象沒有修改。例如:If-Modified-Since:Thu, 10 Apr 2008 09:14:42 GMTIf-Unmodified-Since 如果請(qǐng)求的對(duì)象在該頭部指定的時(shí)間之后沒修改過,才執(zhí)行請(qǐng)求的動(dòng)作(比如返回對(duì)象)。If-Range /reinge/ 瀏覽器告訴 WEB 服務(wù)器,如果我請(qǐng)求的對(duì)象沒有改變,就把我缺少的部分給我,如果對(duì)象改變了,就把整個(gè)對(duì)象給我。瀏覽器通過發(fā)送請(qǐng)求對(duì)象的ETag 或者自己所知道的最后修改時(shí)間給 WEB 服務(wù)器,讓其判斷對(duì)象是否改變了。總是跟 Range 頭部一起使用。Range 瀏覽器(比如 Flashget 多線程下載時(shí))告訴 WEB 服務(wù)器自己想取對(duì)象的哪部分。例如:Range: bytes=1173546Proxy-Authenticate(噢三特K特) 代理服務(wù)器響應(yīng)瀏覽器,要求其提供代理身份驗(yàn)證信息。Proxy-Authorization 瀏覽器響應(yīng)代理服務(wù)器的身份驗(yàn)證請(qǐng)求,提供自己的身份信息。Host 客戶端指定自己想訪問的WEB服務(wù)器的域名/IP 地址和端口號(hào)。如Host:rss.sina.com.cnReferer(銳佛爾) 瀏覽器向WEB 服務(wù)器表明自己是從哪個(gè)網(wǎng)頁URL獲得點(diǎn)擊當(dāng)前請(qǐng)求中的網(wǎng)址/URL, 例如:Referer:http://www.ecdoer.com/User-Agent(A就特) 瀏覽器表明自己的身份(是哪種瀏覽器)。 例如:User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN;rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14

static有什么特性

new出來一個(gè)實(shí)例對(duì)象是否帶有static屬性 static用ES5怎么寫沒有創(chuàng)建對(duì)象,也能使用屬性和調(diào)用方法用來形成靜態(tài)代碼塊以優(yōu)化程序性能。因?yàn)橹粫?huì)在類加載的時(shí)候執(zhí)行一次。因此,很多時(shí)候會(huì)將一些只需要進(jìn)行一次的初始化操作都放在static代碼塊中進(jìn)行。static塊可以置于類中的任何地方,類中可以有多個(gè)static塊。在類初次被加載的時(shí)候,會(huì)按照static塊的順序來執(zhí)行每個(gè)static塊,并且只會(huì)執(zhí)行一次被static修飾的變量或者方法是獨(dú)立于該類的任何對(duì)象,也就是說,這些變量和方法不屬于任何一個(gè)實(shí)例對(duì)象,而是被類的實(shí)例對(duì)象所共享。類第一次加載初始化的時(shí)候就去加載static部分,后面可以重新賦值static用ES5怎么寫: 靜態(tài)是通過類名直接調(diào)用 class A staticB 直接用A.B 將B綁定在A上

async await

同步還是異步 await同步 async異步async和await有兩個(gè)關(guān)鍵字,一個(gè)寫在函數(shù)外面,一個(gè)寫在函數(shù)里面,函數(shù)外面是異步的,函數(shù)里面是同步的,調(diào)用函數(shù)的那一行其實(shí)是異步的,下一行 函數(shù)里面轉(zhuǎn)成阻塞的async await => promise 改寫async函數(shù)中 let a=await promise 的a函數(shù) let b=await promise 的b函數(shù)promise.all改寫 Promise.allSettled Promise.anypromise實(shí)現(xiàn)promise.all的方法async使用的時(shí)候報(bào)錯(cuò),如何捕獲try...catchvar test3 = async function () {try {await p1();await p2();p3();} catch (e) {console.log('p1失敗了', e)}}await后面有個(gè)接口 接口要2S才能完成 接口2S才會(huì)執(zhí)行

$.ajax中async:false的阻塞和await這種阻塞有什么區(qū)別

沒區(qū)別

怎么攜帶cookie發(fā)送給后端

設(shè)置請(qǐng)求頭 請(qǐng)求頭中攜帶cookie

對(duì)象淺拷貝在react中用到哪些地方,為什么

為什么在react中要使用淺拷貝redux中要求:狀態(tài)是只讀的,唯一且不可修改的,reducer必須是一個(gè)純函數(shù)因?yàn)閞edux中數(shù)據(jù)不可更改,所以redux中的數(shù)據(jù)應(yīng)該要拷貝 返回一個(gè)新值

ajax、axios、fetch之間的詳細(xì)區(qū)別以及優(yōu)缺點(diǎn)

1.jQuery ajax $.ajax({type: 'POST',url: url,data: data,dataType: dataType,success: function () {},error: function () {}}); 優(yōu)缺點(diǎn):是對(duì)原生XHR的封裝,除此以外還增添了對(duì)JSONP的支持。本身是針對(duì)MVC的編程,不符合現(xiàn)在前端MVVM的浪潮基于原生的XHR開發(fā),XHR本身的架構(gòu)不清晰,已經(jīng)有了fetch的替代方案JQuery整個(gè)項(xiàng)目太大,單純使用ajax卻要引入整個(gè)JQuery非常的不合理(采取個(gè)性化打包的方案又不能享受CDN服務(wù))2.axiosaxios({method: 'post',url: '/user/12345',data: {firstName: 'Fred',lastName: 'Flintstone'}}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);}); 優(yōu)缺點(diǎn):Axios本質(zhì)上也是對(duì)原生XHR的封裝,只不過它是Promise的實(shí)現(xiàn)版本,符合最新的ES規(guī)范,從它的官網(wǎng)上可以看到它有以下幾條特性:從 node.js 創(chuàng)建 http 請(qǐng)求支持 Promise API客戶端支持防止CSRF提供了一些并發(fā)請(qǐng)求的接口(重要,方便了很多的操作)3.fetchtry {let response = await fetch(url);let data = response.json();console.log(data);} catch(e) {console.log("Oops, error", e);} 優(yōu)缺點(diǎn):符合關(guān)注分離,沒有將輸入、輸出和用事件來跟蹤的狀態(tài)混雜在一個(gè)對(duì)象里更好更方便的寫法更加底層,提供的API豐富(request, response)脫離了XHR,是ES規(guī)范里新的實(shí)現(xiàn)方式fetch是一個(gè)低層次的API,你可以把它考慮成原生的XHR,所以使用起來并不是那么舒服, 需要進(jìn)行封裝,例如: 1)fetch只對(duì)網(wǎng)絡(luò)請(qǐng)求報(bào)錯(cuò),對(duì)400,500都當(dāng)做成功的請(qǐng)求,需要封裝去處理 2)fetch默認(rèn)不會(huì)帶cookie,需要添加配置項(xiàng) 3)fetch不支持abort,不支持超時(shí)控制,使用setTimeout及Promise.reject的實(shí)現(xiàn)的超時(shí)控制并不能阻止請(qǐng)求過程繼續(xù)在后臺(tái)運(yùn)行,造成了量的浪費(fèi) 4)fetch沒有辦法原生監(jiān)測請(qǐng)求的進(jìn)度,而XHR可以為什么要用axios? axios 是一個(gè)基于Promise 用于瀏覽器和 nodejs 的 HTTP 客戶端,它本身具有以下特征:從瀏覽器中創(chuàng)建 XMLHttpRequest從 node.js 發(fā)出 http 請(qǐng)求支持 Promise API攔截請(qǐng)求和響應(yīng)轉(zhuǎn)換請(qǐng)求和響應(yīng)數(shù)據(jù)取消請(qǐng)求自動(dòng)轉(zhuǎn)換JSON數(shù)據(jù)客戶端支持防止CSRF/XSRF

回流/重繪 | 防抖/節(jié)流

回流: 當(dāng)渲染樹中的一部分或者全部因?yàn)樵氐某叽纭⒉季帧㈦[藏等改變而需要重新構(gòu)建的時(shí)候,這時(shí) 候就會(huì)發(fā)生回流。 每個(gè)?面都至少發(fā)生一次回流,也就是?面第一次加載的時(shí)候。 在回流的時(shí)候,瀏覽器會(huì)使渲染樹中受到影響的元素部分失效,并重新繪制這個(gè)部分的渲染樹, 完成回流以后,重繪: 當(dāng)渲染樹中的一些元素需要更新屬性,而這些屬性只是影響元素的外觀,風(fēng)格,而不會(huì)影響布局的,比如background-color。則就叫稱為重繪。防抖: 短時(shí)間內(nèi)多次觸發(fā)同一事件,只執(zhí)行最后一次,或者只執(zhí)行最開始的一次,中間的不執(zhí)行。 在事件觸發(fā)時(shí),開始計(jì)時(shí),在規(guī)定的時(shí)間(delay)內(nèi),若再次觸發(fā)事件,將上一次計(jì)時(shí)(timer)清空,然后重新開始計(jì)時(shí)。保證只有在規(guī)定時(shí)間內(nèi)沒有再次觸發(fā)事件之后,再去執(zhí)行這個(gè)事件。 節(jié)流: 指定時(shí)間間隔內(nèi),若事件被多次觸發(fā),只會(huì)執(zhí)行一次 在事件觸發(fā)之后,開始計(jì)時(shí),在規(guī)定的時(shí)間(delay)內(nèi),若再次觸發(fā)事件,不對(duì)此事件做任何處理。保證在規(guī)定時(shí)間內(nèi)只執(zhí)行一次事件.

減少重繪和回流的方式

CSS使用transform替代top使用visibility替換display:none避免使用table布局盡可能在DOM樹的最末端改變class避免設(shè)置多層內(nèi)聯(lián)樣式將動(dòng)畫效果應(yīng)用到position屬性為absoulte或fixed的元素上避免使用css表達(dá)式將頻繁重繪或者回流的節(jié)點(diǎn)設(shè)置為圖層css硬件加速JavaScript避免頻繁操作樣式避免頻繁操作DOM避免頻繁讀取會(huì)引發(fā)重繪/回流的屬性對(duì)具有復(fù)雜動(dòng)畫的元素使用絕對(duì)定位

事件循環(huán)Event Loop

Event Loop 即事件循環(huán) 是指瀏覽器或者Node的一種解決JavaScript單線程運(yùn)行時(shí)不阻塞的一種機(jī)制,單線程的是所有任務(wù)都在主線程上完成,任務(wù)太多的時(shí)候,頁面卡死,eventLoop可以解決單線程阻塞問題,程序中會(huì)有兩個(gè)線程,一個(gè)主線程,一個(gè)eventLoop線程,負(fù)責(zé)主線程和其他進(jìn)程之間的通信,遇到I/O的時(shí)候,主線程會(huì)讓eventLoop線程通知對(duì)應(yīng)的程序,主線程的任務(wù)會(huì)繼續(xù)往后執(zhí)行,等I/O程序執(zhí)行完了,eventLoop線程會(huì)把結(jié)果返回給主線程,主線程利用回調(diào)函數(shù)調(diào)用結(jié)果,完成任務(wù) (1)所有同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧(execution context stack)。 (2)主線程之外,還存在一個(gè)"任務(wù)隊(duì)列"(task queue)。只要異步任務(wù)有了運(yùn)行結(jié)果,就在"任務(wù)隊(duì)列"之中放置一個(gè)事件。 (3)一旦"執(zhí)行棧"中的所有同步任務(wù)執(zhí)行完畢,系統(tǒng)就會(huì)讀取"任務(wù)隊(duì)列",看看里面有哪些事件。那些對(duì)應(yīng)的異步任務(wù),于是結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開始執(zhí)行。 (4)主線程不斷重復(fù)上面的第三步。宏任務(wù)和微任務(wù)的執(zhí)行順序一次事件循環(huán)中,先執(zhí)行宏任務(wù)隊(duì)列里的一個(gè)任務(wù),再把微任務(wù)隊(duì)列里的所有任務(wù)執(zhí)行完畢,再去宏任務(wù)隊(duì)列取下一個(gè)宏任務(wù)執(zhí)行。

同步異步的區(qū)別

在js中,所有任務(wù)都分為同步任務(wù)和異步任務(wù)兩大類。同步任務(wù)指的是,在主線程上排隊(duì)執(zhí)行的任務(wù),只有前一個(gè)任務(wù)執(zhí)行完畢,才能執(zhí)行后一個(gè)任務(wù);異步任務(wù)指的是,不進(jìn)入主線程、而進(jìn)入"任務(wù)隊(duì)列"(task queue)的任務(wù),只有"任務(wù)隊(duì)列"通知主線程,某個(gè)異步任務(wù)可以執(zhí)行了,該任務(wù)才會(huì)進(jìn)入主線程執(zhí)行。(1)所有同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧(execution context stack)。 (2)主線程之外,還存在一個(gè)"任務(wù)隊(duì)列"(task queue)。只要異步任務(wù)有了運(yùn)行結(jié)果,就在"任務(wù)隊(duì)列"之中放置一個(gè)事件。 (3)一旦"執(zhí)行棧"中的所有同步任務(wù)執(zhí)行完畢,系統(tǒng)就會(huì)讀取"任務(wù)隊(duì)列",看看里面有哪些事件。那些對(duì)應(yīng)的異步任務(wù),于是結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開始執(zhí)行。 (4)主線程不斷重復(fù)上面的第三步。有時(shí)候 setTimeout明明寫的延時(shí)3秒,實(shí)際卻5,6秒才執(zhí)行函數(shù),這又是因?yàn)槭裁?#xff1f;答:setTimeout 并不能保證執(zhí)行的時(shí)間,是否及時(shí)執(zhí)行取決于 JavaScript 線程是擁擠還是空閑。 瀏覽器的JS引擎遇到setTimeout,拿走之后不會(huì)立即放入異步隊(duì)列,同步任務(wù)執(zhí)行之后,timer模塊會(huì)到設(shè)置時(shí)間之后放到異步隊(duì)列中。js引擎發(fā)現(xiàn)同步隊(duì)列中沒有要執(zhí)行的東西了,即運(yùn)行棧空了就從異步隊(duì)列中讀取,然后放到運(yùn)行棧中執(zhí)行。所以setTimeout可能會(huì)多了等待線程的時(shí)間。 這時(shí)setTimeout函數(shù)體就變成了運(yùn)行棧中的執(zhí)行任務(wù),運(yùn)行棧空了,再監(jiān)聽異步隊(duì)列中有沒有要執(zhí)行的任務(wù),如果有就繼續(xù)執(zhí)行,如此循環(huán),就叫Event Loop。

數(shù)據(jù)請(qǐng)求設(shè)置請(qǐng)求數(shù)據(jù)格式Content-Type

1.瀏覽器默認(rèn)的 application/x-www-form-urlencoded(url因扣得的) 這應(yīng)該是最常見的 POST 提交數(shù)據(jù)的方式了。瀏覽器的原生 form 表單,如果不設(shè)置 enctype 屬性,那么最終就會(huì)以 application/x-www-form-urlencoded 方式提交數(shù)據(jù)。2.multipart(莫踢怕特)/form-data 這也是一個(gè)常見的 POST 數(shù)據(jù)提交的方式。我們使用表單上傳文件時(shí),就要讓 form 的 enctype 等于這個(gè)值3.application/json 除了低版本 IE 之外的各大瀏覽器都原生支持 JSON.stringify 4.text/xml 相比于JSON,不能更好的適用于數(shù)據(jù)交換,它包含了太多的包裝, 而且它跟大多數(shù)編程語言的數(shù)據(jù)模型不匹配,讓大多數(shù)程序員感到詫異,XML是面向數(shù)據(jù)的,JSON是面向?qū)ο蠛徒Y(jié)構(gòu)的,JSON會(huì)給程序員一種更加親切的感覺。

數(shù)組扁平化

flat(infinite)

1. reduce遍歷數(shù)組每一項(xiàng),若值為數(shù)組則遞歸遍歷,否則concat。function flatten(arr) { return arr.reduce((result, item)=> {return result.concat(Array.isArray(item) ? flatten(item) : item);}, []); }reduce是數(shù)組的一種方法,它接收一個(gè)函數(shù)作為累加器,數(shù)組中的每個(gè)值(從左到右)開始縮減,最終計(jì)算為一個(gè)值。 reduce包含兩個(gè)參數(shù):回調(diào)函數(shù),傳給total的初始值// 求數(shù)組的各項(xiàng)值相加的和: arr.reduce((total, item)=> { // total為之前的計(jì)算結(jié)果,item為數(shù)組的各項(xiàng)值return total + item; }, 0);2. toString & split 調(diào)用數(shù)組的toString方法,將數(shù)組變?yōu)樽址缓笤儆胹plit分割還原為數(shù)組function flatten(arr) {return arr.toString().split(',').map(function(item) {return Number(item);}) } 因?yàn)閟plit分割后形成的數(shù)組的每一項(xiàng)值為字符串,所以需要用一個(gè)map方法遍歷數(shù)組將其每一項(xiàng)轉(zhuǎn)換為數(shù)值型3. join & split 和上面的toString一樣,join也可以將數(shù)組轉(zhuǎn)換為字符串function flatten(arr) {return arr.join(',').split(',').map(function(item) {return parseInt(item);}) }4. 遞歸遞歸的遍歷每一項(xiàng),若為數(shù)組則繼續(xù)遍歷,否則concatfunction flatten(arr) {var res = [];arr.map(item => {if(Array.isArray(item)) {res = res.concat(flatten(item));} else {res.push(item);}});return res; }5. 擴(kuò)展運(yùn)算符 es6的擴(kuò)展運(yùn)算符能將二維數(shù)組變?yōu)橐痪S[].concat(...[1, 2, 3, [4, 5]]); // [1, 2, 3, 4, 5]根據(jù)這個(gè)結(jié)果我們可以做一個(gè)遍歷,若arr中含有數(shù)組則使用一次擴(kuò)展運(yùn)算符,直至沒有為止。function flatten(arr) {while(arr.some(item=>Array.isArray(item))) {arr = [].concat(...arr);}return arr; }

如何擴(kuò)展數(shù)組,讓他擁有新的方法

Array.prototype.push.apply(a,b)

class中super作用是什么

es5 的繼承是先創(chuàng)建子類的this,然后將父類的方法添加到子類的this上去; es6 的繼承是創(chuàng)建父類的this對(duì)象,然后再對(duì)this對(duì)象添加方法/屬性。 而super方法就是用來創(chuàng)建父類this對(duì)象的。實(shí)際上執(zhí)行的是 super.sport.call(this);

xss攻擊和csrf攻擊是什么

1、CSRF(Cross-site request forgery):跨站請(qǐng)求偽造。 (1)登錄受信任網(wǎng)站A,并在本地生成Cookie。(如果用戶沒有登錄網(wǎng)站A,那么網(wǎng)站B在誘導(dǎo)的時(shí)候,請(qǐng)求網(wǎng)站A的api 接口時(shí),會(huì)提示你登錄) (2)在不登出A的情況下,訪問危險(xiǎn)網(wǎng)站B(其實(shí)是利用了網(wǎng)站A的漏洞)CSRF如何防御 方法一: Token 驗(yàn)證:(用的最多)(1)服務(wù)器發(fā)送給客戶端一個(gè)token;(2)客戶端提交的表單中帶著這個(gè)token。(3)如果這個(gè) token 不合法,那么服務(wù)器拒絕這個(gè)請(qǐng)求。 方法二: 隱藏令牌:把 token 隱藏在 http 的 head頭中。方法二和方法一有點(diǎn)像,本質(zhì)上沒有太大區(qū)別,只是使用方式上有區(qū)別。 方法三: Referer(銳服爾) 驗(yàn)證:Referer 指的是頁面請(qǐng)求來源。意思是,只接受本站的請(qǐng)求,服務(wù)器才做響應(yīng);如果不是,就攔截。2、XSS(Cross Site Scripting):跨域腳本攻擊。 XSS攻擊的核心原理是:不需要你做任何的登錄認(rèn)證,它會(huì)通過合法的操作(比如在url中輸入、在評(píng)論框中輸入),向你的頁面注入腳本(可能是js、hmtl代碼塊等)。 最后導(dǎo)致的結(jié)果可能是:盜用Cookie破壞頁面的正常結(jié)構(gòu),插入廣告等惡意內(nèi)容D-doss攻擊 XSS的攻擊方式 1、反射型發(fā)出請(qǐng)求時(shí),XSS代碼出現(xiàn)在url中,作為輸入提交到服務(wù)器端,服務(wù)器端解析后響應(yīng),XSS代碼隨響應(yīng)內(nèi)容一起傳回給瀏覽器,最后瀏覽器解析執(zhí)行XSS代碼。這個(gè)過程像一次反射,所以叫反射型XSS。 2、存儲(chǔ)型存儲(chǔ)型XSS和反射型XSS的差別在于,提交的代碼會(huì)存儲(chǔ)在服務(wù)器端(數(shù)據(jù)庫、內(nèi)存、文件系統(tǒng)等),下次請(qǐng)求時(shí)目標(biāo)頁面時(shí)不用再提交XSS代碼。XSS的防范措施(encode + 過濾)主要有三個(gè): 1、編碼:對(duì)用戶輸入的數(shù)據(jù)進(jìn)行HTML Entity(安特踢) 編碼。 2、過濾:移除用戶輸入的和事件相關(guān)的屬性。如onerror可以自動(dòng)觸發(fā)攻擊,還有onclick等。(總而言是,過濾掉一些不安全的內(nèi)容)移除用戶輸入的Style節(jié)點(diǎn)、Script節(jié)點(diǎn)、Iframe節(jié)點(diǎn)。(尤其是Script節(jié)點(diǎn),它可是支持跨域的呀,一定要移除)。 3、校正避免直接對(duì)HTML Entity進(jìn)行解碼。使用DOM Parse轉(zhuǎn)換,校正不配對(duì)的DOM標(biāo)簽。這個(gè)概念,它的作用是把文本解析成DOM結(jié)構(gòu)。比較常用的做法是,通過第一步的編碼轉(zhuǎn)成文本,然后第三步轉(zhuǎn)成DOM對(duì)象,然后經(jīng)過第二步的過濾。還有一種簡潔的答案:首先是encode,如果是富文本,就白名單。3、CSRF 和 XSS 的區(qū)別: 區(qū)別一:CSRF:需要用戶先登錄網(wǎng)站A,獲取 cookie。XSS:不需要登錄。 區(qū)別二:(原理的區(qū)別)CSRF:是利用網(wǎng)站A本身的漏洞,去請(qǐng)求網(wǎng)站A的api。XSS:是向網(wǎng)站 A 注入 JS代碼,然后執(zhí)行 JS 里的代碼,篡改網(wǎng)站A的內(nèi)容。

webapp和小程序有什么區(qū)別

首先,微信小程序已經(jīng)提供了一套 view, data, model, router 層的開發(fā)工具, 對(duì)于開發(fā)簡單應(yīng)用,小程序是可以比 webapp 更加快速的。但是實(shí)際上微信小程序提供的這一套開發(fā)框架,要開發(fā)一些復(fù)雜應(yīng)用,是很困難的, 因?yàn)?#xff1a;小程序不支持 npm 等 package manager(麥呢橘)無法復(fù)用社區(qū)中已經(jīng)很成熟的 web 框架和工具組件只能封裝 view 和 style,無法封裝行為(handler),行為只能定義在 page 上小程序有 1mb 的限制,所以我們只能將圖片之類的靜態(tài)資源事先放在服務(wù)器上其次,微信小程序是由微信自己來 host,開發(fā)者只需要上傳就好, 而微信 webapp 需要開發(fā)者自己 host,還需要注冊(cè)域名甚至備案才可以調(diào)用微信接口以及跟公眾號(hào)集成。 所以微信小程序降低了開發(fā)者的門檻。綜上,對(duì)于簡單的工具型應(yīng)用,微信小程序可以讓開發(fā)者加快開發(fā)速度,降低發(fā)布門檻, 這種類型的應(yīng)用比較適合微信小程序。對(duì)于復(fù)雜的應(yīng)用,webapp 是更適合的形式。

react優(yōu)缺點(diǎn)

優(yōu)點(diǎn): 1、采用虛擬 DOM,它并不直接對(duì)DOM進(jìn)行操作,安插在javascript邏輯和實(shí)際的DOM之間,性能好 2、跨瀏覽器兼容:虛擬DOM幫助我們解決了跨瀏覽器問題,它為我們提供了標(biāo)準(zhǔn)化的API,甚至在IE8中都是沒問題的。 3、一切都是組件:代碼更加 模塊化 ,重用代碼更容易,可維護(hù)性高。 4、單向數(shù)據(jù)流:redux 實(shí)現(xiàn)是一個(gè)用于在JavaScript應(yīng)用中創(chuàng)建單向數(shù)據(jù)層的架構(gòu),它隨著React視圖庫的開發(fā)而被Facebook概念化。 5、同構(gòu)、純粹的javascript:因?yàn)樗阉饕娴呐老x程序依賴的是服務(wù)端響應(yīng)而不是JavaScript的執(zhí)行,預(yù)渲染你的應(yīng)用有助于搜索引擎優(yōu)化。 6、兼容性好:比如使用RequireJS來加載和打包,而Browserify(不弱瑟)和Webpack適用于構(gòu)建大型應(yīng)用。它們使得那些艱難的任務(wù)不再讓人望而生畏。 7、JSX語法:為了更加便利的模擬DOM結(jié)構(gòu),我們使用了JSX語法,可以讓我們?cè)贘S中編譯DOM結(jié)構(gòu) 8、函數(shù)式編程:JS的最大特點(diǎn)就是函數(shù)式編程,在React中,函數(shù)式編程可謂式無處不見缺點(diǎn): 不適合單獨(dú)做一個(gè)完整的框架:react是視圖層框架,大型項(xiàng)目想要一套完整的框架的話,也許還需要引入Flux和route相關(guān)的東西。

react生命周期

16版本: 初始階段: constructor定義state componentWillMount(這個(gè)鉤子函數(shù)在將來會(huì)被棄用)為掛載做準(zhǔn)備工作 render 解析 this.state 和 this.props 將jsx型的虛擬dom渲染為對(duì)象類型的虛擬domrender 中不允許使用 this.setState() 如何你使用了,就會(huì)棧溢出 componentDidMount表示組件掛載結(jié)束虛擬dom -> Real dom可以獲取真實(shí)dom數(shù)據(jù)請(qǐng)求 -> 賦值給state第三方庫實(shí)例化/DOM操作更新階段: componentWillReceiveProps(在17版本中被棄用)這個(gè)鉤子實(shí)際作用是判斷組件身上的props是否發(fā)生改變 shouldComponentUpdate可以決組件是否要更新渲染 return true/false接收新舊狀態(tài),用于作對(duì)比(淺對(duì)比)一般需要我們手動(dòng)作深對(duì)比這個(gè)鉤子函數(shù)是React組件性能優(yōu)化的一種方式 componentWillUpdate表示組件更新前的準(zhǔn)備這個(gè)鉤子函數(shù)在未來版本被棄用 render和初始化階段的作用一致 componentDidUpdate對(duì)Real dom 作操作注意:父組件數(shù)據(jù)更新,子組件會(huì)重新運(yùn)行render,反之不行每次都要運(yùn)行子組件render,會(huì)造成react性能浪費(fèi) 粗略解決方案:在shouldComponentUpdate中,可判斷哪些數(shù)據(jù)改變從而來控制return true/false 繼而決定是否需要更新render渲染更好的解決方案:1.引用PureComponent,讓類組件繼承(extends)PureComponent 如:class App extends PureComponent{}2.引用memo,讓函數(shù)組件寫在memo()里 如:const memoApp =memo(function App() {})3.除了memo之外,更細(xì)致的是函數(shù)組件中還可以用useCallback(方法)和useMemo(對(duì)象和數(shù)組)兩個(gè)鉤子阻止組件render銷毀階段: componentWillUnmount銷毀組件清除無用實(shí)例和事件 錯(cuò)誤捕獲:componentDidCatch用戶捕獲子組件throw的錯(cuò)誤,然后顯示回退UI15版本: 相對(duì)于16版本,初始化階段(constructor鉤子變成下列兩個(gè)):定義于初始化props的 getDefalutProps 鉤子函數(shù)定義于初始化state的 getInitialState 鉤子函數(shù) 沒有錯(cuò)誤捕獲階段17版本: 相對(duì)于16版本 少3多2少了componentWillMount,componentWillReceiveProps,componentWillUpdate 3個(gè)鉤子函數(shù)(斯塔得可) (迪外的) 多了static getDerivedStateFromProps鉤子函數(shù) (破外服)一個(gè)靜態(tài)方法,所以不能在這個(gè)函數(shù)里面使用this,這個(gè)函數(shù)有兩個(gè)參數(shù)nextProps和prevState,這個(gè)函數(shù)會(huì)返回一個(gè)對(duì)象用來更新當(dāng)前的state對(duì)象,如果不需要更新可以返回null。簡單說就是,可以增加一次state狀態(tài)(斯那坡秀的) 多了getSnapshotBeforeUpdate鉤子函數(shù)快照這個(gè)函數(shù)有一個(gè)返回值,會(huì)作為第三個(gè)參數(shù)傳遞給componentDidUpdate鉤子

redux流程 redux的原理

view用actionCreator(酷睿A特)創(chuàng)建一個(gè)action,里面可能包含一些數(shù)據(jù) 使用store的dispatch方法將action傳入store store將action與舊的state轉(zhuǎn)發(fā)給reducer reducer深拷貝state,并返回一個(gè)新的state給store store接收并更新state 使用store.subscribe(薩布斯快不)訂閱更新,重新render組件redux組成state :用來存儲(chǔ)數(shù)據(jù)和數(shù)據(jù)管理的、更新視圖reducer:是一個(gè)純函數(shù),接收舊 state 和 action,根據(jù)不同的 Action 做出不同的操作并返回新的 stateactions:發(fā)送動(dòng)作給reducer,reducer接收動(dòng)作,判斷動(dòng)作類型修改數(shù)據(jù),修改事件后,組件重新做redux事件的訂閱Redux三大原則 單一數(shù)據(jù)源:整個(gè)應(yīng)用的 state 被存儲(chǔ)在一個(gè) Object tree 中,且只存在于唯一的Store中state 是只讀的:唯一改變 state 的方法就是觸發(fā) action,action 是一個(gè)用于描述發(fā)生事件的普通對(duì)象,視圖部分只需要表達(dá)想要修改的意圖,所有修改都會(huì)被集中化處理。狀態(tài)的改變通過純函數(shù)來完成:Redux使用純函數(shù)方式來執(zhí)行狀態(tài)的修改,Action表明了修改狀態(tài)值的意圖,而真正執(zhí)行狀態(tài)修改的則是Reducer。且Reducer必須是一個(gè)純函數(shù),當(dāng)Reducer接收到Action時(shí),Action并不能直接修改State的值,而是通過創(chuàng)建一個(gè)新的狀態(tài)對(duì)象來返回修改的狀態(tài)。

redux 中間件

在action 和 store 之間執(zhí)行中間件Redux中間件機(jī)制Redux本身就提供了非常強(qiáng)大的數(shù)據(jù)流管理功能,但這并不是它唯一的強(qiáng)大之處,它還提供了利用中間件來擴(kuò)展自身功能,以滿足用戶的開發(fā)需求(米的為爾) applyMiddlewares():它是 Redux 的原生方法,作用是將所有中間件組成一個(gè)數(shù)組,依次執(zhí)行。 applyMiddleware顧名思義,用于調(diào)用各種中間件; applyMiddleware執(zhí)行后,將所有入?yún)⒅虚g件存入一個(gè)數(shù)組,并且返回一個(gè)閉包(閉包的概念不做累述) 閉包接受一個(gè)createStore作為入?yún)⒉⑶覉?zhí)行后返回下一個(gè)閉包。

redux-thunk|異步action

首先檢查參數(shù) action 的類型,如果是函數(shù)的話,就執(zhí)行這個(gè) action 函數(shù), 并把 dispatch, getState, extraArgument(哎克斯拽埃歌門特) 作為參數(shù)傳遞進(jìn)去, 否則就調(diào)用 next 讓下一個(gè)中間件繼續(xù)處理 action 好處可以進(jìn)行前后端數(shù)據(jù)交互 缺點(diǎn)將帶有數(shù)據(jù)請(qǐng)求的action和沒有帶有數(shù)據(jù)請(qǐng)求的action混在一起了缺點(diǎn)解決: 棄用redux-thunk,使用redux-sagaredux-saga可以將異步action和普通action區(qū)別開來

redux-saga|集中處理異步action

redux-saga可以將異步action和普通action區(qū)別開來,控制器與更優(yōu)雅的異步處理 redux-saga就是用Generator(杰呢瑞特)來處理異步。redux-saga文檔并沒有說自己是處理異步的工具,而是說用來處理邊際效應(yīng)(side effects),這里的邊際效應(yīng)你可以理解為程序?qū)ν獠康牟僮?#xff0c;比如請(qǐng)求后端,比如操作文件。redux-saga相當(dāng)于在Redux原有數(shù)據(jù)流中多了一層,通過對(duì)Action進(jìn)行監(jiān)聽,從而捕獲到監(jiān)聽的Action,然后可以派生一個(gè)新的任務(wù)對(duì)state進(jìn)行維護(hù)(這個(gè)看項(xiàng)目本身的需求),通過更改的state驅(qū)動(dòng)View的變更。redux-saga同樣是一個(gè)redux中間件,它的定位就是通過集中控制action,起到一個(gè)類似于MVC中控制器的效果。 同時(shí)它的語法使得復(fù)雜異步操作不會(huì)像promise那樣出現(xiàn)很多then的情況,更容易進(jìn)行各類測試。

redux與react-redux的關(guān)系

redux是獨(dú)立的應(yīng)用狀態(tài)管理工具。它是可以獨(dú)立于react之外的。如果我們需要在react當(dāng)中運(yùn)用它,那么我們需要手動(dòng)訂閱store的狀態(tài)變化,來對(duì)我們的react組件進(jìn)行更新。react-reudx這個(gè)工具,就幫我們實(shí)現(xiàn)了這個(gè)功能,我們只需對(duì)store進(jìn)行處理,react組件就會(huì)有相應(yīng)的變化。Redux的核心由三部分組成:Store, Action, Reducer。 Store: 是個(gè)對(duì)象,貫穿你整個(gè)應(yīng)用的數(shù)據(jù)都應(yīng)該存儲(chǔ)在這里。 Action: 是個(gè)對(duì)象,必須包含type這個(gè)屬性,reducer將根據(jù)這個(gè)屬性值來對(duì)store進(jìn)行相應(yīng)的處理。除此之外的屬性,就是進(jìn)行這個(gè)操作需要的數(shù)據(jù)。 Reducer: 是個(gè)函數(shù)。接受兩個(gè)參數(shù):要修改的數(shù)據(jù)(state) 和 action對(duì)象。根據(jù)action.type來決定采用的操作,對(duì)state進(jìn)行修改,最后返回新的state。總結(jié) Redux: store, action, reducer store: getState, dispatch, subscribe combineReducers (克木拜恩) createStore store ? dispatch ? action ? reducerreact-redux: connect : 將store作為props注入 provider(破外的): 使store在子孫組件的connect中能夠獲取到

react-reudx

1. UI組件|顯示頁面?? (破森特遜弄)React-Redux 將所有組件分成兩大類:UI 組件(presentational component)和容器組件 2. 容器組件|負(fù)責(zé)管理數(shù)據(jù)/復(fù)雜邏輯?UI 組件負(fù)責(zé) UI 的呈現(xiàn),容器組件負(fù)責(zé)管理數(shù)據(jù)和邏輯。 3. Provider組件|容器組件獲取state??所有的 UI 組件都由用戶提供,容器組件則是由 React-Redux 自動(dòng)生成。也就是說,用戶負(fù)責(zé)視覺層,狀態(tài)管理則是全部交給它。 4. connect()|UI組件+容器組件React-Redux 提供connect方法,用于從 UI 組件生成容器組件。connect的意思,就是將這兩種組件連起來。

DVA與CRA相比的優(yōu)點(diǎn)

dva:dva 首先是一個(gè)基于 redux 和 redux-saga 的數(shù)據(jù)流方案,然后為了簡化開發(fā)體驗(yàn),dva 還額外內(nèi)置了 react-router 和 fetch,所以也可以理解為一個(gè)輕量級(jí)的應(yīng)用框架。--- 來自官方。相比于cra只是多了內(nèi)置的redux和redux-saga,幫我們處理了數(shù)據(jù)流這方面的需求而已。如果只是想要達(dá)到這個(gè)效果的話,直接在cra中增加dva-core的依賴也是可以做到的。umi:是一個(gè)可插拔的企業(yè)級(jí) react 應(yīng)用框架。umi和cra都是應(yīng)用框架,可能相比cra來說umi的功能點(diǎn)更多一些,只能說是功能性的話umi要相對(duì)來說更勝一籌

flux

flux 是 react 中的類似于 vuex 的公共狀態(tài)管理方案,它是 Facebook 官方給出的應(yīng)用架構(gòu),利用數(shù)據(jù)的單向流動(dòng)的形式對(duì)公共狀態(tài)進(jìn)行管理。現(xiàn)已不推薦使用。flux的組成View:視圖層Action:視圖發(fā)出的消息Dispatcher:派發(fā)者,用來接收Action,執(zhí)行回調(diào)函數(shù)Store:數(shù)據(jù)層,存放狀態(tài),一旦發(fā)生改動(dòng)flux 在進(jìn)行數(shù)據(jù)更新時(shí),會(huì)經(jīng)歷以下幾步:用戶與 View 層交互,觸發(fā) ActionAction 使用 dispatcher.dispatch 將Action自己的狀態(tài)發(fā)送給dispatcherdispatcher 通過register注冊(cè)事件,再通過Action傳入的類型來觸發(fā)對(duì)應(yīng)的 Store 回調(diào)進(jìn)行更新Store 里進(jìn)行相應(yīng)的數(shù)據(jù)更新,并觸發(fā) View 層事件使試圖也同步更新View層 收到信號(hào)進(jìn)行更新redux和flux的區(qū)別1)redux是flux中的一個(gè)實(shí)現(xiàn)Flux的核心思想就是數(shù)據(jù)和邏輯永遠(yuǎn)單向流動(dòng)2)在redux中我們只能定義一個(gè)store,在flux中我們可以定義多個(gè)3)在redux中,store和dispatch都放到了store,結(jié)構(gòu)更加清晰4)在redux中本身就內(nèi)置State對(duì)象,對(duì)倉庫的管理更加明確

React 中 keys 的作用

key是react用于追蹤哪些列表被修改、被添加或者被移出的輔助標(biāo)識(shí)。在開發(fā)過程中,我們需要保證某些元素在同級(jí)的元素中key是具有唯一性的特性,在react Diff算法中React會(huì)借助元素的key值來判斷該元素是新創(chuàng)建的還是移動(dòng)而來的元素,從而減少元素的不必要的重復(fù)渲染。此外,我們還需要借助key值來判斷元素與本地狀態(tài)的關(guān)聯(lián)關(guān)系,因此我們絕不可忽視轉(zhuǎn)換函數(shù)中 Key 的重要性。react根據(jù)key來決定是銷毀重新創(chuàng)建組件還是更新組件,原則是:key相同,組件有所變化,react會(huì)只更新組件對(duì)應(yīng)變化的屬性。 key不同,組件會(huì)銷毀之前的組件,將整個(gè)組件重新渲染。

react新特性和diff算法

render 支持返回這五類: React elements, 數(shù)組, Fragments, Portal, String/numbers, boolean/null, 基礎(chǔ)數(shù)據(jù)類型Fiber React Fiber的方法其實(shí)很簡單——分片。把一個(gè)耗時(shí)長的任務(wù)分成很多小片,每一個(gè)小片的運(yùn)行時(shí)間很短,雖然總時(shí)間依然很長,但是在每個(gè)小片執(zhí)行完之后,都給其他任務(wù)一個(gè)執(zhí)行的機(jī)會(huì),這樣唯一的線程就不會(huì)被獨(dú)占,其他任務(wù)依然有運(yùn)行的機(jī)會(huì)。新的生命周期函數(shù) 由于異步渲染的改動(dòng),componentWillMount, componentWillReceiveProps,componentWillUpdate 三個(gè)函數(shù)將被廢棄。 由于這是一個(gè)很大的改變會(huì)影響很多現(xiàn)有的組件,所以需要慢慢的去改。 目前react 16 只是會(huì)報(bào)warning,在react 17就只能在前面加UNSAFE_的前綴來使用diff算法 作用: 計(jì)算出Virtual DOM中真 正變化的部分,并只針對(duì)該部分進(jìn)行原生DOM操作,而非重新渲染整個(gè)頁面getDerivedStateFromProps static getDerivedStateFromProps(props, state)在調(diào)用render方法之前調(diào)用, 無論是在初始安裝還是后續(xù)更新。它應(yīng)返回一個(gè)對(duì)象來更新狀態(tài),或者返回null以不更新任何內(nèi)容。根據(jù)props更新state 這個(gè)生命周期可用于替代componentWillReceivePropsgetSnapshotBeforeUpdate() getSnapshotBeforeUpdate(prevProps, prevState)在最近呈現(xiàn)的輸出被提交到例如DOM之前調(diào)用。它使組件可以在可能更改之前從DOM捕獲一些信息(例如滾動(dòng)位置)。此生命周期返回的任何值都將作為參數(shù)傳遞給componentDidUpdate()。hookslazy、suspense lazy需要跟Suspence配合使用。 lazy實(shí)際上是幫助我們實(shí)現(xiàn)代碼分割的功能。由于有些內(nèi)容,并不一定要在首屏展示,所以這些資源沒有必要一開始就要去獲取,那么這些資源就可以動(dòng)態(tài)獲取。 這樣的話,相當(dāng)于把不需要首屏展示的代碼分割出來,減少首屏代碼的體積,提升性能。Suspence 很像Error Boundary,不同的是Error Boundary是用來捕獲錯(cuò)誤,顯示相應(yīng)的callback組件。而Suspence是用來捕獲還沒有加載好的組件,并暫停渲染,顯示相應(yīng)的callback。

setState概述,同步異步

1. 兩個(gè)參數(shù)及用法第一個(gè)參數(shù)可以是對(duì)象或者函數(shù),是更新state 第二個(gè)參數(shù)獲取最新的state,副作用操作,dom操作事件觸發(fā)聲明,數(shù)據(jù)獲取,第三方庫實(shí)例化2. 同步/異步原理setState在合成事件和鉤子函數(shù)中是異步的 在原生事件和setTimeout中是同步的setState的“異步”并不是說內(nèi)部由異步代碼實(shí)現(xiàn),其實(shí)本身執(zhí)行的過程和代碼都是同步的,只是合成事件和鉤子函數(shù)的調(diào)用順序在更新之前,導(dǎo)致在合成事件和鉤子函數(shù)中沒法立馬拿到更新后的值,形式了所謂的“異步”,當(dāng)然可以通過第二個(gè)參數(shù) setState(partialState, callback) 中的callback拿到更新后的結(jié)果。setState 的批量更新優(yōu)化也是建立在“異步”(合成事件、鉤子函數(shù))之上的,在原生事件和setTimeout 中不會(huì)批量更新,在“異步”中如果對(duì)同一個(gè)值進(jìn)行多次 setState , setState 的批量更新策略會(huì)對(duì)其進(jìn)行覆蓋,取最后一次的執(zhí)行,如果是同時(shí) setState 多個(gè)不同的值,在更新時(shí)會(huì)對(duì)其進(jìn)行合并批量更新。

react合成事件

1. 合成事件原理如果DOM上綁定了過多的事件處理函數(shù),整個(gè)頁面響應(yīng)以及內(nèi)存占用可能都會(huì)受到影響。React為了避免這類DOM事件濫用,同時(shí)屏蔽底層不同瀏覽器之間的事件系統(tǒng)差異,實(shí)現(xiàn)了一個(gè)中間層——SyntheticEvent。當(dāng)用戶在為onClick添加函數(shù)時(shí),React并沒有將Click時(shí)間綁定在DOM上面。 而是在document處監(jiān)聽所有支持的事件,當(dāng)事件發(fā)生并冒泡至document處時(shí),React將事件內(nèi)容封裝交給中間層SyntheticEvent(負(fù)責(zé)所有事件合成) 所以當(dāng)事件觸發(fā)的時(shí)候,對(duì)使用統(tǒng)一的分發(fā)函數(shù)dispatchEvent將指定函數(shù)執(zhí)行。2. 與原生事件的區(qū)別React合成事件一套機(jī)制:React并不是將click事件直接綁定在dom上面,而是采用事件冒泡的形式冒泡到document上面,然后React將事件封裝給正式的函數(shù)處理運(yùn)行和處理。

react路由傳參和讀參

1.params <Route path='/path/:name' component={Path}/> <link to="/path/2">xxx</Link> this.props.history.push({pathname:"/path/" + name}); 讀取參數(shù)用:this.props.match.params.name 優(yōu)勢(shì):刷新地址欄,參數(shù)依然存在 缺點(diǎn):只能傳字符串,并且,如果傳的值太多的話,url會(huì)變得長而丑陋。2.query <Route path='/query' component={Query}/> <Link to={{ path : ' /query' , query : { name : 'sunny' }}}> this.props.history.push({pathname:"/query",query: { name : 'sunny' }}); 讀取參數(shù)用: this.props.location.query.name 優(yōu)勢(shì): 傳參優(yōu)雅,傳遞參數(shù)可傳對(duì)象; 缺點(diǎn): 刷新地址欄,參數(shù)丟失3.state <Route path='/sort ' component={Sort}/> <Link to={{ path : ' /sort ' , state : { name : 'sunny' }}}> this.props.history.push({pathname:"/sort ",state : { name : 'sunny' }}); 讀取參數(shù)用: this.props.location.query.state 優(yōu)缺點(diǎn)同query4.search <Route path='/web/departManange ' component={DepartManange}/> <link to="web/departManange?tenantId=12121212">xxx</Link> this.props.history.push({pathname:"/web/departManange?tenantId" + row.tenantId}); 讀取參數(shù)用: this.props.location.search 優(yōu)缺點(diǎn)同params

redux和mobx(類似雙向數(shù)據(jù)綁定)區(qū)別

1. 組成部分actions->state->computed values->Reactions 2. 工作流在mobx中, 數(shù)據(jù)是通過加 @observable 作為可監(jiān)測的被觀察者, 在view層中, 你可以通過添加@observer 將view作為觀察者,對(duì)數(shù)據(jù)進(jìn)行監(jiān)測, 如果要觸發(fā)改變數(shù)據(jù),則使用@action, 事實(shí)上,你可以直接在view層改變數(shù)據(jù), 但這種方式不便監(jiān)控?cái)?shù)據(jù),因此不推薦直接改變數(shù)據(jù)。 而@computed可以用來計(jì)算數(shù)據(jù), 也可以是計(jì)算多個(gè)數(shù)據(jù)之后返回新的數(shù)據(jù), 如果其中數(shù)據(jù)改變, @computed也會(huì)觸發(fā)改變 3. 優(yōu)點(diǎn)不同于redux的單一數(shù)據(jù)流, mobx中,你可以同時(shí)在各個(gè)地方使用同一份state, 也可以在一個(gè)頁面中使用多個(gè)store文件

react組件通信5種

1.父組件向子組件通信 React數(shù)據(jù)流動(dòng)是單向的,父組件向子組件通信也是最常見的;父組件通過props向子組件傳遞需要的信息2.子組件向父組件通信 利用回調(diào)函數(shù),可以實(shí)現(xiàn)子組件向父組件通信:父組件將一個(gè)函數(shù)作為 props 傳遞給子組件,子組件調(diào)用該回調(diào)函數(shù),便可以向父組件通信。3.非嵌套組件間通信 非嵌套組件,就是沒有任何包含關(guān)系的組件,包括兄弟組件以及不在同一個(gè)父級(jí)中的非兄弟組件。對(duì)于非嵌套組件,可以采用下面兩種方式:利用二者共同父組件的 context 對(duì)象進(jìn)行通信使用自定義事件的方式 如果采用組件間共同的父級(jí)來進(jìn)行中轉(zhuǎn),會(huì)增加子組件和父組件之間的耦合度,如果組件層次較深的話,找到二者公共的父組件不是一件容易的事,當(dāng)然還是那句話,也不是不可以。4.跨組件通信 所謂跨級(jí)組件通信,就是父組件向子組件的子組件通信,向更深層的子組件通信。跨級(jí)組件通信可以采用下面兩種方式:中間組件層層傳遞 props使用 context 對(duì)象 中間組件層層傳遞 props:如果父組件結(jié)構(gòu)較深,那么中間的每一層組件都要去傳遞 props,增加了復(fù)雜度,并且這些 props 并不是這些中間組件自己所需要的。不過這種方式也是可行的,當(dāng)組件層次在三層以內(nèi)可以采用這種方式,當(dāng)組件嵌套過深時(shí),采用這種方式就需要斟酌了。使用 context 對(duì)象:context 相當(dāng)于一個(gè)全局變量,是一個(gè)大容器,我們可以把要通信的內(nèi)容放在這個(gè)容器中,這樣一來,不管嵌套有多深,都可以隨意取用。 使用 context 也很簡單,需要滿足兩個(gè)條件:上級(jí)組件要聲明自己支持 context,并提供一個(gè)函數(shù)來返回相應(yīng)的 context 對(duì)象子組件要聲明自己需要使用 context5.redux 首先由view dispatch攔截action,然后執(zhí)行對(duì)應(yīng)reducer并更新到store中,最終views會(huì)根據(jù)store數(shù)據(jù)的改變執(zhí)行界面的刷新渲染操作。1)首先先把redux相關(guān)工具安裝好 2)通過創(chuàng)建一個(gè)store實(shí)例createStore,接收一個(gè)rootReducer和中間件執(zhí)行函數(shù)3)創(chuàng)建分塊的數(shù)據(jù)rootReducer,通過combineReducers打造rootReducer,里面放分塊的數(shù)據(jù)4)在組件中通過高階組件connect函數(shù),接收store里的數(shù)據(jù),把ActionCreators里的方法綁定到組件身上,并且可以發(fā)送動(dòng)作action給reducer5)在reductor中根據(jù)action中的type動(dòng)作類型,判斷動(dòng)作修改數(shù)據(jù)

組件按需加載

(實(shí)現(xiàn)方式,需要的依賴)懶加載1、vue異步組件技術(shù)vue-router配置路由,使用vue的異步組件技術(shù),可以實(shí)現(xiàn)按需加載。但是,這種情況下一個(gè)組件生成一個(gè)js文件。2.import()3.webpack提供的require.ensure()4.第三方庫比如react-loadable 5.lazyload-loader

組件銷毀

componentWillUnmount定義state flag:false 作為開關(guān) 定義方法if判斷是否為1,改變state flag:true將方法綁定組件上 可以用三目或者短路原則&&控制組件的顯示隱藏

Ant D中input輸入框三個(gè)屬性怎么實(shí)現(xiàn)

onChange輸入框內(nèi)容改變時(shí)候回調(diào) value輸入的內(nèi)容 defaultValue輸入框默認(rèn)值input默認(rèn)值在input中綁定value 定義一個(gè)state 和input雙向數(shù)據(jù)綁定 做成受控組件 定義一個(gè)事件 改變的時(shí)候獲取e.target.value

Hooks

為什么使用hook不必寫class組件就可以用state和其他的React特性;自定義hook 實(shí)現(xiàn)組件的復(fù)用 用useEffects代替生命周期方法 代碼更加簡潔出現(xiàn)原因3點(diǎn)為了讓函數(shù)組件擁有類組件的功能。原因比如useState、useReducer 狀態(tài)定義比如useEffect、useLayoutEffect 生命周期功能比如useRef useImperativeHandle 替代了類組件的 Ref為了優(yōu)化函數(shù)組件,比如useMemo、useCallback函數(shù)組件添加新的方法,如useDebugValue顯示自定義hook,自己添加hook類名自定義hooks來復(fù)用狀態(tài)優(yōu)點(diǎn)4點(diǎn) 1.讓函數(shù)組件可以定義狀態(tài) 讓函數(shù)組件可以使用生命周期、監(jiān)聽數(shù)據(jù)讓函數(shù)組件可以有Ref的功能(父組件獲取子組件)優(yōu)化函數(shù)組件 useMemo、useCallback自定義hooks來復(fù)用狀態(tài),代碼量比類組件更少,更清爽。 2.使用規(guī)則2點(diǎn)不要在循環(huán),條件或嵌套函數(shù)中調(diào)用 Hook只在函數(shù)組件中使用 Hooks 3.常用HookuseState:定義狀態(tài) 修改狀態(tài)返回一個(gè)數(shù)組,其中第一項(xiàng)是狀態(tài)值,第二項(xiàng)是一個(gè)更新狀態(tài)的函數(shù)。狀態(tài)一旦改變,React 就會(huì)重新渲染組件,變量獲取新的狀態(tài)值。useEffect:相當(dāng)于componentDidMount,componentDidUpdate,componentWillUnmount三個(gè)鉤子的組合參數(shù)一:執(zhí)行的回調(diào)函數(shù);參數(shù)二:該useEffect在哪些state發(fā)生變化時(shí),才重新執(zhí)行;第二個(gè)參數(shù)是空數(shù)組的時(shí)候執(zhí)行一次,相當(dāng)于componentDidMount,不加的時(shí)候執(zhí)行多次第二個(gè)參數(shù)的作用就是 僅在更改時(shí)更新,實(shí)現(xiàn)性能的優(yōu)化DOM操作 第三方實(shí)例化可以做 清除無用實(shí)例和事件useEffect傳入的回調(diào)函數(shù)本身可以有一個(gè)返回值,這個(gè)返回值是另外一個(gè)回調(diào)函數(shù),來模擬componentWillUnmountuseLayoutEffect:布局副作用useEffect 在瀏覽器渲染完成后執(zhí)行useLayoutEffect 在瀏覽器渲染前執(zhí)行,在render過程中,會(huì)阻塞Dom渲染useLayoutEffect 里的任務(wù)最好影響了 Layout為了用戶體驗(yàn),優(yōu)先使用 useEffect (優(yōu)先渲染)useContext:跨組件通信 createContext創(chuàng)建一個(gè)組件 <numContext.Provider value={num}>useDebugValue:自定義 hook 的標(biāo)簽 方便調(diào)試臺(tái)查看useMemo:記憶組件 動(dòng)態(tài)緩存 新值和舊值一樣,不重新渲染頁面,優(yōu)化作用,類似于shouldComponentUpdate useCallBack:作用和 useMemo 一樣useMemo和useCallback都會(huì)在組件第一次渲染的時(shí)候執(zhí)行,之后會(huì)在其依賴的變量發(fā)生改變時(shí)再次執(zhí)行并且這兩個(gè)hooks都返回緩存的值,useMemo返回緩存的變量,useCallback返回緩存的函數(shù)。useCallback(x => console.log(x), [m]) 等價(jià)于useMemo( () => x => console.log(x), [m])useRef:返回一個(gè)可變的ref對(duì)象useImperativeHandle:將組件中的方法放到外面使用搭配React.forwardRef5.自定義hook類似于高階組件 高階組件返回的一個(gè)類組件,而自定義Hook可以返回任何東西高階組件必須傳遞一個(gè)組件作為參數(shù),而自定義Hook不需要function useFriendStatus(friendID) {const [isOnline, setIsOnline] = useState(null);// 在開發(fā)者工具中的這個(gè) Hook 旁邊顯示標(biāo)簽// e.g. "FriendStatus: Online"useDebugValue(isOnline ? 'Online' : 'Offline');return isOnline;} 可以理解為數(shù)據(jù)的操作都在hook里進(jìn)行,而外部只關(guān)心自己想要的。我只要數(shù)據(jù)列表,獲取產(chǎn)品鉤子(可能并不需要,可通過參數(shù)變更從而觸發(fā)重新獲取數(shù)據(jù))、刪除產(chǎn)品鉤子 為了封裝方法:節(jié)流;

react useState() Hook

1.使用 useState() 進(jìn)行狀態(tài)管理調(diào)用useState() Hook 來啟用函數(shù)組件中的狀態(tài)。useState(initialValue)的第一個(gè)參數(shù)initialValue是狀態(tài)的初始值。[state, setState] = useState(initialValue)返回一個(gè)包含2個(gè)元素的數(shù)組:狀態(tài)值和狀態(tài)更新函數(shù)。使用新值調(diào)用狀態(tài)更新器函數(shù)setState(newState)更新狀態(tài)。或者,可以使用一個(gè)回調(diào)setState(prev => next)來調(diào)用狀態(tài)更新器,該回調(diào)將返回基于先前狀態(tài)的新狀態(tài)。調(diào)用狀態(tài)更新器后,React 確保重新渲染組件,以使新狀態(tài)變?yōu)楫?dāng)前狀態(tài)。 2.多種狀態(tài)通過多次調(diào)用useState(),一個(gè)函數(shù)組件可以擁有多個(gè)狀態(tài)。需要注意的,要確保對(duì)useState()的多次調(diào)用在渲染之間始終保持相同的順序。 3.狀態(tài)的延遲初始化每當(dāng) React 重新渲染組件時(shí),都會(huì)執(zhí)行useState(initialState)。如果初始狀態(tài)是原始值(數(shù)字,布爾值等),則不會(huì)有性能問題。當(dāng)初始狀態(tài)需要昂貴的性能方面的操作時(shí),可以通過為useState(computeInitialState)提供一個(gè)函數(shù)來使用狀態(tài)的延遲初始化,該函數(shù)僅在初始渲染時(shí)執(zhí)行一次,以獲得初始狀態(tài)。在以后的組件渲染中,不會(huì)再調(diào)用該函數(shù),從而跳過昂貴的操作。 4.調(diào)用 useState() 在使用useState() Hook 時(shí),必須遵循 Hook 的規(guī)則: 1.僅頂層調(diào)用Hook:不能在循環(huán),條件,嵌套函數(shù)等中調(diào)用useState()。在多個(gè)useState()調(diào)用中,渲染之間的調(diào)用順序必須相同。 2.僅從React 函數(shù)調(diào)用 Hook:必須僅在函數(shù)組件或自定義鉤子內(nèi)部調(diào)用useState()。

高階組件HOC

1.名詞解釋/作用使函數(shù)復(fù)用,可以通過給組件傳遞方法來復(fù)用高階組件中的函數(shù)方法。高階組件特點(diǎn)高階組件是一個(gè)函數(shù)高階組件接收一個(gè)組件作為參數(shù)進(jìn)行使用,且需要在render函數(shù)中return返回這個(gè)組件高階組件的目的是為了: 復(fù)用組件,將多個(gè)組件都要使用的類似邏輯放在同一個(gè)地方進(jìn)行處理,類似于在Vue中封裝cookie以供重復(fù)使用2.常用高階組件4個(gè)React.memo()connect()provider() withRouter() // 可以使用 3.有自己封裝過嗎 拖拽封裝,給組件里面的標(biāo)簽添加方法就可以實(shí)現(xiàn)拖拽,并返回標(biāo)簽的x與y坐標(biāo)。深對(duì)比,深復(fù)制封裝、正則封裝、頁面路由跳轉(zhuǎn)、路由數(shù)據(jù)接收解析。

拖拽封裝思路

重點(diǎn): 1、一定要絕對(duì)定位,脫離文檔流才可以移動(dòng)。 2、綁定拖拽的元素,移動(dòng)和鼠標(biāo)松開后是對(duì)document的綁定,因?yàn)橐苿?dòng)的是整個(gè)div。 3、點(diǎn)擊:a= 獲取當(dāng)前鼠標(biāo)坐標(biāo)、b =div距瀏覽器距離、c = 鼠標(biāo)在div內(nèi)部距離=a-b。移動(dòng):通過 a - c 建立鼠標(biāo)與div的關(guān)系,防止鼠標(biāo)超出div。拖拽狀態(tài) = 0鼠標(biāo)在元素上按下的時(shí)候{ 拖拽狀態(tài) = 1 記錄下鼠標(biāo)的x和y坐標(biāo) 記錄下元素的x和y坐標(biāo) } 鼠標(biāo)在元素上移動(dòng)的時(shí)候{ 如果拖拽狀態(tài)是0就什么也不做。 如果拖拽狀態(tài)是1,那么 元素y = 現(xiàn)在鼠標(biāo)y - 原來鼠標(biāo)y + 原來元素y 元素x = 現(xiàn)在鼠標(biāo)x - 原來鼠標(biāo)x + 原來元素x } 鼠標(biāo)在任何時(shí)候放開的時(shí)候{ 拖拽狀態(tài) = 0 }

數(shù)據(jù)請(qǐng)求封裝思路

自定義hook封裝過組件嗎

1.將Hello組件和App組件中共用的邏輯放在統(tǒng)一的自定義hook中寫 2.自定義hook,hook名以u(píng)se開頭 3.其他組件通過import引入自定義hook,就可以使用了

react和vue的區(qū)別

相同點(diǎn): 1.都使用了虛擬dom,如果需要改變?nèi)魏卧氐臓顟B(tài),先改虛擬dom,當(dāng)有變化產(chǎn)生時(shí),會(huì)創(chuàng)建新的虛擬dom,通過diff算法對(duì)比新舊虛擬dom的差異,只需要渲染差異部分就行 2.都使用組件化不同點(diǎn): 1.react中有新語法jsx,vue用普通的html 2.vue中父組件和子組件有通信的時(shí)候,父組件數(shù)據(jù)改變引起子組件改變,子組件會(huì)重新渲染,如果父子組件沒有通信,父組件改變子組件不會(huì)渲染,react中不管是否有數(shù)據(jù)通信,父組件改變子組件都會(huì)渲染 3.react:create-react-appvue :vue-cli 4.react中用redux管理狀態(tài),state通過setState更新vue中數(shù)據(jù)由vuex管理

react的class組件,沒有class的時(shí)候怎么寫

React.createClass 我們最早使用這個(gè)方法來構(gòu)建一個(gè)組件“類”,它接受一個(gè)對(duì)象為參數(shù), 對(duì)象中必須聲明一個(gè)render方法,render返回一個(gè)組件實(shí)例

生命周期 鉤子函數(shù)用es5怎么定義

protoType.componentDidMount

虛擬dom和diff算法

虛擬 dom 相當(dāng)于在 js 和真實(shí) dom 中間加了一個(gè)緩存,利用 dom diff 算法 避免了沒有必要的 dom 操作,從而提高性能 具體實(shí)現(xiàn)步驟如下 用 JavaScript 對(duì)象結(jié)構(gòu)表示 DOM 樹的結(jié)構(gòu);然后用這個(gè)樹構(gòu)建一個(gè)真正的 DOM 樹, 插到文檔當(dāng)中 當(dāng)狀態(tài)變更的時(shí)候,重新構(gòu)造一棵新的對(duì)象樹。然后用新的樹和舊的樹進(jìn)行比較,記錄兩 棵樹差異把2所記錄的差異應(yīng)用到步驟1所構(gòu)建的真正的 DOM 樹上,視圖就更新1.虛擬dom是什么所謂的虛擬 dom,也就是虛擬節(jié)點(diǎn)。它通過JS的Object對(duì)象模擬DOM中的節(jié)點(diǎn),然后再通過特定的render方法將其渲染成真實(shí)的DOM節(jié)點(diǎn)用js模擬一顆dom樹,放在瀏覽器內(nèi)存中。當(dāng)你要變更時(shí),虛擬dom使用diff算法進(jìn)行新舊虛擬dom的比較,將變更放到變更隊(duì)列中,反應(yīng)到實(shí)際的dom樹,減少了dom操作。2.虛擬dom的使用基本流程(前四步驟)1.獲取數(shù)據(jù)2.創(chuàng)建虛擬dom3.通過render函數(shù)解析jsx,將其轉(zhuǎn)換成虛擬dom結(jié)構(gòu)4.將虛擬dom渲染成真實(shí)dom5.數(shù)據(jù)更改了6.使用diff算法比對(duì)兩次虛擬dom,生成patch對(duì)象7.根據(jù)key將patch對(duì)象渲染到頁面中改變的結(jié)構(gòu)上,而其他沒有改變的地方是不做任何修改的(虛擬dom的惰性原則)優(yōu)點(diǎn): 保證性能下限: 框架的虛擬 DOM 需要適配任何上層 API 可能產(chǎn)生的操作,它的一些 DOM 操作的實(shí)現(xiàn)必須是普適的,所以它的性能并不是最優(yōu)的;但是比起粗暴的 DOM 操作性能要好很多,因此框架的虛擬 DOM 至少可以保證在你不需要手動(dòng)優(yōu)化的情況下,依然可以提供還不錯(cuò)的性能,即保證性能的下限; 無需手動(dòng)操作 DOM: 我們不再需要手動(dòng)去操作 DOM,只需要寫好 View-Model 的代碼邏輯,框架會(huì)根據(jù)虛擬 DOM 和 數(shù)據(jù)雙向綁定,幫我們以可預(yù)期的方式更新視圖,極大提高我們的開發(fā)效率; 跨平臺(tái): 虛擬 DOM 本質(zhì)上是 JavaScript 對(duì)象,而 DOM 與平臺(tái)強(qiáng)相關(guān),相比之下虛擬 DOM 可以進(jìn)行更方便地跨平臺(tái)操作,例如服務(wù)器渲染、weex 開發(fā)等等。缺點(diǎn): 無法進(jìn)行極致優(yōu)化: 雖然虛擬 DOM + 合理的優(yōu)化,足以應(yīng)對(duì)絕大部分應(yīng)用的性能需求,但在一些性能要求極高的應(yīng)用中虛擬 DOM 無法進(jìn)行針對(duì)性的極致優(yōu)化。首次渲染大量DOM時(shí),由于多了一層虛擬DOM的計(jì)算,會(huì)比innerHTML插入慢。1.diff算法是什么Diff算法是用于比較兩個(gè)新舊虛擬dom樹的差異的,比較完之后會(huì)得到一個(gè)差異對(duì)象,我們稱之為patch補(bǔ)丁對(duì)象比較后會(huì)出現(xiàn)四種情況:1、此節(jié)點(diǎn)是否被移除 -> 添加新的節(jié)點(diǎn)2、屬性是否被改變 -> 舊屬性改為新屬性3、文本內(nèi)容被改變 -> 舊內(nèi)容改為新內(nèi)容4、節(jié)點(diǎn)要被整個(gè)替換 -> 結(jié)構(gòu)完全不相同 移除整個(gè)替換2.diff算法運(yùn)行結(jié)束后,返回是什么返回一個(gè)key

react Native

React Native(內(nèi)特服)能在手機(jī)上創(chuàng)建原生應(yīng)用,React在這方面處于領(lǐng)先位置。使用JavaScript, CSS和HTML創(chuàng)建原生移動(dòng)應(yīng)用,這是一個(gè)重要的革新。Vue社區(qū)與阿里合作開發(fā)Vue版的React Native——Weex也很不錯(cuò),但仍處于開發(fā)狀態(tài)且并沒經(jīng)過實(shí)際項(xiàng)目的驗(yàn)證。既擁有Native的用戶體驗(yàn)、又保留React的開發(fā)效率React Native與React.js的主要區(qū)別還是JSX,它使用XML標(biāo)記的方式去直接聲明界面,將HTML直接嵌入到JavaScript代碼中

react-router(路由)原理

react-router依賴基礎(chǔ) - history history是一個(gè)獨(dú)立的第三方j(luò)s庫,可以用來兼容在不同瀏覽器、不同環(huán)境下對(duì)歷史記錄的管理老瀏覽器的history: 主要通過hash來實(shí)現(xiàn),對(duì)應(yīng)createHashHistory 高版本瀏覽器: 通過html5里面的history,對(duì)應(yīng)createBrowserHistory node環(huán)境下: (不弱惹)主要存儲(chǔ)在歷史記錄memeory里面,對(duì)應(yīng)createMemoryHistory 抽象了一個(gè)公共的文件createHistory:此時(shí)的location跟瀏覽器原生的location是不相同的,最大的區(qū)別就在于里面多了key字段,history內(nèi)部通過key來進(jìn)行l(wèi)ocation的操作原理: 1.執(zhí)行URL前進(jìn)createBrowserHistory: pushState、replaceStatecreateHashHistory: location.hash=*** location.replace()createMemoryHistory: 在內(nèi)存中進(jìn)行歷史記錄的存儲(chǔ) 1.檢測URL回退createBrowserHistory: popstatecreateHashHistory: hashchangecreateMemoryHistory: 因?yàn)槭窃趦?nèi)存中操作,跟瀏覽器沒有關(guān)系,不涉及UI層面的事情,所以可以直接進(jìn)行歷史信息的回退 1.state的存儲(chǔ)為了維護(hù)state的狀態(tài),將其存儲(chǔ)在sessionStorage里面:基本原理:實(shí)現(xiàn)URL與UI可視化界面的同步。其中在react-router中,URL對(duì)應(yīng)Location對(duì)象,而UI是由react components來決定的,這樣就轉(zhuǎn)變成location與components之間的同步問題。在react-router中最主要的component是Router、RouterContext、Link,history庫起到了中間橋梁的作用安裝react-router-dom Link組件用于點(diǎn)擊鏈接跳轉(zhuǎn)其他頁面,沒有路由激活NavLink 用于有路由激活效果的

react-router-dom和react-router的區(qū)別

寫法上的區(qū)別: import {Swtich, Route, Router, HashHistory, Link} from 'react-router-dom';import {Switch, Route, Router} from 'react-router'; import {HashHistory, Link} from 'react-router-dom';react-router-dom: 加入了在瀏覽器運(yùn)行環(huán)境下的一些功能:BrowserRouter和HashRouter組件,前者使用pushState和popState事件構(gòu)建路由,后者使用window.location.hash和hashchange事件構(gòu)建路由。react-router-dom是依賴于react-router的,其中Switch、Route、Router、Redirect等組件是直接引入react-router中的react-router-dom還另外新增了Link、BrowserRouter、HashRouter組件。在引入react-router-dom后不需要顯性引入react-router, react-router-dom依賴react-router,npm都會(huì)將他們安裝。react-router3.x與react-router-dom區(qū)別react-router3.x版本下路由采用集中式配置,UI組件和路由是分開的。react-router4.x版本下路由路由采用分散式配置,路由嵌套在UI組件當(dāng)中,更加契合組件化思想(組件中的路由也應(yīng)該包含在組件之中)。

react路由模式

我們一直在使用的路由方式是BrowserRouter,也就是瀏覽器的路由方式,其實(shí)React還有幾種路由方式:(不弱惹) 1、BrowserRouter:瀏覽器的路由方式,也就是在開發(fā)中最常使用的路由方式 2、HashRouter:在路徑前加入#號(hào)成為一個(gè)哈希值,Hash模式的好處是,再也不會(huì)因?yàn)槲覀兯⑿露也坏轿覀兊膶?duì)應(yīng)路徑 3、MemoryRouter:不存儲(chǔ)history,所有路由過程保存在內(nèi)存里,不能進(jìn)行前進(jìn)后退,因?yàn)榈刂窓跊]有發(fā)生任何變化 4、NativeRouter:經(jīng)常配合ReactNative使用,多用于移動(dòng)端 5、StaticRouter:設(shè)置靜態(tài)路由,需要和后臺(tái)服務(wù)器配合設(shè)置,比如設(shè)置服務(wù)端渲染時(shí)使用(斯大推克)

react路由配置

1、引入路由包npm install --save react-routernpm install --save react-router-domreact-router:是基本的router包,里邊函的內(nèi)容較多,但是在網(wǎng)頁開發(fā)中有很多用不到,現(xiàn)在的市面上的課程講的基本都是這個(gè)包的教程。react-router-dom:隨著react生態(tài)環(huán)境的壯大,后出現(xiàn)的包,這個(gè)包比react-router包輕巧了很多。 2、設(shè)置路由配置文件在src目錄下新建一個(gè)Router/index.js文件用于管理路由,這里需要引入一些對(duì)應(yīng)的組件和路由包文件。Router的history是必需的propsSwitch表示只渲染第一個(gè)與當(dāng)前地址匹配的<Route>Route的props path為路徑,component為路徑對(duì)應(yīng)的頁面exact屬性表示精確匹配,比如我們有多層路由進(jìn)行嵌套時(shí),exact可以幫助我們精確匹配到你想跳轉(zhuǎn)的路由。 exact的值為bool型,為true是表示嚴(yán)格匹配,為false時(shí)為正常匹配3、在入口文件引入路由配置文件import RouterConfig from './router/index.js';ReactDOM.render(<RouterConfig/>, document.getElementById('root'));4、在各組件中使用路由<ul className="menu"><li><NavLink to='/Page1'>第一個(gè)頁面</NavLink></li><li><NavLink to='/Page2'>第二個(gè)頁面</NavLink></li></ul>1.Switch:表示一次只渲染一個(gè)組件 2.Route:路由組件,用于展示一個(gè)組件 同router-view 3.Redirect:重定向(銳得埃克特) 4.lazy + Suspense(色斯盤絲):實(shí)現(xiàn)路由懶加載 5.exact:路徑完全匹配 6.fallback:組件切換時(shí)候的轉(zhuǎn)場組件

react路由(router)實(shí)現(xiàn)異步加載

react-router,官網(wǎng)文檔給出的是用webpack的bundle-loaderrequire.ensure。這是webpack的舊式寫法,現(xiàn)在已不推薦import()符合ECMAScript提議的import()語法,該提案與普通 import 語句或 require 函數(shù)的類似,但返回一個(gè) Promise 對(duì)象。這意味著模塊時(shí)異步加載的

react原理

1. setState setState在合成事件和鉤子函數(shù)中是異步的 在原生事件和setTimeout中是同步的setState的“異步”并不是說內(nèi)部由異步代碼實(shí)現(xiàn),其實(shí)本身執(zhí)行的過程和代碼都是同步的,只是合成事件和鉤子函數(shù)的調(diào)用順序在更新之前,導(dǎo)致在合成事件和鉤子函數(shù)中沒法立馬拿到更新后的值,形式了所謂的“異步”,第一個(gè)參數(shù)可以是對(duì)象或者函數(shù) 是更新state 第二個(gè)參數(shù)獲取最新的state,副作用操作 dom操作事件觸發(fā)聲明 數(shù)據(jù)獲取2. JSX語法的轉(zhuǎn)化JSX 僅僅是 createElement() 方法的語法糖(簡化語法)JSX 語法被 @babel/preset-react 插件編譯為 createElement() 方法react.createElement()React 元素:是一個(gè)對(duì)象,用來描述你希望在屏幕上看到的內(nèi)容3. 組件更新機(jī)制setState() 的兩個(gè)作用: 1. 修改 state 2. 更新組件(UI)過程:父組件重新渲染時(shí),也會(huì)重新渲染子組件。但只會(huì)渲染當(dāng)前組件子樹(當(dāng)前組件及其所有子組件) 4. 組件性能優(yōu)化減輕 state:只存儲(chǔ)跟組件渲染相關(guān)的數(shù)據(jù)避免不必要的重新渲染 : shouldComponentUpdate(nextProps, nextState) 通過返回值決定該組件是否重新渲染,返回 true 表示重新渲染,false 表示不重新渲染 起到優(yōu)化作用5. 純組件 PureComponentPureComponent 內(nèi)部自動(dòng)實(shí)現(xiàn)了 shouldComponentUpdate 鉤子,不需要手動(dòng)比較 純組件內(nèi)部通過分別 對(duì)比 前后兩次 props 和 state 的值,來決定是否重新渲染組件 純組件內(nèi)部的對(duì)比是 shallow compare(淺層對(duì)比)6. 虛擬 DOM 和 Diff 算法數(shù)據(jù)改變視圖更新初次渲染時(shí),React 會(huì)根據(jù)初始state(Model),創(chuàng)建一個(gè)虛擬 DOM 對(duì)象(樹)。根據(jù)虛擬 DOM 生成真正的 DOM,渲染到頁面中。當(dāng)數(shù)據(jù)變化后(setState(),重新根據(jù)新的數(shù)據(jù),創(chuàng)建新的虛擬DOM對(duì)象(樹)。與上一次得到的虛擬 DOM 對(duì)象,使用 Diff 算法 對(duì)比(找不同),生成patch補(bǔ)丁對(duì)象,得到需要更新的內(nèi)容。最終,React 只將變化的內(nèi)容更新(patch)到 DOM 中,重新渲染到頁面。

react的connect高階組件實(shí)現(xiàn), 如何在全局中取得store

連接React組件與 Redux store。 connect:connect函數(shù)的返回值是一個(gè)高階組件,通過高階組件來獲取store中的數(shù)據(jù) connect底層原理:是閉包mapStateFromProps:從countReducer中解構(gòu)出num數(shù)據(jù),用來獲取數(shù)據(jù) mapDispatchFromProps:將ActionCreators中的方法綁定到組件上,并且發(fā)送actionconnect調(diào)用的結(jié)果是返回一個(gè)高階組件 connect方法利用了合并分發(fā)的原理來幫助我們完成store內(nèi)容的獲取合并: 將store中的所有數(shù)據(jù)拿到手 分發(fā): 將我們UI需要的數(shù)據(jù)派發(fā)出去原理 合并分發(fā) :合并的意思是:(我們項(xiàng)目中)redux的數(shù)據(jù)是集中在一處的 分發(fā)的意思是:給的是所有數(shù)據(jù)中的分塊的數(shù)據(jù)

react的connect實(shí)現(xiàn)原理

首先connect之所以會(huì)成功,是因?yàn)镻rovider組件: 在原應(yīng)用組件上包裹一層,使原來整個(gè)應(yīng)用成為Provider的子組件 接收Redux的store作為props,通過context對(duì)象傳遞給子孫組件上的connect那connect做了些什么呢? 它真正連接 Redux 和 React,它包在我們的容器組件的外一層, 它接收上面 Provider 提供的 store 里面的 state 和 dispatch, 傳給一個(gè)構(gòu)造函數(shù),返回一個(gè)對(duì)象,以屬性形式傳給我們的容器組件。關(guān)于它的源碼 connect是一個(gè)高階函數(shù),首先傳入mapStateFromProps、mapDispatchFromProps, 然后返回一個(gè)生產(chǎn)Component的函數(shù)(wrapWithConnect), 然后再將真正的Component作為參數(shù)傳入wrapWithConnect, 這樣就生產(chǎn)出一個(gè)經(jīng)過包裹的Connect組件,該組件具有如下特點(diǎn):通過props.store獲取祖先Component的store props包括stateProps、dispatchProps、parentProps,合并在一起得到nextState,作為props傳給真正的Component componentDidMount時(shí),添加事件this.store.subscribe(this.handleChange),實(shí)現(xiàn)頁面交互 shouldComponentUpdate時(shí)判斷是否有避免進(jìn)行渲染,提升頁面性能,并得到nextState componentWillUnmount時(shí)移除注冊(cè)的事件this.handleChange

react-router3和react-router4 的區(qū)別

一、V3或者說V早期版本是把router 和 layout components 分開在V4中是:集中式 router通過 <Route> 嵌套,實(shí)現(xiàn) Layout 和 page 嵌套Layout 和 page 組件 是作為 router 的一部分 二、在V3中,我們是將整個(gè)龐大的router直接丟給Dom在V4中,除了BrowserRouter,我們丟給DOM的我們的程序本身另外,V4 中,我們不再使用 {props.children} 來嵌套組件了,替代的 <Route>,當(dāng) route 匹配時(shí),子組件會(huì)被渲染到 <Route> 書寫的地方三、在V3 中的 routing 規(guī)則是 exclusive,意思就是最終只獲取一個(gè) route而 V4 中的 routes 默認(rèn)是 inclusive 的,這就意味著多個(gè) <Route>可以同時(shí)匹配和呈現(xiàn)如果只想匹配一個(gè)路由,可以使用Switch,在 <Switch> 中只有一個(gè) <Route> 會(huì)被渲染,同時(shí)可以再在每個(gè)路由添加exact,做到精準(zhǔn)匹配Redirect,瀏覽器重定向,當(dāng)多有都不匹配的時(shí)候,進(jìn)行匹配

react中獲取真實(shí)的dom節(jié)點(diǎn)

使用ref屬性獲取Dom元素后,再使用原生javascript獲取內(nèi)容

react是什么層面上的框架

React框架本身和我們常用的JavaScript MVC框架,如:AngularJS,Backbone,Ember等,沒有直接的可比性。 React的官方博客中明確闡述了React不是一個(gè)MVC框架, 而是一個(gè)用于構(gòu)建組件化UI的庫,是一個(gè)前端界面開發(fā)工具。所以頂多算是MVC中的V(view)。

react數(shù)據(jù)流

React遵循從上到下的數(shù)據(jù)流向,即單向數(shù)據(jù)流。單向數(shù)據(jù)流并非‘單向綁定’,甚至單向數(shù)據(jù)流與綁定沒有‘任何關(guān)系’。 對(duì)于React來說,單向數(shù)據(jù)流(從上到下)與單一數(shù)據(jù)源這兩個(gè)原則,限定了React中要想在一個(gè)組件中更新另一個(gè)組件的狀態(tài)(類似于Vue的平行組件傳參,或者是子組件向父組件傳遞參數(shù)) ,需要進(jìn)行狀態(tài)提升。即將狀態(tài)提升到他們最近的祖先組件中。子組件中Change了狀態(tài),觸發(fā)父組件狀態(tài)的變更,父組件狀態(tài)的變更, 影響到了另一個(gè)組件的顯示(因?yàn)閭鬟f給另一個(gè)組件的狀態(tài)變化了,這一點(diǎn)與Vue子組件的$emit()方法很相似)。

react數(shù)據(jù)一定要在DidMount里獲取更新的原因

componentDidMount方法中的代碼,是在組件已經(jīng)完全掛載到網(wǎng)頁上才會(huì)調(diào)用被執(zhí)行,所以可以保證數(shù)據(jù)的加載。 在這方法中調(diào)用setState方法,會(huì)觸發(fā)重渲染。這個(gè)方法就是用來加載外部數(shù)據(jù)用的,或處理其他的副作用代碼。constructor()constructor()中獲取數(shù)據(jù)的話,如果時(shí)間太長,或者出錯(cuò),組件就渲染不出來,整個(gè)頁面都沒法渲染了。constructor是作組件state初紿化工作,并不是設(shè)計(jì)來作加載數(shù)據(jù)的。componentWillMount()如果使用SSR(服務(wù)端渲染),componentWillMount會(huì)執(zhí)行2次,一次在服務(wù)端,一次在客戶端。而componentDidMount不會(huì)。constructor可以完成state初始化,componentWillMount使用的很少,目前16版本加入了UNSAFE來標(biāo)識(shí) componentWillMount,新的生命周期static getDerivedStateFromProps() 也會(huì)替代這個(gè)。React16之后采用了Fiber架構(gòu),只有componentDidMount聲明周期函數(shù)是確定被執(zhí)行一次的,類似ComponentWillMount的生命周期鉤子都有可能執(zhí)行多次,所以不加以在這些生命周期中做有副作用的操作,比如請(qǐng)求數(shù)據(jù)之類。render()無限r(nóng)endercomponentDidMount()確保已經(jīng)render過一次。提醒我們正確地設(shè)置初始狀態(tài),這樣就不會(huì)得到導(dǎo)致錯(cuò)誤的"undefined"狀態(tài)。

react中的受控組件和非受控組件

受控組件HTML中的表單元素是可輸入的,也就是有自己的可變狀態(tài)而React中可變狀態(tài)通常保存在state中,并且只能通過setState()方法來修改React講state與表單元素值value綁定在一起,有state的值來控制表單元素的值簡單來說,值受到react控制的表單元素非受控組件調(diào)用 React.createRef() 方法創(chuàng)建ref對(duì)象將創(chuàng)建好的 ref 對(duì)象添加到文本框中通過ref對(duì)象獲取到文本框的值簡單來說,表單組件沒有value prop就可以稱為非受控組件

react中的ref的3種方式

方式1: string類型綁定 類似于vue中的ref綁定方式,可以通過this.refs.綁定的ref的名字獲取到節(jié)點(diǎn)dom 注意的是 這種方式已經(jīng)不被最新版的react推薦使用,有可能會(huì)在未來版本中遺棄方式2: react.CreateRef() 通過在class中使用React.createRef()方法創(chuàng)建一些變量,可以將這些變量綁定到標(biāo)簽的ref中 那么該變量的current則指向綁定的標(biāo)簽dom方式3: 函數(shù)形式 在class中聲明函數(shù),在函數(shù)中綁定ref 使用這種方法可以將子組件暴露給父組件以使得父組件能夠調(diào)用子組件的方法 通過函數(shù)的方法綁定ref可以將整個(gè)子組件暴露給父組件當(dāng)在子組件中調(diào)用onRef函數(shù)時(shí),正在調(diào)用從父組件傳遞的函數(shù)。this.props.onRef(this)這里的參數(shù)指向子組件本身,父組件接收該引用作為第一個(gè)參數(shù):onRef = {ref =>(this.child = ref)}然后它使用this.child保存引用。之后,可以在父組件內(nèi)訪問整個(gè)子組件實(shí)例,并且可以調(diào)用子組件函數(shù)。

react中的static(靜態(tài)方法)

靜態(tài)方法和 React 沒有直接關(guān)系,React 的組件都是繼承自 React.Component 這個(gè)類,靜態(tài)方法屬于類本身。static并不是react定義的,而加上static關(guān)鍵字,就表示該方法不會(huì)被實(shí)例繼承,而是直接通過類來調(diào)用。這里涉及到了ES6的class,我們定義一個(gè)組件的時(shí)候通常是定義了一個(gè)類, 而static則是創(chuàng)建了一個(gè)屬于這個(gè)類的屬性或者方法。 組件則是這個(gè)類的一個(gè)實(shí)例,component的props和state是屬于這個(gè)實(shí)例的,

react的props與state的區(qū)別

props: 一般用于父組件向子組件通信,在組件之間通信使用。 state: 一般用于組件內(nèi)部的狀態(tài)維護(hù),更新組建內(nèi)部的數(shù)據(jù),狀態(tài),更新子組件的props等。

混合開發(fā)

1. 混合開發(fā)是介于webapp和原生app之間的一種應(yīng)用,它同時(shí)具有webapp可以跨平臺(tái)的特性,也具備原生app可以進(jìn)行安裝使用的特性 2. webApp 1. 優(yōu)點(diǎn): 跨平臺(tái) 、 維護(hù)更新、項(xiàng)目迭代快2. 缺點(diǎn): 交互體驗(yàn)不好 、進(jìn)入應(yīng)用的方式麻煩 3. 原生app1.案例: 美團(tuán)、餓了嗎、微信、QQ 2.安裝在手機(jī)中使用的 3.優(yōu)點(diǎn): 手機(jī)安裝、交互體驗(yàn)好 4.缺點(diǎn): 維護(hù)更新、項(xiàng)目迭代很慢、成本太高了 4. 混合開發(fā): 擇中方案跨平臺(tái)維護(hù)更新快 成本低手機(jī)安裝,交互體驗(yàn)好為什么混合開發(fā)會(huì)興起呢? 1. 混合開發(fā)的興起是偶然的混合開發(fā)方式 1. h5 主導(dǎo)- 開發(fā)思維: H5【 vue/ react/ angular 】 + 第三方可以訪問原生設(shè)備的庫- 微信公眾號(hào): h5網(wǎng)頁 + 微信JSSDK - 歷史1. PhoneGap + cordva.js 淘汰2. vue/react/angular + ioinc.js 3. vue - uni-app 4. h5 + h5plus.js h5 + h5+5. 微信公眾號(hào): webapp + js-jdk 6. vue/react + weex.js[ 阿里內(nèi)部 ] 2. React Native1. facebook 團(tuán)隊(duì)項(xiàng)目 16 - 18年很熱火,18年后半年開始熱度下降,facebook覺得這個(gè)框架對(duì)于開發(fā)者而言開發(fā)難度太大,維護(hù)成本也高,Facebook決定不再更新它了、2. 典型應(yīng)用: 餓了嗎3. React Native開發(fā)出來項(xiàng)目 - 原生app 4. React Native = React + 原生js5. 構(gòu)建React Native項(xiàng)目 - 腳手架 1. 構(gòu)建項(xiàng)目環(huán)境: create-react-native-app 2. 手機(jī)調(diào)試:expo expo-cli3. 目錄解釋1. __test__ expo手機(jī)調(diào)試的測試文件夾,不用管2. .expo 臨時(shí)文件,運(yùn)行項(xiàng)目3. .expo-shared 分享4. assets 靜態(tài)資源5. components 公共組件6. constants 項(xiàng)目公用的常量7. navigation 底部tabbar欄組件8. node_modules 依賴包9. screens 頁面

小程序

對(duì)于路由的觸發(fā)方式以及頁面生命周期函數(shù)如下:

路由方式觸發(fā)時(shí)機(jī)路由前頁面路由后頁面
初始化小程序打開的第一個(gè)頁面onLoad, onSHow
打開新頁面調(diào)用 API wx.navigateTo 或使用組件 onHideonLoad, onShow
頁面重定向調(diào)用 API wx.redirectTo 或使用組件 onUnloadonLoad, onShow
頁面返回調(diào)用 API wx.navigateBack 或使用組件或用戶按左上角返回按鈕onUnloadonShow
Tab 切換調(diào)用 API wx.navigateBack 或使用組件或用戶按調(diào)用 API wx.switchTab 或使用組件 或用戶切換 Tab各種情況請(qǐng)參考下表
重啟動(dòng)調(diào)用 API wx.reLaunch 或使用組件 onUnloadonLoad, onShow

頁面跳轉(zhuǎn)觸發(fā)的生命周期,其實(shí)還是存在問題的,并非官方所說的那樣。

SwitchTab的跳轉(zhuǎn)BUG 首頁跳轉(zhuǎn)到子頁面后,在子頁面上使用: <navigator type='switchTab' url="/pages/index/index" ><view>跳轉(zhuǎn)首頁</button> </navigator> 這種方式有問題,解決的辦法是通過JS來實(shí)現(xiàn)跳轉(zhuǎn),代碼如下: <view class="weui-btn-area"><button class="weui-btn" bindtap="backIndex" type="default">返回主頁</button> </view> 跳轉(zhuǎn)成功后,重新調(diào)用onload方法,JS代碼如下: backIndex:function(){wx.switchTab({url: '/pages/index/index',success: function (e) {var page = getCurrentPages().pop();if (page == undefined || page == null) return;page.onLoad();}})}

get與post的區(qū)別

1.提交方式 get: get會(huì)將接收到的數(shù)據(jù)拼接到url地址中,以"?"問號(hào)劃分,問號(hào)后面是接收到的數(shù)據(jù),多個(gè)數(shù)據(jù)之間用&連接。用戶可以很直觀的看見。 post: post會(huì)將接收到的數(shù)據(jù)放置在html header中一起發(fā)送到指定的url地址內(nèi)。用戶看不到這個(gè)過程。2.傳遞數(shù)據(jù)大小 get: get傳遞數(shù)據(jù)的大小因?yàn)槭艿綖g覽器地址欄的限制,所以一般在2k-8k,這要據(jù)瀏覽器而定,比如谷歌瀏覽器就是8k。 post: post傳遞數(shù)據(jù)的大小最小是2M,但理論上是無上限的。3.應(yīng)用范圍 get: get一般用于獲取/查詢資源信息.多用于a標(biāo)簽的href屬性中,也常用于location.href屬性中。 post: post一般是用于更新數(shù)據(jù)信息.多用于表單提交。4.安全性 get的安全性比post較差。

react父組件通過ref獲取不到子組件的解決方案

在子組件中 this.customfunction = this.customfunction.bind(this); 即可

React PureComponent 和 Component 區(qū)別

React.PureComponent 與 React.Component 幾乎完全相同,但 React.PureComponent 通過prop和state的淺對(duì)比來實(shí)現(xiàn) shouldComponentUpate()。如果React組件的 render() 函數(shù)在給定相同的props和state下渲染為相同的結(jié)果,在某些場景下你可以使用 React.PureComponent 來提升性能。React.PureComponent 的 shouldComponentUpdate() 只會(huì)對(duì)對(duì)象進(jìn)行淺對(duì)比。如果對(duì)象包含復(fù)雜的數(shù)據(jù)結(jié)構(gòu),它可能會(huì)因深層的數(shù)據(jù)不一致而產(chǎn)生錯(cuò)誤的否定判斷(表現(xiàn)為對(duì)象深層的數(shù)據(jù)已改變視圖卻沒有更新, 原文:false-negatives)。當(dāng)你期望只擁有簡單的props和state時(shí),才去繼承 PureComponent ,或者在你知道深層的數(shù)據(jù)結(jié)構(gòu)已經(jīng)發(fā)生改變時(shí)使用 forceUpate() 。或者,考慮使用 不可變對(duì)象 來促進(jìn)嵌套數(shù)據(jù)的快速比較。此外,React.PureComponent 的 shouldComponentUpate() 會(huì)忽略整個(gè)組件的子級(jí)。請(qǐng)確保所有的子級(jí)組件也是”Pure”的。PureComponent的作用:PureComponent 其實(shí)是在內(nèi)部幫我們簡單實(shí)現(xiàn)了一下shouldComponentUpdate的功能,以便提供組件的性能;這里的簡單指是:對(duì)prop和state做淺比較,若淺比較結(jié)果相同,則該組件以及其子組件不做render;否則,render。使用PureComponent注意事項(xiàng):PureComponent主要針對(duì)prop和state為基本數(shù)據(jù)類型,如bool、string、number;對(duì)于數(shù)組和對(duì)象等引用類型,則要引用不同,才會(huì)渲染;如果引用相同,則PureComponent淺比較返回結(jié)果相同,不做render;PureComponent 中不建議再另外重寫shouldComponentUpdate方法,否則會(huì)報(bào)warning信息:PureComponent的最好作為展示組件,如果prop和state每次都會(huì)變,PureComponent做淺比較也會(huì)影響性能,可以考慮直接用Component;對(duì)于prop和state數(shù)據(jù)結(jié)構(gòu)比較復(fù)雜的情況,可以考慮自己重寫shouldComponentUpdate方法來做優(yōu)化;

react中調(diào)用setState之后發(fā)生

React會(huì)將當(dāng)前傳入的參數(shù)對(duì)象與組件當(dāng)前的狀態(tài)合并,然后觸發(fā)調(diào)和過程,在調(diào)和的過程中,React會(huì)以相對(duì)高效的方式根據(jù)新的狀態(tài)構(gòu)建React元素樹并且重新渲染整個(gè)UI界面.React得到的元素樹之后,React會(huì)自動(dòng)計(jì)算出新的樹與老的樹的節(jié)點(diǎn)的差異,然后根據(jù)差異對(duì)界面進(jìn)行最小化的渲染,在React的差異算法中,React能夠精確的知道在哪些位置發(fā)生看改變以及應(yīng)該如何去改變,這樣就保證了UI是按需更新的而不是重新渲染整個(gè)界面

SPA和MPA的異同

單頁應(yīng)用(SinglePage Application,SPA)指只有一個(gè)主頁面的應(yīng)用,一開始只需加載一次 js,css 等相關(guān)資源。所有的內(nèi)容都包含在主頁面,對(duì)每一個(gè)功能模塊組件化。單頁應(yīng)用跳轉(zhuǎn),就是切換相關(guān)組件,僅刷新局部資源。多頁應(yīng)用(MultiPage Application,MPA)指有多個(gè)獨(dú)立的頁面的應(yīng)用,每個(gè)頁面必須重復(fù)加載 js,css 等相關(guān)資源。多頁應(yīng)用跳轉(zhuǎn),需要整頁資源刷新。兩者對(duì)比表格:SPA ||| MPA 結(jié)構(gòu):一個(gè)主頁面 + 許多模塊的組件 ||| 許多完整的頁面 體驗(yàn):頁面切換快,體驗(yàn)佳;當(dāng)初次加載文件過多時(shí),需要做相關(guān)的調(diào)優(yōu)。 ||| 頁面切換慢,網(wǎng)速慢的時(shí)候,體驗(yàn)尤其不好 資源文件:組件公用的資源只需要加載一次 ||| 每個(gè)頁面都要自己加載公用的資源 適用場景:對(duì)體驗(yàn)度和流暢度有較高要求的應(yīng)用,不利于 SEO(可借助 SSR 優(yōu)化 SEO) ||| 適用于對(duì) SEO 要求較高的應(yīng)用 過渡動(dòng)畫:Vue 提供了 transition 的封裝組件,容易實(shí)現(xiàn) ||| 很難實(shí)現(xiàn) 內(nèi)容更新:相關(guān)組件的切換,即局部更新 ||| 整體 HTML 的切換,費(fèi)錢(重復(fù) HTTP 請(qǐng)求) 路由模式:可以使用 hash ,也可以使用 history ||| 普通鏈接跳轉(zhuǎn) 數(shù)據(jù)傳遞:因?yàn)閱雾撁?#xff0c;使用全局變量就好(Vuex) ||| cookie 、localStorage 等緩存方案,URL 參數(shù),調(diào)用接口保存等 相關(guān)成本:前期開發(fā)成本較高,后期維護(hù)較為容易 ||| 前期開發(fā)成本低,后期維護(hù)就比較麻煩,因?yàn)榭赡芤粋€(gè)功能需要改很多地方單頁應(yīng)用實(shí)現(xiàn)核心:前端路由 前端路由的核心:改變視圖的同時(shí)不會(huì)向后端發(fā)出請(qǐng)求。

TS

TS好處: 1、強(qiáng)類型 2、不需要去瀏覽器中瀏覽效果,就能知道編譯錯(cuò)誤靜態(tài)類型檢查可以做到early fail,即你編寫的代碼即使沒有被執(zhí)行到,一旦你編寫代碼時(shí)發(fā)生類型不匹配,語言在編譯階段(解釋執(zhí)行也一樣,可以在運(yùn)行前)即可發(fā)現(xiàn) 4、類型就是最好的注釋,看類型我們就知道這個(gè)是什么 3、即使ts中有編譯報(bào)錯(cuò),tsc依舊可以將其編譯成js學(xué)習(xí)TS的基本數(shù)據(jù)類型 定類型是為了安全,規(guī)矩多就安全 1、基礎(chǔ)數(shù)據(jù)類型 :number \string\boolean\null\undefinedany 表示任意類型 void 表示空類型,空類型是針對(duì)函數(shù)的,表示函數(shù)沒有返回值。返回空 2、內(nèi)置對(duì)象類型 : Array \ Boolean \ HTMLElement 3、自定義類型 : 接口 類 泛型 枚舉類型

TS 中 interface 和 type 的區(qū)別

在ts中,定義類型由兩種方式:接口(interface)和類型別名(type alias) interface只能定義對(duì)象類型, type聲明的方式可以定義組合類型,交叉類型和原始類型如果用type alias 聲明的方式,會(huì)導(dǎo)致一些功能的缺失1.interface方式可以實(shí)現(xiàn)接口的extends/implements,而type 不行2.interface可以實(shí)現(xiàn)接口的merge,但是type不行

Webpack

webpack打包react vue,與自己的源代碼分離使用splitchunks webpack熱更新:不用刷新瀏覽器而將新變更的模塊替換掉舊的模塊。webpack會(huì)分析每個(gè)入口文件,解析包依賴關(guān)系的各個(gè)文件,每個(gè)模塊都打包到bundle.js。webpack給每個(gè)模塊分配一個(gè)唯一的ID并通過這個(gè)ID索引和訪問模塊。頁面運(yùn)行時(shí),先啟動(dòng)entry.js,其他模塊會(huì)在運(yùn)行require時(shí)候執(zhí)行。1.Webpack Loader Plugin(loader ,plugin分別什么作用,哪個(gè)配置可以把依賴包抽離出來,不打包進(jìn)去) 【Loader】:用于對(duì)模塊源碼的轉(zhuǎn)換,loader描述了webpack如何處理非javascript模塊,并且在buld中引入這些依賴。loader可以將文件從不同的語言(如TypeScript)轉(zhuǎn)換為JavaScript,或者將內(nèi)聯(lián)圖像轉(zhuǎn)換為data URL。比如說:CSS-Loader,Style-Loader等。babel-loader優(yōu)雅降級(jí)配置ES高版本轉(zhuǎn)成低版本【Plugin】:是用于在webpack打包編譯過程里,在對(duì)應(yīng)的事件節(jié)點(diǎn)里執(zhí)行自定義操作,比如資源管理、bundle文件優(yōu)化等操作,依賴包抽離 const ExtractTextWebapckPlugin= require("extract-text-webpack-plugin") module exclude node_modules排除excloude排除node_modulesloader的使用很簡單:在webpack.config.js中指定loader。module.rules可以指定多個(gè)loader,對(duì)項(xiàng)目中的各個(gè)loader有個(gè)全局概覽。loader是運(yùn)行在NodeJS中,可以用options對(duì)象進(jìn)行配置。plugin可以為loader帶來更多特性。loader可以進(jìn)行壓縮,打包,語言翻譯等等。loader從模板路徑解析,npm install node_modules。也可以自定義loader,命名XXX-loader。語言類的處理器loader:CoffeeScript,TypeScript,ESNext(Bable),Sass,Less,Stylus。任何開發(fā)技術(shù)棧都可以使用webpack。webpack常用的loader樣式:style-loader、css-loader、less-loader、sass-loader等 文件:raw-loader、file-loader 、url-loader等 編譯:babel-loader、coffee-loader 、ts-loader等 校驗(yàn)測試:mocha-loader、jshint-loader 、eslint-loader等目的在于解決loader無法實(shí)現(xiàn)的其他事,從打包優(yōu)化和壓縮,到重新定義環(huán)境變量,功能強(qiáng)大到可以用來處理各種各樣的任務(wù)。webpack提供了很多開箱即用的插件:CommonChunkPlugin主要用于提取第三方庫和公共模塊,避免首屏加載的bundle文件,或者按需加載的bundle文件體積過大,導(dǎo)致加載時(shí)間過長,是一把優(yōu)化的利器。而在多頁面應(yīng)用中,更是能夠?yàn)槊總€(gè)頁面間的應(yīng)用程序共享代碼創(chuàng)建bundle。webpack功能強(qiáng)大,難點(diǎn)在于它的配置文件,webpack4默認(rèn)不需要配置文件,可以通過mode選項(xiàng)為webpack指定了一些默認(rèn)的配置,mode分為:development/production,默認(rèn)是production。插件可以攜帶參數(shù),所以在plugins屬性傳入new實(shí)例。webpack常用的plugin webpack內(nèi)置UglifyJsPlugin,壓縮和混淆代碼。 webpack內(nèi)置CommonsChunkPlugin,提高打包效率,將第三方庫和業(yè)務(wù)代碼分開打包。 ProvidePlugin:自動(dòng)加載模塊,代替require和importhtml-webpack-plugin可以根據(jù)模板自動(dòng)生成html代碼,并自動(dòng)引用css和js文件extract-text-webpack-plugin 將js文件中引用的樣式單獨(dú)抽離成css文件DefinePlugin 編譯時(shí)配置全局變量,這對(duì)開發(fā)模式和發(fā)布模式的構(gòu)建允許不同的行為非常有用。【Mode】可以在config文件里面配置,也可以在CLI參數(shù)中配置:webpack--mode=production(一般會(huì)選擇在CLI,也就是npm scripts里面進(jìn)行配置)。在webpack4以下版本,webpack3.XX,通過plugins進(jìn)行環(huán)境變量的配置。【resolve】模塊,resolver是個(gè)庫,幫助webpack找到bundle需要引入的模塊代碼,打包時(shí),webpack使用enhanced-resolve來解析路徑。 2.webpack優(yōu)化 多進(jìn)程打包 安裝插件thread-loader parallel-webpack HappyPack多進(jìn)程壓縮 parallel-uglify-plugin terser-webpack-plugin 資源CDN 公用代碼提取,使用 CDN 加載 動(dòng)態(tài)polyfill 動(dòng)態(tài) polyfill 指的是根據(jù)不同的瀏覽器,動(dòng)態(tài)載入需要的 polyfill

flex布局

flex是由 flex-grow:1父容器在主軸上還有多少剩余空間,flex-shrink當(dāng)父元素的寬度大于所有子元素的寬度的和時(shí)(即父元素會(huì)有剩余空間), 子元素如何分配父元素的剩余空間flex-basis基準(zhǔn)值組成flex 怎么實(shí)現(xiàn)1個(gè)盒子垂直居中 如何實(shí)現(xiàn)四個(gè)盒子水平均勻分布父容器 display:flex; justify-content: center; align-items: center;display: flex; justify-content:space-evenly; align-items: center;

實(shí)現(xiàn)導(dǎo)航的吸頂效果

設(shè)置css:fixed固定定位 判斷滾動(dòng)條滾動(dòng)的距離大于導(dǎo)航條距頂部的距離,來判斷是否實(shí)現(xiàn)吸頂,然后addClass添加樣式

less的hover簡寫

a{&:hover {} //這里&代表它的上一級(jí)就是a }

CSS偽類 ::after,before的應(yīng)用場景

::before和::after必須配合content屬性來使用, content用來定義插入的內(nèi)容,content必須有值,至少是空。 默認(rèn)情況下,偽類元素的display是默認(rèn)值inline,可以通過設(shè)置display:block來改變其顯示。1.清除浮動(dòng): 在浮動(dòng)元素后面添加一個(gè)空的Div標(biāo)簽,然后在設(shè)置它的清除浮動(dòng)要是,使用after偽元素2.常見消息框 : 偽類content:' ' 偽類4條邊必須寬度相同,而且其他三條邊為transparent 可以通過設(shè)置定位元素left,top值為50%,translate(-50%,-50%) 來使任意寬高的元素居中。div::before{content:' ';3.陰影 : 通過設(shè)置before,after不同位置,不同旋轉(zhuǎn)角度,要保證偽類的顏色及z-indexdiv.outer::before,div.outer::after{content:'';z-index:1;width:50%;height:3px;position:absolute;left:10px;bottom:7px;background-color:transparent;box-shadow:5px 5px 10px rgba(0,0,0,0.5);-webkit-transform:rotate(-3deg);4.做出各種圖形效果#star-five:before {border-bottom: 80px solid red;border-left: 30px solid transparent;border-right: 30px solid transparent;position: absolute;height: 0;width: 0;top: -45px;left: -65px;content: '';transform: rotate(-35deg);}#star-five:after {width: 0;height: 0;border-left: 100px solid transparent;border-right: 100px solid transparent;border-bottom: 70px solid yellow;top: 7px;left: -110px;position: absolute;display: block;content: '';transform: rotate(-70deg);}

CSS權(quán)重的計(jì)算

權(quán)重疊加 0,0,0,5 + 0,0,0,5 =0,0,0,10 而不是 0,0,1,0,所以不會(huì)存在10個(gè)div能趕上一個(gè)類選擇器的情況繼承的權(quán)重是0 1)如果選中了,那么以上面的公式來計(jì)權(quán)重。誰大聽誰的。 2)如果沒有選中,那么權(quán)重是0,因?yàn)槔^承的權(quán)重為0當(dāng)選擇器沖突時(shí),權(quán)重高的生效;當(dāng)權(quán)重相同時(shí),寫在后頭的會(huì)把前面的覆蓋。

http

http2.0,https連接,http概述:超文本傳輸協(xié)議,是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議http的缺點(diǎn) 1.通信使用明文可能會(huì)被竊聽。 2.不驗(yàn)證通信方的身份可能遭遇偽裝。 3.無法證明報(bào)文的完整性,可能已遭篡改。https就是在安全的傳輸層上發(fā)送的http。它在將http報(bào)文發(fā)送給TCP之前,先將其發(fā)送給了一個(gè)安全層 ,對(duì)其進(jìn)行加密。http安全層是通過ssl及其現(xiàn)代替代協(xié)議TSL來實(shí)現(xiàn)的。https的優(yōu)點(diǎn) (1)使用HTTPS協(xié)議可認(rèn)證用戶和服務(wù)器,確保數(shù)據(jù)發(fā)送到正確的客戶機(jī)和服務(wù)器; (2)HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,要比http協(xié)議安全,可防止數(shù)據(jù)在傳輸過程中不被竊取、改變,確保數(shù)據(jù)的完整性。https的缺點(diǎn) 但是https因?yàn)榧恿藢觭sl,所以在效率方面比較低,會(huì)使頁面加載的時(shí)長延長近50%,也會(huì)增加10-20%的耗電。 需要安裝證書,在一定基礎(chǔ)上增加部署費(fèi)用,并且報(bào)文加密解密對(duì)數(shù)據(jù)傳遞有一點(diǎn)的效率影響。http/2.0的目標(biāo)是改善用戶加載頁面的時(shí)候更快 HTTP/2采用二進(jìn)制格式而非文本格式 HTTP/2是完全多路復(fù)用的,而非有序并阻塞的——只需一個(gè)連接即可實(shí)現(xiàn)并行

http對(duì)稱加密非對(duì)稱加密

對(duì)稱密鑰加密是指加密和解密使用同一個(gè)密鑰的方式,一方通過密鑰將信息加密后,把密文傳給另一方,另一方通過這個(gè)相同的密鑰將密文解密,轉(zhuǎn)換成可以理解的明文非對(duì)稱加密是加密和解密使用的是兩個(gè)不同的密鑰,所以這種算法叫作非對(duì)稱加密算法。指使用一對(duì)非對(duì)稱密鑰,即公鑰和私鑰,公鑰可以隨意發(fā)布,但私鑰只有自己知道。發(fā)送密文的一方使用對(duì)方的公鑰進(jìn)行加密處理,對(duì)方接收到加密信息后,使用自己的私鑰進(jìn)行解密。

WebSocket和http有什么區(qū)別

socket是傳輸控制層協(xié)議,webSocket是應(yīng)用層協(xié)議WebSocket protocol 是HTML5一種新的協(xié)議。它實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工通信(full-duplex)。 一開始的握手需要借助HTTP請(qǐng)求完成。HTTP請(qǐng)求缺點(diǎn): 會(huì)導(dǎo)致過多不必要的請(qǐng)求,浪費(fèi)流量和服務(wù)器資源,每一次請(qǐng)求、應(yīng)答,都浪費(fèi)了一定流量在相同的頭部信息上然而WebSocket的出現(xiàn)可以彌補(bǔ)這一缺點(diǎn)。 在WebSocket中,只需要服務(wù)器和瀏覽器通過HTTP協(xié)議進(jìn)行一個(gè)握 手的動(dòng)作,然后單獨(dú)建立一條TCP的通信通道進(jìn)行數(shù)據(jù)的傳送。原理:(webSocket) WebSocket同HTTP一樣也是應(yīng)用層的協(xié)議,但是它是一種雙向通信協(xié)議,是建立在TCP之上的。1. 瀏覽器、服務(wù)器建立TCP連接,三次握手。這是通信的基礎(chǔ),傳輸控制層,若失敗后續(xù)都不執(zhí)行。 2. TCP連接成功后,瀏覽器通過HTTP協(xié)議向服務(wù)器傳送WebSocket支持的版本號(hào)等信息。(開始前的HTTP握手) 3. 服務(wù)器收到客戶端的握手請(qǐng)求后,同樣采用HTTP協(xié)議回饋數(shù)據(jù)。 4. 當(dāng)收到了連接成功的消息后,通過TCP通道進(jìn)行傳輸通信。WebSocket與HTTP的關(guān)系 相同點(diǎn): 都是一樣基于TCP的,都是可靠性傳輸協(xié)議。 都是應(yīng)用層協(xié)議不同點(diǎn): WebSocket是雙向通信協(xié)議,模擬Socket協(xié)議,可以雙向發(fā)送或接受信息。HTTP是單向的。 WebSocket是需要握手進(jìn)行建立連接的。

錯(cuò)誤調(diào)試工具

F12 斷點(diǎn) 錯(cuò)誤附近輸出打印 火狐中的firebug IE開發(fā)者工具 Emmet

http狀態(tài)碼

200 OK 請(qǐng)求成功。一般用于GET與POST請(qǐng)求 3開頭 重定向 300 多種選擇。請(qǐng)求的資源可包括多個(gè)位置,相應(yīng)可返回一個(gè)資源特征與地址的列表用于用戶終端(例如:瀏覽器)選擇 301 永久移動(dòng)。請(qǐng)求的資源已被永久的移動(dòng)到新URI,返回信息會(huì)包括新的URI,瀏覽器會(huì)自動(dòng)定向到新URI。今后任何新的請(qǐng)求都應(yīng)使用新的URI代替 302 臨時(shí)移動(dòng)。與301類似。但資源只是臨時(shí)被移動(dòng)。客戶端應(yīng)繼續(xù)使用原有URI 303 查看其它地址。與301類似。使用GET和POST請(qǐng)求查看 304 未修改。所請(qǐng)求的資源未修改,服務(wù)器返回此狀態(tài)碼時(shí),不會(huì)返回任何資源。客戶端通常會(huì)緩存訪問過的資源,通過提供一個(gè)頭信息指出客戶端希望只返回在指定日期之后修改的資源 305 使用代理。所請(qǐng)求的資源必須通過代理訪問 306 已經(jīng)被廢棄的HTTP狀態(tài)碼 307 臨時(shí)重定向。與302類似。使用GET請(qǐng)求重定向 400 客戶端請(qǐng)求的語法錯(cuò)誤,服務(wù)器無法理解 401 請(qǐng)求要求用戶的身份認(rèn)證 402 保留,將來使用 403 服務(wù)器理解請(qǐng)求客戶端的請(qǐng)求,但是拒絕執(zhí)行此請(qǐng)求 404 服務(wù)器無法根據(jù)客戶端的請(qǐng)求找到資源(網(wǎng)頁)。通過此代碼,網(wǎng)站設(shè)計(jì)人員可設(shè)置"您所請(qǐng)求的資源無法找到"的個(gè)性頁面 405 客戶端請(qǐng)求中的方法被禁止 406 N服務(wù)器無法根據(jù)客戶端請(qǐng)求的內(nèi)容特性完成請(qǐng)求 407 請(qǐng)求要求代理的身份認(rèn)證,與401類似,但請(qǐng)求者應(yīng)當(dāng)使用代理進(jìn)行授權(quán) 408 服務(wù)器等待客戶端發(fā)送的請(qǐng)求時(shí)間過長,超時(shí) 409 服務(wù)器完成客戶端的 PUT 請(qǐng)求時(shí)可能返回此代碼,服務(wù)器處理請(qǐng)求時(shí)發(fā)生了沖突 410 客戶端請(qǐng)求的資源已經(jīng)不存在。410不同于404,如果資源以前有現(xiàn)在被永久刪除了可使用410代碼,網(wǎng)站設(shè)計(jì)人員可通過301代碼指定資源的新位置 411 服務(wù)器無法處理客戶端發(fā)送的不帶Content-Length的請(qǐng)求信息 412 客戶端請(qǐng)求信息的先決條件錯(cuò)誤 413 由于請(qǐng)求的實(shí)體過大,服務(wù)器無法處理,因此拒絕請(qǐng)求。為防止客戶端的連續(xù)請(qǐng)求,服務(wù)器可能會(huì)關(guān)閉連接。如果只是服務(wù)器暫時(shí)無法處理,則會(huì)包含一個(gè)Retry-After的響應(yīng)信息 414 請(qǐng)求的URI過長(URI通常為網(wǎng)址),服務(wù)器無法處理 415 服務(wù)器無法處理請(qǐng)求附帶的媒體格式 416 客戶端請(qǐng)求的范圍無效 417 服務(wù)器無法滿足Expect的請(qǐng)求頭信息 500 服務(wù)器內(nèi)部錯(cuò)誤,無法完成請(qǐng)求 501 服務(wù)器不支持請(qǐng)求的功能,無法完成請(qǐng)求 502 作為網(wǎng)關(guān)或者代理工作的服務(wù)器嘗試執(zhí)行請(qǐng)求時(shí),從遠(yuǎn)程服務(wù)器接收到了一個(gè)無效的響應(yīng) 503 由于超載或系統(tǒng)維護(hù),服務(wù)器暫時(shí)的無法處理客戶端的請(qǐng)求。延時(shí)的長度可包含在服務(wù)器的Retry-After頭信息中 504 充當(dāng)網(wǎng)關(guān)或代理的服務(wù)器,未及時(shí)從遠(yuǎn)端服務(wù)器獲取請(qǐng)求 505 服務(wù)器不支持請(qǐng)求的HTTP協(xié)議的版本,無法完成處理

HTTP和HTTPS的區(qū)別

HTTP是超文本傳輸協(xié)議,信息是明文傳輸?shù)?#xff0c;HTTPS是具有ssl/tls加密傳輸協(xié)議。默認(rèn)端口不同,前者是80,后者是443。HTTPS比HTTP安全HTTPS協(xié)議需要到CA申請(qǐng)證書,需要一定費(fèi)用

瀏覽器的緩存機(jī)制

什么是瀏覽器緩存 Web緩存是指一個(gè)Web資源(如html頁面,圖片,js,數(shù)據(jù)等)存在于Web服務(wù)器和客戶端(瀏覽器)之間的副本。緩存會(huì)根據(jù)進(jìn)來的請(qǐng)求保存輸出內(nèi)容的副本;當(dāng)下一個(gè)請(qǐng)求來到的時(shí)候,如果是相同的URL,緩存會(huì)根據(jù)緩存機(jī)制決定是直接使用副本響應(yīng)訪問請(qǐng)求,還是向源服務(wù)器再次發(fā)送請(qǐng)求。比較常見的就是瀏覽器會(huì)緩存訪問過網(wǎng)站的網(wǎng)頁,當(dāng)再次訪問這個(gè)URL地址的時(shí)候,如果網(wǎng)頁沒有更新,就不會(huì)再次下載網(wǎng)頁,而是直接使用本地緩存的網(wǎng)頁。只有當(dāng)網(wǎng)站明確標(biāo)識(shí)資源已經(jīng)更新,瀏覽器才會(huì)再次下載網(wǎng)頁。瀏覽器和網(wǎng)站服務(wù)器是根據(jù)緩存機(jī)制進(jìn)行緩存的非HTTP協(xié)議定義的緩存機(jī)制瀏覽器緩存機(jī)制,其實(shí)主要就是HTTP協(xié)議定義的緩存機(jī)制(如: Expires; Cache-control等)。但是也有非HTTP協(xié)議定義的緩存機(jī)制,如使用HTML Meta 標(biāo)簽,Web開發(fā)者可以在HTML頁面的<head>節(jié)點(diǎn)中加入<meta>標(biāo)簽<meta http-equiv="Pragma" content="no-cache">上述代碼的作用是告訴瀏覽器當(dāng)前頁面不被緩存,每次訪問都需要去服務(wù)器拉取。使用上很簡單,但只有部分瀏覽器可以支持,而且所有緩存代理服務(wù)器都不支持,因?yàn)榇聿唤馕鯤TML內(nèi)容本身。瀏覽器在第一次請(qǐng)求發(fā)生后,再次請(qǐng)求時(shí):瀏覽器會(huì)先獲取該資源緩存的header信息,根據(jù)其中的expires和cache-control判斷是否命中強(qiáng)緩存),若命中則直接從緩存中獲取資源,包括緩存的header信息,本次請(qǐng)求不會(huì)與服務(wù)器進(jìn)行通信; 如果沒有命中強(qiáng)緩存,瀏覽器會(huì)發(fā)送請(qǐng)求到服務(wù)器,該請(qǐng)求會(huì)攜帶第一次請(qǐng)求返回的有關(guān)緩存的header字段信息(Last-Modified/IF-Modified-Since、Etag/IF-None-Match),由服務(wù)器根據(jù)請(qǐng)求中的相關(guān)header信息來對(duì)比結(jié)果是否命中協(xié)商緩存,若命中,則服務(wù)器返回新的響應(yīng)header信息更新緩存中的對(duì)應(yīng)header信息,但是并不返回資源內(nèi)容,它會(huì)告知瀏覽器可以直接從緩存獲取;否則返回最新的資源內(nèi)容

瀏覽器的強(qiáng)緩存和協(xié)商緩存

這里說的緩存是指瀏覽器(客戶端)在本地磁盤中對(duì)訪問過的資源保存的副本文件。瀏覽器緩存主要有以下幾個(gè)優(yōu)點(diǎn): 1. 減少重復(fù)數(shù)據(jù)請(qǐng)求,避免通過網(wǎng)絡(luò)再次加載資源,節(jié)省流量。 2. 降低服務(wù)器的壓力,提升網(wǎng)站性能。 3. 加快客戶端加載網(wǎng)頁的速度,提升用戶體驗(yàn)。瀏覽器緩存分為強(qiáng)緩存和協(xié)商緩存,兩者有兩個(gè)比較明顯的區(qū)別: 1. 如果瀏覽器命中強(qiáng)緩存,則不需要給服務(wù)器發(fā)請(qǐng)求;而協(xié)商緩存最終由服務(wù)器來決定是否使用緩存,即客戶端與服務(wù)器之間存在一次通信。 2. 在chrome中強(qiáng)緩存(雖然沒有發(fā)出真實(shí)的http請(qǐng)求)的請(qǐng)求狀態(tài)碼返回是200(from cache);而協(xié)商緩存如果命中走緩存的話,請(qǐng)求的狀態(tài)碼是304(not modified)。不同瀏覽器的策略不同,在Fire Fox中,from cache狀態(tài)碼是304.強(qiáng)緩存 強(qiáng)緩存是利用http的返回頭中的Expires或者Cache-Control兩個(gè)字段來控制的,用來表示資源的緩存時(shí)間。 Expires:該字段是http1.0時(shí)的規(guī)范,它的值為一個(gè)絕對(duì)時(shí)間的GMT格式的時(shí)間字符串,比如Expires:Mon,18 Oct 2066 23:59:59 GMT。這個(gè)時(shí)間代表著這個(gè)資源的失效時(shí)間,在此時(shí)間之前,即命中緩存。這種方式有一個(gè)明顯的缺點(diǎn),由于失效時(shí)間是一個(gè)絕對(duì)時(shí)間,所以當(dāng)服務(wù)器與客戶端時(shí)間偏差較大時(shí),就會(huì)導(dǎo)致緩存混亂。 Cache-Control:Cache-Control是http1.1時(shí)出現(xiàn)的header信息,主要是利用該字段的max-age值來進(jìn)行判斷,它是一個(gè)相對(duì)時(shí)間,例如Cache-Control:max-age=3600,代表著資源的有效期是3600秒。cache-control除了該字段外,還有下面幾個(gè)比較常用的設(shè)置值:no-cache:不使用本地緩存。需要使用緩存協(xié)商,先與服務(wù)器確認(rèn)返回的響應(yīng)是否被更改,如果之前的響應(yīng)中存ETag,那么請(qǐng)求的時(shí)候會(huì)與服務(wù)端驗(yàn)證,如果資源未被更改,則可以避免重新下載。 no-store:直接禁止游覽器緩存數(shù)據(jù),每次用戶請(qǐng)求該資源,都會(huì)向服務(wù)器發(fā)送一個(gè)請(qǐng)求,每次都會(huì)下載完整的資源。 public:可以被所有的用戶緩存,包括終端用戶和CDN等中間代理服務(wù)器。 private:只能被終端用戶的瀏覽器緩存,不允許CDN等中繼緩存服務(wù)器對(duì)其緩存。Cache-Control與Expires可以在服務(wù)端配置同時(shí)啟用,同時(shí)啟用的時(shí)候Cache-Control優(yōu)先級(jí)高。為什么要有Etag HTTP1.1中Etag的出現(xiàn)主要是為了解決幾個(gè)Last-Modified比較難解決的問題:1.一些文件也許會(huì)周期性的更改,但是他的內(nèi)容并不改變(僅僅改變的修改時(shí)間)這個(gè)時(shí)候我們并不希望客戶端認(rèn)為這個(gè)文件被修改了,而重新GET 2.某些文件修改非常頻繁,比如在秒以下的時(shí)間內(nèi)進(jìn)行修改,(比方說1s內(nèi)修改了N次),If-Modified-Since能檢查到的粒度是s級(jí)的,這種修改無法判斷(或者說UNIX記錄MTIME只能精確到秒); 3.某些服務(wù)器不能精確的得到文件的最后修改時(shí)間。Last-Modified與ETag是可以一起使用的,服務(wù)器會(huì)優(yōu)先驗(yàn)證ETag,一致的情況下,才會(huì)繼續(xù)比對(duì)Last-Modified,最后才決定是否返回304。200 OK(from cache)與304 Not Modified的區(qū)別200 OK( from cache )不向服務(wù)器發(fā)送請(qǐng)求,直接使用本地緩存文件。304 Not Modified則向服務(wù)器詢問,若服務(wù)器認(rèn)為瀏覽器的緩存版本還可用,那么便會(huì)返回304。緩存類型 獲取資源形式 狀態(tài)碼 發(fā)送請(qǐng)求到服務(wù)器 強(qiáng)緩存 從緩存取 200(from cache) 否,直接從緩存取 協(xié)商緩存 從緩存取 304(Not Modified) 否,通過服務(wù)器來告知緩存是否可用用戶行為對(duì)緩存的影響 用戶操作 Expires/Cache-Control Last-Modied/Etag 地址欄回車 有效 有效 頁面鏈接跳轉(zhuǎn) 有效 有效 新開窗口 有效 有效 前進(jìn)回退 有效 有效 F5刷新 無效 有效 Ctrl+F5強(qiáng)制刷新 無效 無效

不能被緩存的請(qǐng)求

1. HTTP信息頭中包含Cache-Control:no-cache,pragma:no-cache(HTTP1.0),或Cache-Control:max-age=0等告訴瀏覽器不用緩存的請(qǐng)求 2. 需要根據(jù)Cookie,認(rèn)證信息等決定輸入內(nèi)容的動(dòng)態(tài)請(qǐng)求是不能被緩存的 3. 經(jīng)過HTTPS安全加密的請(qǐng)求 4. POST請(qǐng)求無法被緩存 5. HTTP響應(yīng)頭中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的請(qǐng)求無法被緩存

用戶行為對(duì)緩存的影響

qq、fire fox 、safari 、chrome 這幾個(gè)瀏覽器的訪問同一個(gè)頁面,不同的瀏覽器在 F5 刷新的時(shí)候 ,同一個(gè)文件 qq 、fire fox 瀏覽器會(huì)返回 `304 Not Nodified`,在請(qǐng)求頭中不攜帶 `Expires/Cache-Control`; 而 chrome 和 safari 刷新的時(shí)候,會(huì)返回 `200 from cache`, 沒有真正發(fā)起請(qǐng)求,走強(qiáng)緩存。可見不同的瀏覽器反饋是不一致的,所以下面表格中"F5刷新"時(shí) `Expires/Cache-Control` 會(huì)無效我認(rèn)為是存在一定爭議的。而 Ctrl + F5 強(qiáng)制刷新的時(shí)候,會(huì)暫時(shí)禁用強(qiáng)緩存和協(xié)商緩存。

eslint規(guī)則

Eslint 是一個(gè)JavaScript驗(yàn)證工具,有了它可以讓你的編輯器像ide一樣進(jìn)行一些靜態(tài)的錯(cuò)誤提示功能.npm install eslint -g某些文件關(guān)閉eslint檢測 在文件的最頂端加上注釋 /*eslint-disable*/關(guān)閉某一行代碼的eslint檢查 // eslint-disable-next-line.eslintrc.json配置rules選項(xiàng)

git

(版本回退是什么命令,哪個(gè)命令查看已刪除的提交commitId)git-reset 版本回退git reset --hard xxx 回到上一個(gè)版本git reset --soft xxx 該命令將最近一次提交節(jié)點(diǎn)的提交記錄回退到暫存區(qū)git reset --mixed xxx 是將最近一次提交節(jié)點(diǎn)記錄回退到工作區(qū)git log 與 git reflog 查看歷史記錄(被刪除的歷史commit ID)git場景問題 提交暫存區(qū)git add 出錯(cuò) git reset HEAD <文件名> 回退提交本地倉庫 git commit出錯(cuò): 1.更改 commit 信息:git commit --amend -m“新提交消息” 2.漏提交:git add missed-file // missed-file 為遺漏提交文件git commit --amend --no-edit //--no-edit提交消息不會(huì)更改 3.git reset --hard commit_id git log查看提交的版本git revert 是提交一個(gè)新的版本 git fetch 將遠(yuǎn)程主機(jī)的更新全部放到本地中g(shù)it revert 和 git reset 的區(qū)別:(1)git revert是用一次新的commit來回滾之前的commit,git reset是直接刪除指定的commit。 (2)git revert是用一次逆向的commit“中和”之前的提交 ,合并的時(shí)候回滾的變化不會(huì)出現(xiàn)git reset是之間把某些commit在某個(gè)branch上刪除,合并時(shí)候回滾的commit會(huì)被引入

node.js

1.Node不是一個(gè)后端語言,但是它可以做類似后端語言的功能 2.Node是使用谷歌V8引擎 3.Node是js的一個(gè)運(yùn)行環(huán)境 4.Node具有非阻塞I/O 特點(diǎn) 5.Node采用了Common.js規(guī)范 node+koa2 node+express用于快速構(gòu)建Node.js項(xiàng)目node.js 是一個(gè)基于 Chrome V8 引擎的 JavaScirpt 運(yùn)行環(huán)境。Node.js使用了一個(gè)事件驅(qū)動(dòng)、非阻塞式I/O的模型,使其輕量又高效**Node.js基于commonjs規(guī)范事件驅(qū)動(dòng): 任務(wù)執(zhí)行,發(fā)布者,訂閱者,事件驅(qū)動(dòng) . 異步(非阻塞): 執(zhí)行某一個(gè)任務(wù)的同時(shí)也可以執(zhí)行其他任務(wù) 同步(阻塞): 執(zhí)行某一個(gè)任務(wù),這個(gè)任務(wù)如果沒有執(zhí)行完成,其他任務(wù)必須等待 I/O: 輸入/輸出( 數(shù)據(jù)庫操作,文件系統(tǒng)操作等 ) - 服務(wù)器的環(huán)境 非阻塞I/O模型: 當(dāng)使用Node.js來實(shí)現(xiàn)數(shù)據(jù)庫操作、文件系統(tǒng)等操作時(shí),要進(jìn)行的異步操作,異步操作的核心傳統(tǒng)實(shí)現(xiàn)方式就是回調(diào)函數(shù)和事件。Node.js的包管理工具npm優(yōu)點(diǎn):Node.js 使用了一個(gè)事件驅(qū)動(dòng)、非阻塞式 I/O 的模型,異步編程,使其輕量又高效。 缺點(diǎn):單進(jìn)程,單線程,只支持單核cpu,不能充分的利用多核cpu服務(wù)器。一旦這個(gè)進(jìn)程崩掉,那么整個(gè)web服務(wù)就崩掉了。內(nèi)置模塊 http 是用于創(chuàng)建一個(gè)能夠處理和響應(yīng) http 響應(yīng)的服務(wù)fs 用于對(duì)系統(tǒng)文件及目錄進(jìn)行讀寫操作。 path 提供了一些用于處理文件路徑的小工具 Url:幫助我們對(duì)提交上來的url進(jìn)行解析處理 querystring 提供用于解析和格式化 URL 查詢字符串的工具。qs.parse() qs.stringify()

TS語法

TypeScript具有類型系統(tǒng),且是JavaScript的超集。它可以編譯成普通的JavaScript代碼。 TypeScript支持任意瀏覽器,任意環(huán)境,任意系統(tǒng)并且是開源的。npm install -g typescripttsc --init 生成tsconfig.json配置文件基礎(chǔ)數(shù)據(jù)類型 number、string、boolean、null 、undefined any 表示任意類型 void 表示空類型 內(nèi)置對(duì)象類型Array BooleanHTMLElementHTMLDivElement 自定義類型 接口 interface 類 泛型 未來的類型定義的時(shí)候不知道是什么類型,調(diào)用的時(shí)候才知道元組 1、數(shù)組中的數(shù)據(jù)類型必須和規(guī)定的類型順序?qū)?yīng)起來 2、當(dāng)使用越界索引給數(shù)組賦值的時(shí)候,會(huì)使用聯(lián)合類型(只要值是規(guī)定類型的某一種即可)。枚舉 enum類型是對(duì)JavaScript標(biāo)準(zhǔn)數(shù)據(jù)類型的一個(gè)補(bǔ)充never類型表示的是那些永不存在的值的類型。readonly:只讀屬性,不可修改sex? :表示sex是一個(gè)可傳屬性,可以有也可以沒有[propName: string]: any;表示新增的屬性可以是任意類型arr3: Array<number> 數(shù)組類型定義arr2: (number | string)[]fn (a: number, b: number) : number 函數(shù)類型定義

linux命令

pwd:輸入pwd命令,Linux會(huì)輸出當(dāng)前目錄。ls命令用來查看目錄的內(nèi)容。cd命令用來改變所在目錄。cat命令可以用來合并文件,也可以用來在屏幕上顯示整個(gè)文件的內(nèi)容。grep命令的最大功能是在一堆文件中查找一個(gè)特定的字符串。touch命令用來創(chuàng)建新文件cp命令用來拷貝文件mv命令用來移動(dòng)文件rm命令用來刪除文件。 mkdir 創(chuàng)建文件夾創(chuàng)建目錄

CSS3新特性

1 圓角邊框:border-radius 2 多背景圖:background 3 顏色和透明度:background: rgba(0,0,0,.5) 4 多列布局和彈性盒:display: flex 5 盒子的變幻(2D、3D)transform: translate(50px,100px);//移動(dòng) transform: rotate(); //旋轉(zhuǎn) transform: scale(); //縮放transform: skew(); //傾斜 6 過渡 transition: width 1s linear 2s; 動(dòng)畫:animation: myfirst 5s; @keyframes myfirst { 0% {background: block;} 25% {background: red;} 50% {background: yellow;} 100% {background: green;} } 7 引入web字體(在服務(wù)器端存儲(chǔ)) 8 媒體查詢 9 陰影 h 10 文字陰影 text-shadow div 11 盒子陰影 box-shadow

HTML5 h5新特性

1 語義化標(biāo)簽 section aside header nav 2 表單新特性:autofocus 自動(dòng)獲取焦點(diǎn)placeholder 占位multipleautocomplete 自動(dòng)補(bǔ)全,是否自動(dòng)記錄之前提交的數(shù)據(jù),以用于下一次輸入建議required 在表單提交時(shí)會(huì)驗(yàn)證是否有輸入,沒有則彈出提示消息。min:限定輸入數(shù)字的最小值。max:限定輸入數(shù)字的最大值 3 video(視頻)和audio(音頻) 4 canvas畫布 5 webworker 就是為 JavaScript 創(chuàng)造多線程環(huán)境,允許主線程創(chuàng)建 Worker 線程,將一些任務(wù)分配給后者運(yùn)行。 6 webscoket 服務(wù)器可以主動(dòng)向客戶端推送信息,客戶端也可以主動(dòng)向服務(wù)器發(fā)送信息,是真正的雙向平等對(duì)話,屬于服務(wù)器推送技術(shù)的一種。 7 拖拽apidragstart:源對(duì)象開始拖放。 drag:源對(duì)象拖放過程中。 dragend:源對(duì)象拖放結(jié)束。 過程對(duì)象: dragenter:源對(duì)象開始進(jìn)入過程對(duì)象范圍內(nèi)。 dragover:源對(duì)象在過程對(duì)象范圍內(nèi)移動(dòng)。 dragleave:源對(duì)象離開過程對(duì)象

標(biāo)準(zhǔn)盒模型與怪異盒模型區(qū)別

標(biāo)準(zhǔn)盒模型一個(gè)塊的總寬度= width + margin(左右) + padding(左右) + border(左右) 怪異盒模型一個(gè)塊的總寬度= width + margin(左右)(即width已經(jīng)包含了padding和 border值)

CSS3彈性盒

彈性盒 display:flex(父元素添加) 彈性盒:控制子元素按主軸方向排列 彈性盒可以設(shè)置單獨(dú)內(nèi)容水平垂直居中 父元素:display:flex 子元素:margin:auto 靈活元素:靈活元素即使是內(nèi)聯(lián)元素也能設(shè)置寬高加父元素身上 1.flex-direction 屬性指定了彈性子元素在父容器中的位置。 row:橫向從左到右排列(左對(duì)齊),默認(rèn)的排列方式。row-reverse:反轉(zhuǎn)橫向排列(右對(duì)齊,從后往前排,最后一項(xiàng)排在最前面。column:縱向排列。olumn-reverse:反轉(zhuǎn)縱向排列,從后往前排,最后一項(xiàng)排在最上面。 2.justify-content:flex-start/flex-end/space-between/space-around 3.align-items: 設(shè)置或檢索彈性盒子元素在側(cè)軸(縱軸)方向上的對(duì)齊方式。 center/flex-start/flex-end/baseline/stretch 4.flex-wrap:屬性用于指定彈性盒子的子元素?fù)Q行方式。nowrap/wrap/wrap-reverse 5.align-content:設(shè)置各個(gè)行的對(duì)齊: stretch - 默認(rèn)。各行將會(huì)伸展以占用剩余的空間。flex-start - 各行向彈性盒容器的起始位置堆疊。flex-end - 各行向彈性盒容器的結(jié)束位置堆疊。center -各行向彈性盒容器的中間位置堆疊。space-between -各行在彈性盒容器中平均分布。space-around 加子元素身 1、align-self:屬性用于設(shè)置彈性元素自身在側(cè)軸(縱軸)方向上的對(duì)齊方式。align-self: auto | flex-start | flex-end | center | baseline | stretchflex 屬性用于指定彈性子元素如何分配空間。1: 計(jì)算值為 1 1 autoinitial: 計(jì)算值為 0 1 autonone:計(jì)算值為 0 0 auto inherit:從父元素繼承 2、第一個(gè)參數(shù)表示: flex-grow 定義項(xiàng)目的放大比例,默認(rèn)為0,即如果存在剩余空間,也不放大 3、第二個(gè)參數(shù)表示: flex-shrink 定義了項(xiàng)目的縮小比例,默認(rèn)為1,即如果空間不足,該項(xiàng)目將縮小 4、第三個(gè)參數(shù)表示: flex-basis給上面兩個(gè)屬性分配多余空間之前, 計(jì)算項(xiàng)目是否有多余空間, 默認(rèn)值為 auto, 即項(xiàng)目本身的大小

CSS元素居中

1.使用margin進(jìn)行固定長度的偏移 2.使用絕對(duì)定位并進(jìn)行偏移(已知寬高) #father{ position:relative; } #son{ position: absolute; left:50%; top:50%; margin-left: -子元素的寬/2; margin-top: -子元素的高/2; } 3.使用絕對(duì)定位并margin自適應(yīng)進(jìn)行居中 #father{ position:relative;} #son{position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin:auto; }(啊不斯陸特) 4.使用彈性盒子來實(shí)現(xiàn)居中 #father{ display: flex; justify-content: center; align-items: center; }(加斯特佛) (額來) (哎特木) 5.使用定位 + transform #father{ position:relative;} #son{ position: absolute; left: 50%; top: 50%; transform:translate(-50% -50%) }6.table-cell布局 因?yàn)閠able-cell相當(dāng)與表格的td,td為行內(nèi)元素,無法設(shè)置寬和高,所以嵌套一層,嵌套一層必須設(shè)置display: inline-block;

CSS幾種定位的區(qū)別 relative, absolute, fixed

1、相對(duì)定位position:relative;參考物是自己,不脫離文檔流(初始位置仍然占據(jù)空 間),top:100px; 給正值是向該容器的中心點(diǎn)移動(dòng);2、絕對(duì)定位position:absolute; 參考物是外層具有position屬性的元素, 如果向外 都么有找到最后會(huì)參考body/html做定位3、固定定位position:fixed; 參考物是可視窗口 4、粘性定位(了解)position:sticky; 是絕對(duì)定位+固定定位

div外邊距重疊的原因及解決辦法

情況一:兩個(gè)div垂直邊界相鄰,margin會(huì)等于二者中margin較大的值 解決方案: 1.position:absolute 2.float:left 情況二:子元素在父元素內(nèi),子元素的margin-top會(huì)與父元素的margin-top重疊,值等于二者中較大的,如果只有子元素設(shè)置了margin-top,則顯示為父元素的margin-top 解決方案: 1.給父元素設(shè)置border(給子元素設(shè)置邊框沒有用) 2.給父元素設(shè)置padding值 3.給父元素或子元素添加float:left 4.給父元素或子元素添加position:absolute 5.給父元素添加overflow:hidden 6.給子元素添加display:inline-block 情況三:一個(gè)空白元素自身的margin-top和margin-bottom會(huì)重疊,值為而這種較大的 解決方案: 1.設(shè)置透明border

px,em,rem,pt的區(qū)別

1、px實(shí)際上就是像素,用px設(shè)置字體大小時(shí),比較穩(wěn)定和精確 2、em就是根據(jù)基準(zhǔn)來縮放字體的大小 3、rem是相對(duì)于根元素字體大小來顯示的 4、pt的大小等于1英寸的1/72 瀏覽器的兼容性除了IE6-IE8,其他的瀏覽器都支持em和rem,px所有瀏覽器都支持

CSS的BFC

1、什么是BFC BFC(Block formatting context)直譯為“塊級(jí)格式化上下文”。 他是一個(gè)獨(dú)立的渲染區(qū)域,也可以理解成一個(gè)獨(dú)立的容器,并且這個(gè)容器里box的布局,與這個(gè)容器外的毫不相干。 2、BFC渲染規(guī)則 a.內(nèi)部的box會(huì)在垂直方向,一個(gè)接一個(gè)的放置 b.box垂直方向的距離由margin決定。屬于同一個(gè)BFC的兩個(gè)相鄰box的margin會(huì)發(fā)生重 疊 c.每個(gè)元素的margin box的左邊,與包含塊border box的左邊相接觸(對(duì)于從左往右的格 式化,否則相反)。 即使存在浮動(dòng)也是如此 d.BFC的區(qū)域不會(huì)與float box重疊 e.BFC就是頁面上的一個(gè)隔離的獨(dú)立容器,容器里面的子元素不會(huì)影響到外面的元素。反之 也如此 f.計(jì)算BFC的高度時(shí),浮動(dòng)元素也參與計(jì)算 3、如何產(chǎn)生BFC a.根元素 b.float屬性不為none c.position為absolute或fixed d.display為inline-block, table-cell,table-caption,flex,inline-flex e.overflow不為visible 4、BFC的作用 a.自適應(yīng)兩欄布局 b.清除內(nèi)部浮動(dòng) c.防止垂直margin重疊(放在兩個(gè)BFC里)

兼容問題

1)css瀏覽器兼容問題(比如設(shè)置元素透明度,ie瀏覽器使用濾鏡實(shí)現(xiàn),filter :progid:DXlmage Transform.Microsoft.Alpha(style=0,opacity=50);非IE瀏覽器 opacity:0.5) 解決方法:現(xiàn)在前端開發(fā)已經(jīng)出現(xiàn)了非常多的框架和類庫用于瀏覽器的兼容問題,比如jq類 庫,解決獲取元素中包含的所有文本內(nèi)容兼容性問題,$(“element”).text(“element text”) 2)css3瀏覽器前綴問題 -ms-:ie瀏覽器 -o-:opera歐朋瀏覽器 -webkit-:谷歌瀏覽器 -moz-:火狐瀏覽器工作中遇到的困難 1)IE6中高度不對(duì)問題 在div中給定了高度為1px,其它瀏覽器顯示正常,可是ie6中顯示的高度就不對(duì)了,這時(shí)我 給樣式表中加 了個(gè)font-size:0px;line-height:0px;就好了 2)把border設(shè)為“0”像素雖然在頁面上看不見,但按border默認(rèn)值理解,瀏覽器依然對(duì) border- width/border-color進(jìn)行了渲染,即已經(jīng)占用了內(nèi)存值把border設(shè)為“none”即沒有,瀏覽器解析“none”時(shí)將不作出渲染動(dòng)作,即不會(huì)消耗內(nèi)存

移動(dòng)端適配

1.Media Queries 通過查詢?cè)O(shè)備的寬度來執(zhí)行不同的 css 代碼,最終達(dá)到界面 的配置 2.Flex彈性布局 3.rem + viewport 縮放 實(shí)現(xiàn)原理 根據(jù)rem將頁面放大dpr倍, 然后viewport設(shè)置為1/dpr. 4、rem實(shí)現(xiàn) 移動(dòng)端適配方案: 1)viewport(scale=1/dpr) dpr:備像素比 2)rem 3)flex 4)vm/vh以iphone8為例,iphone8的CSS像素為375px*677px,DPR是2,所以其設(shè)備像素為750px*1354px750(px) / 375(px) = 2

什么是CSS預(yù)處理器?優(yōu)點(diǎn)是什么

css預(yù)處理器用一種專門的編程語言,進(jìn)行web頁面樣式設(shè)計(jì),然后在編譯成正常的css文件, 以供項(xiàng)目使用 在css中使用變量、簡單的邏輯程序、函數(shù)。可以讓你的css更加簡潔、適應(yīng)性更強(qiáng)、可讀性更佳、更易于代碼的維護(hù)

0.5px線怎么實(shí)現(xiàn)(單邊框0.5px)

方式一:border + border - img + 線性漸變linear-gradient 方式二:定位 + 偽元素 + background + 線性漸變linear-gradient 方式三:定位 + 偽元素 + transform縮放(scale)

CSS布局 - 左側(cè)寬度固定,右側(cè)自適應(yīng)

方法一: 設(shè)置絕對(duì)定位寬度固定區(qū)域設(shè)置 position:absolute+ left/right+ top + width自適應(yīng)區(qū)域設(shè)置 margin-left/margin-right: 固定寬度區(qū)域的寬度。注意:(1)若左側(cè)固定的高度大于右側(cè)自適應(yīng)區(qū)域高度頁面布局就變成這樣了:(測試布局區(qū)域緊挨著自適應(yīng)區(qū)域的下方,蓋住了部分固定區(qū)域)簡單粗暴的就是測試布局區(qū)域定位的top值直接設(shè)置為兩個(gè)區(qū)域最高的高度值(2)若左側(cè)固定的高度大于右側(cè)自適應(yīng)區(qū)域高度,且測試區(qū)域不進(jìn)行定位 方法二:浮動(dòng)布局左側(cè)固定區(qū)域浮動(dòng)+寬度,右側(cè)自適應(yīng)區(qū)域 設(shè)置margin-left :左側(cè)寬度值。 方法三:BFC規(guī)則左側(cè)固定區(qū)域浮動(dòng)+寬度,右側(cè)自適應(yīng)區(qū)域(非浮動(dòng)元素)設(shè)置overflow:hidden。

CSS布局 - 左右側(cè)寬度固定,中間自適應(yīng)

1、絕對(duì)定位布局:position + margin 缺點(diǎn): 如果中間欄含有最小寬度限制,或是含有寬度的內(nèi)部元素,當(dāng)瀏覽器寬度小到一定程度,會(huì)發(fā)生層重疊的情況。 2、浮動(dòng)布局: float + margin 3、flex布局高度由內(nèi)容決定。 4、table布局高度由內(nèi)容決定。 5、Grid網(wǎng)格布局 6、圣杯布局 7、雙飛翼布局 8、對(duì)比圣杯布局和雙飛翼布局 (1)都是左右欄定寬,中間欄自適應(yīng)的三欄布局,中間欄都放到文檔流前面,保證先行渲染。 (2)解決方案基本相似:都是三欄全部設(shè)置左浮動(dòng)float:left,然后分別結(jié)局中間欄內(nèi)容被覆蓋的問題。 (3)解決中間欄內(nèi)容被覆蓋問題時(shí),圣杯布局設(shè)置父元素的padding,雙飛翼布局在中間欄嵌套一個(gè)div,內(nèi)容放到新的 div中,并設(shè)置margin,實(shí)際上,雙飛翼布局就是圣杯布局的改進(jìn)方案。

webpack 打包優(yōu)化 怎么減少打包時(shí)間

多進(jìn)程打包 - 速度分析 多進(jìn)程壓縮 - 體積分析 資源CDN 動(dòng)態(tài)polyfill - 根據(jù)不同瀏覽器,動(dòng)態(tài)載入需要的polyfill,大幅度減少構(gòu)建體積split-thunk 前端構(gòu)建項(xiàng)目中,為了提高打包效率,往往將第三庫與業(yè)務(wù)邏輯代碼分開打包,因?yàn)榈谌綆焱恍枰?jīng)常打包更新。webpack建議使用CommonsChunk 來單獨(dú)打包第三方庫webpack loader(轉(zhuǎn)換器)和plugin(插件)有什么區(qū)別:loader它是一個(gè)轉(zhuǎn)換器,將A文件進(jìn)行編譯形成B文件,這里操作的是文件,比如將A.scss轉(zhuǎn)換為A.css,單純的文件轉(zhuǎn)換過程plugin是一個(gè)擴(kuò)展器,它豐富了webpack本身,針對(duì)是loader結(jié)束后,webpack打包的整個(gè)過程,它并不直接操作文件,而是基于事件機(jī)制工作,會(huì)監(jiān)聽webpack打包過程中的某些節(jié)點(diǎn),執(zhí)行廣泛的任務(wù)loader:優(yōu)雅降級(jí),圖片打包 plugin:html產(chǎn)出:把public下面的html文件打包到build里面的index.html并自動(dòng)引入app.jscss抽離靜態(tài)資源拷貝

繼承的6種方式

1.原型鏈繼承重點(diǎn):讓新實(shí)例的原型等于父類的實(shí)例。特點(diǎn):1、實(shí)例可繼承的屬性有:實(shí)例的構(gòu)造函數(shù)的屬性,父類構(gòu)造函數(shù)屬性,父類原型的屬性。(新實(shí)例不會(huì)繼承父類實(shí)例的屬性!)缺點(diǎn):1、新實(shí)例無法向父類構(gòu)造函數(shù)傳參。2、繼承單一。3、所有新實(shí)例都會(huì)共享父類實(shí)例的屬性。(原型上的屬性是共享的,一個(gè)實(shí)例修改了原型屬性,另一個(gè)實(shí)例的原型屬性也會(huì)被修改!) 2.借用構(gòu)造函數(shù)繼承重點(diǎn):用.call()和.apply()將父類構(gòu)造函數(shù)引入子類函數(shù)(在子類函數(shù)中做了父類函數(shù)的自執(zhí)行(復(fù)制))特點(diǎn):1、只繼承了父類構(gòu)造函數(shù)的屬性,沒有繼承父類原型的屬性。2、解決了原型鏈繼承缺點(diǎn)1、2、3。3、可以繼承多個(gè)構(gòu)造函數(shù)屬性(call多個(gè))。4、在子實(shí)例中可向父實(shí)例傳參。缺點(diǎn):1、只能繼承父類構(gòu)造函數(shù)的屬性。2、無法實(shí)現(xiàn)構(gòu)造函數(shù)的復(fù)用。(每次用每次都要重新調(diào)用)3、每個(gè)新實(shí)例都有父類構(gòu)造函數(shù)的副本,臃腫。 3.組合繼承(組合原型鏈繼承和借用構(gòu)造函數(shù)繼承) 重點(diǎn):結(jié)合了兩種模式的優(yōu)點(diǎn),傳參和復(fù)用特點(diǎn):1、可以繼承父類原型上的屬性,可以傳參,可復(fù)用。2、每個(gè)新實(shí)例引入的構(gòu)造函數(shù)屬性是私有的。缺點(diǎn):調(diào)用了兩次父類構(gòu)造函數(shù)(耗內(nèi)存),子類的構(gòu)造函數(shù)會(huì)代替原型上的那個(gè)父類構(gòu)造函數(shù)。 4.原型式繼承重點(diǎn):用一個(gè)函數(shù)包裝一個(gè)對(duì)象,然后返回這個(gè)函數(shù)的調(diào)用,這個(gè)函數(shù)就變成了個(gè)可以隨意增添屬性的實(shí)例或?qū)ο蟆? object.create()就是這個(gè)原理。特點(diǎn):類似于復(fù)制一個(gè)對(duì)象,用函數(shù)來包裝。缺點(diǎn):1、所有實(shí)例都會(huì)繼承原型上的屬性。2、無法實(shí)現(xiàn)復(fù)用。(新實(shí)例屬性都是后面添加的) 5.寄生式繼承重點(diǎn):就是給原型式繼承外面套了個(gè)殼子。優(yōu)點(diǎn):沒有創(chuàng)建自定義類型,因?yàn)橹皇翘琢藗€(gè)殼子返回對(duì)象(這個(gè)),這個(gè)函數(shù)順理成章就成了創(chuàng)建的新對(duì)象。缺點(diǎn):沒用到原型,無法復(fù)用。 6.寄生組合式繼承(常用)重點(diǎn):修復(fù)了組合繼承的問題寄生:在函數(shù)內(nèi)返回對(duì)象然后調(diào)用組合:1、函數(shù)的原型等于另一個(gè)實(shí)例。2、在函數(shù)中用apply或者call引入另一個(gè)構(gòu)造函數(shù),可傳參 

阻止冒泡和取消默認(rèn)事件(默認(rèn)行為)

防止事件捕獲和冒泡: w3c的方法是e.stopPropagation() IE則是使用e.cancelBubble = true取消默認(rèn)事件 w3c的方法是e.preventDefault() IE則是使用e.returnValue = falsejQuery用法 阻止默認(rèn)事件 return false (不停止冒泡)

作用域和作用域鏈

變量的作用域無非就是兩種: 全局變量和局部變量。javascript的作用域是相對(duì)函數(shù)而言的,可以稱為函數(shù)作用域全局作用域: 最外層函數(shù)定義的變量擁有全局作用域,即對(duì)任何內(nèi)部函數(shù)來說,都是可以訪問的局部作用域: 局部作用域一般只在固定的代碼片段內(nèi)可訪問到,而對(duì)于函數(shù)外部是無法訪問的作用域鏈: 根據(jù)在內(nèi)部函數(shù)可以訪問外部函數(shù)變量的這種機(jī)制,用鏈?zhǔn)讲檎覜Q定哪些數(shù)據(jù)能被內(nèi)部函數(shù)訪問。作用域鏈的前端,始終都是當(dāng)前執(zhí)行的代碼所在環(huán)境的變量對(duì)象作用域鏈中的下一個(gè)對(duì)象來自于外部環(huán)境,而在下一個(gè)變量對(duì)象則來自下一個(gè)外部環(huán)境,一直到全局執(zhí)行環(huán)境全局執(zhí)行環(huán)境的變量對(duì)象始終都是作用域鏈上的最后一個(gè)對(duì)象

遍歷數(shù)組的方式

1.for循環(huán) 使用臨時(shí)變量,將長度緩存起來,避免重復(fù)獲取數(shù)組長度,當(dāng)數(shù)組較大時(shí)優(yōu)化效果才會(huì)比較明顯。2.foreach循環(huán) 遍歷數(shù)組中的每一項(xiàng),沒有返回值,對(duì)原數(shù)組沒有影響,不支持IE。 有一些局限,不能continue跳過或者break終止循環(huán)3.map循環(huán) 有返回值,可以return出來 map的回調(diào)函數(shù)中支持return返回值 并不影響原來的數(shù)組,return的是新數(shù)組4.for of遍歷 可以正確響應(yīng)break、continue和return語句5.filter遍歷 不會(huì)改變?cè)紨?shù)組,返回新數(shù)組6.every遍歷 every()是對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),如果該函數(shù)對(duì)每一項(xiàng)返回true,則返回true。7.some遍歷 some()是對(duì)數(shù)組中每一項(xiàng)運(yùn)行指定函數(shù),如果該函數(shù)對(duì)任一項(xiàng)返回true,則返回true。8.reduce reduce()方法接收一個(gè)函數(shù)作為累加器(accumulator),數(shù)組中的每個(gè)值(從左到右)開始縮減,最終為一個(gè)值。9.reduceRight reduceRight()方法的功能和reduce()功能是一樣的, 不同的是reduceRight()從數(shù)組的末尾向前將數(shù)組中的數(shù)組項(xiàng)做累加。10.find find()方法返回?cái)?shù)組中符合測試函數(shù)條件的第一個(gè)元素。否則返回undefined 11.findIndex 對(duì)于數(shù)組中的每個(gè)元素,findIndex方法都會(huì)調(diào)用一次回調(diào)函數(shù)(采用升序索引順序),直到有元素返回 true。 只要有一個(gè)元素返回 true,findIndex立即返回該返回 true 的元素的索引值。 如果數(shù)組中沒有任何元素返回 true,則 findIndex 返回 -1。 findIndex 不會(huì)改變數(shù)組對(duì)象。12.keys,values,entries ES6 提供三個(gè)新的方法 —— entries(),keys()和values() —— 用于遍歷數(shù)組。 它們都返回一個(gè)遍歷器對(duì)象,可以用for...of循環(huán)進(jìn)行遍歷, 唯一的區(qū)別是keys()是對(duì)鍵名的遍歷、values()是對(duì)鍵值的遍歷,entries()是對(duì)鍵值對(duì)的遍歷

數(shù)據(jù)分頁

前端的話,定義一個(gè)新的數(shù)組for循環(huán)判斷,有個(gè)公式,計(jì)算起始頁和終止頁的。 符合條件push僅數(shù)組中,后端就是用limt判斷

數(shù)組排序

1. 普通數(shù)組排序  js中用方法sort()為數(shù)組排序。sort()方法有一個(gè)可選參數(shù),是用來確定元素順序的函數(shù)。如果這個(gè)參數(shù)被省略,那么數(shù)組中的元素將按照ASCII字符順序進(jìn)行排序。 2. 冒泡排序 (1)比較相鄰的元素。如果第一個(gè)比第二個(gè)大,就交換他們兩個(gè)位置。 (2)對(duì)每一對(duì)相鄰元素作同樣的工作,從開始第一對(duì)到結(jié)尾的最后一對(duì)。在這一點(diǎn),最后的元素應(yīng)該會(huì)是最大的數(shù)。 (3)針對(duì)所有的元素重復(fù)以上的步驟,除了最后一個(gè)。 (4)持續(xù)每次對(duì)越來越少的元素重復(fù)上面的步驟,直到?jīng)]有任何一對(duì)數(shù)字需要比較。 3. 快速排序:遞歸思想,兩邊快速的排序,冒泡排序的改進(jìn) (1)選擇數(shù)組中間數(shù)作為基數(shù),并從數(shù)組中取出此基數(shù); (2)準(zhǔn)備兩個(gè)數(shù)組容器,遍歷數(shù)組,逐個(gè)與基數(shù)比對(duì),較小的放左邊容器,較大的放右邊容器; (3)進(jìn)行相同的操作,直到數(shù)組中只有一個(gè)元素時(shí),返回該數(shù)組。 4. 插入排序 (1)從第一個(gè)元素開始,該元素可以認(rèn)為已經(jīng)被排序 (2)取出下一個(gè)元素,在已經(jīng)排序的元素序列中掃描 (3)如果該元素(已排序)大于新元素,將該元素移到下一位置 (4)重復(fù)步驟3,直到找到已排序的元素小于或者等于新元素的位置 (5)將新元素插入到下一位置中 (6)重復(fù)步驟2 5. 選擇排序 (1)在未排序序列中找到最小(大)元素 (2)并存放到排序序列的起始位置 (3)然后,再從剩余未排序元素中繼續(xù)尋找最小(大)元素 (4)然后放到已排序序列的末尾。 (5)以此類推

數(shù)組合并

1、concatjs的Array對(duì)象提供了一個(gè)叫concat()方法,連接兩個(gè)或更多的數(shù)組,并返回結(jié)果。var c = a.concat(b); //c=[1,2,3,4,5,6];這里有一個(gè)問題,concat方法連接a、b兩個(gè)數(shù)組后,a、b兩個(gè)數(shù)組的數(shù)據(jù)不變,同時(shí)會(huì)返回一個(gè)新的數(shù)組。這樣當(dāng)我們需要進(jìn)行多次的數(shù)組合并時(shí),會(huì)造成很大的內(nèi)存浪費(fèi),如果是數(shù)據(jù)量比較小的時(shí)候,還可以勉強(qiáng)用,如果數(shù)據(jù)量大的時(shí)候,這個(gè)就不妥了,所以這個(gè)方法肯定不是最好的。2、for循環(huán) 大概的思路是:遍歷其中一個(gè)數(shù)組,把該數(shù)組中的所有元素依次添加到另外一個(gè)數(shù)組中。直接上代碼:for(var i in b) { a.push ( b[i] );}3、apply函數(shù)的apply方法有一個(gè)特性,那就是func.apply(obj,argv),argv是一個(gè)數(shù)組。a.push.apply(a,b);調(diào)用a.push這個(gè)函數(shù)實(shí)例的apply方法,同時(shí)把,b當(dāng)作參數(shù)傳入,這樣a.push這個(gè)方法就會(huì)遍歷b數(shù)組的所有元素,達(dá)到合并的效果。這里可能有點(diǎn)繞,我們可以把b看成[4,5,6],變成這樣:a.push.apply(a,[4,5,6]);然后上面的操作就等同于:a.push(4,5,6);這樣就很清楚了!

數(shù)組方法

push,在數(shù)組末尾添加一位或多位元素 pop,刪除數(shù)組最后一位元素 unshift,在數(shù)組的開頭添加一位或多位元素 shift,刪除數(shù)組的第一位元素 join,將數(shù)組轉(zhuǎn)換為字符串 reserve,反轉(zhuǎn)數(shù)組元素的順序 sort,對(duì)數(shù)組進(jìn)行排序 concat,連接兩個(gè)或多個(gè)數(shù)組 splice,添加或刪除數(shù)組中的元素 slice,從已有的數(shù)組中返回選定的元素 indexOf、lastIndexOf,查找數(shù)組中的元素 forEach,對(duì)數(shù)組進(jìn)行遍歷循環(huán),對(duì)數(shù)組中每一項(xiàng)運(yùn)行指定的函數(shù) map,迭代數(shù)組 filter,對(duì)數(shù)組中的元素進(jìn)行指定的檢查返回符合條件的元素放入一個(gè)新數(shù)組中 every,測試所有元素是否都符合指定條件 some,測試某些元素是否符合指定條件 reduce,接收一個(gè)函數(shù)作為累加器,數(shù)組中的每個(gè)值開始縮減,最終計(jì)算為一個(gè)值 toString,將數(shù)組轉(zhuǎn)換為字符串

數(shù)組去重

使用ES6 Setvar arr = [1, 1, 4, 2, 2, 3, 3, 3, 6, 6, 6];arr = Array.from(new Set(arr)); [...new Set(arr)]console.log(arr);//[1, 4, 2, 3, 6]使用indexOfvar arr = [1, 1, 4, 2, 2, 3, 3, 3, 6, 6, 6];var newArr = [];arr.forEach((item) => {newArr.indexOf(item) === -1 ? newArr.push(item) : "";});console.log(newArr);//[1, 4, 2, 3, 6]使用lastIndexOfvar arr = [1, 1, 4, 2, 2, 3, 3, 3, 6, 6, 6];var newArr = [];arr.forEach((item) => {newArr.lastIndexOf(item) === -1 ? newArr.push(item) : "";});console.log(newArr);//[1, 4, 2, 3, 6]使用雙重for循環(huán)加splice方法var arr = [1, 1, 4, 2, 2, 3, 3, 3, 6, 6, 6];for (var i = 0; i < arr.length; i++) {for (var j = i + 1; j < arr.length; j++) {if (arr[i] == arr[j]) {arr.splice(j,1);j--;}}}console.log(arr);//[1, 4, 2, 3, 6]使用forEach和includes方法var arr = [1, 1, 4, 2, 2, 3, 3, 3, 6, 6, 6];var newArr = [];arr.forEach((item) => {newArr.includes(item) ? "" : newArr.push(item);});console.log(newArr);//[1, 4, 2, 3, 6]使用fliter和includes方法var arr = [1, 1, 4, 2, 2, 3, 3, 3, 6, 6, 6];var newArr = [];arr.filter((item) => {newArr.includes(item) ? "" : newArr.push(item);});console.log(newArr);//[1, 4, 2, 3, 6]

for…of 原理

for...of 是ES6引入用來遍歷所有數(shù)據(jù)結(jié)構(gòu)的統(tǒng)一方法。這里的所有數(shù)據(jù)結(jié)構(gòu)只指具有iterator接口的數(shù)據(jù)。 一個(gè)數(shù)據(jù)只要部署了 Symbol.iterator,就具有了 iterator接口,就可以使用 for...of 循環(huán)遍歷它的成員。 也就是說,for...of循環(huán)內(nèi)部調(diào)用的數(shù)據(jù)結(jié)構(gòu)為Symbol.iterator方法。 部署在 Symbol.iterator 屬性,或者說,一個(gè)數(shù)據(jù)結(jié)構(gòu)只要具有 Symbol.iterator 屬性,就認(rèn)為是"可遍歷的"。Iterator(伊特瑞特):遍歷器(Iterator)就是這樣一種機(jī)制。它是一種接口,為各種不同的數(shù)據(jù)結(jié)構(gòu)提供統(tǒng)一的訪問機(jī)制。任何數(shù)據(jù)結(jié)構(gòu)只要部署 Iterator 接口,就可以完成遍歷操作(即依次處理該數(shù)據(jù)結(jié)構(gòu)的所有成員)。通俗點(diǎn)理解就是為了解決不同數(shù)據(jù)結(jié)構(gòu)遍歷的問題,引入了Iterator.Iterator的特點(diǎn):各種數(shù)據(jù)結(jié)構(gòu),提供一個(gè)統(tǒng)一的、簡便的訪問接口使得數(shù)據(jù)結(jié)構(gòu)的成員能夠按某種次序排列ES6 創(chuàng)造了一種新的遍歷命令for...of循環(huán),Iterator 接口主要供for...of消費(fèi)原生具備 Iterator 接口的數(shù)據(jù)結(jié)構(gòu)如下。ArrayMapSetString:字符串是一個(gè)類似數(shù)組的對(duì)象,也原生具有 Iterator 接口。TypedArray:通俗理解:ArrayBuffer是一片內(nèi)存空間,不能直接引用里面的數(shù)據(jù),可以通過TypedArray類型引用,用戶只能通過TypedArray使用這片內(nèi)存,不能直接通過ArrayBuffer使用這片內(nèi)存函數(shù)的 arguments 對(duì)象NodeList 對(duì)象除了原生具備Iterator 接口的數(shù)據(jù)之外,其他數(shù)據(jù)結(jié)構(gòu)(主要是對(duì)象)的 Iterator 接口, 都需要自己在Symbol.iterator屬性上面部署,這樣才會(huì)被for...of循環(huán)遍歷。對(duì)象(Object)之所以沒有默認(rèn)部署 Iterator 接口,是因?yàn)閷?duì)象的哪個(gè)屬性先遍歷,哪個(gè)屬性后遍歷是不確定的,需要開發(fā)者手動(dòng)指定。本質(zhì)上,遍歷器是一種線性處理,對(duì)于任何非線性的數(shù)據(jù)結(jié)構(gòu),部署遍歷器接口,就等于部署一種線性轉(zhuǎn)換。不過,嚴(yán)格地說,對(duì)象部署遍歷器接口并不是很必要,因?yàn)檫@時(shí)對(duì)象實(shí)際上被當(dāng)作 Map 結(jié)構(gòu)使用,ES5 沒有 Map 結(jié)構(gòu),而 ES6 原生提供了。一個(gè)對(duì)象如果要具備可被for...of循環(huán)調(diào)用的 Iterator 接口,就必須在Symbol.iterator的屬性上部署遍歷器生成方法(原型鏈上的對(duì)象具有該方法也可)。

遍歷對(duì)象的方式

第一種: for...in第二種: 1)Object.keys(obj) 2)Object.values(obj) 參數(shù):obj:要返回其枚舉自身屬性的對(duì)象 返回值:一個(gè)表示給定對(duì)象的所有可枚舉屬性的字符串?dāng)?shù)組。第三種: 使用Object.getOwnPropertyNames(obj) 返回一個(gè)數(shù)組,包含對(duì)象自身的所有屬性(包含不可枚舉屬性) 遍歷可以獲取key和value

map與filter和forEach的區(qū)別

map 與 filter 區(qū)別:相同點(diǎn):filter 和 map 都是對(duì)數(shù)組的操作,均返回一個(gè)新的數(shù)組不同點(diǎn):filter是滿足條件的留下,是對(duì)原數(shù)組的過濾;map則是對(duì)原數(shù)組的加工,映射成一對(duì)一映射的新數(shù)組map 與 forEach 區(qū)別:map()會(huì)分配內(nèi)存空間存儲(chǔ)新數(shù)組并返回,forEach()不會(huì)返回?cái)?shù)據(jù)(undefined)。forEach()允許callback更改原始數(shù)組的元素。map()返回新的數(shù)組。

面向?qū)ο缶幊?/h1> 面向?qū)ο缶幊? 將所需要做的功能抽象成一個(gè)“對(duì)象”,然后一遍遍地調(diào)用這個(gè)對(duì)象來完成你想要的功能。面向?qū)ο蟮娜筇卣? 1.封裝 我們平時(shí)所用的方法和類都是一種封裝,當(dāng)我們?cè)陧?xiàng)目開發(fā)中,遇到一段功能的代碼在好多地方重復(fù)使用的時(shí)候,我們可以把他單獨(dú)封裝成一個(gè)功能的方法,這樣在我們需要使用的地方直接調(diào)用就可以了。2.繼承 繼承在我們的項(xiàng)目開發(fā)中主要使用為子類繼承父類,繼承會(huì)繼承父類的實(shí)例屬性和實(shí)例方法,并不會(huì)繼承靜態(tài)屬性和靜態(tài)方法,并且靜態(tài)方法只能通過類名去調(diào)用。3.多態(tài) 多態(tài)的具體表現(xiàn)為方法重載和方法重寫: 方法重載: 重載是指不同的函數(shù)使用相同的函數(shù)名,但是函數(shù)的參數(shù)個(gè)數(shù)或類型不同。調(diào)用的時(shí)候根據(jù)函數(shù)的參數(shù)來區(qū)別不同的函數(shù) 方法重寫: 重寫(也叫覆蓋)是指在派生類中重新對(duì)基類中的虛函數(shù)(注意是虛函數(shù))重新實(shí)現(xiàn)。即函數(shù)名和參數(shù)都一樣,只是函數(shù)的實(shí)現(xiàn)體不一樣三大特征的優(yōu)點(diǎn): 封裝: 封裝的優(yōu)勢(shì)在于定義只可以在類內(nèi)部進(jìn)行對(duì)屬性的操作,外部無法對(duì)這些屬性指手畫腳,要想修改,也只能通過你定義的封裝方法;繼承: 繼承減少了代碼的冗余,省略了很多重復(fù)代碼,開發(fā)者可以從父類底層定義所有子類必須有的屬性和方法,以達(dá)到耦合的目的;多態(tài): 多態(tài)實(shí)現(xiàn)了方法的個(gè)性化,不同的子類根據(jù)具體狀況可以實(shí)現(xiàn)不同的方法,光有父類定義的方法不夠靈活,遇見特殊狀況就捉襟見肘了

window.onload與document.ready的區(qū)別

1.執(zhí)行時(shí)間window.onload必須等到頁面內(nèi)包括圖片的所有元素加載完畢后才能執(zhí)行。 $(document).ready()是DOM結(jié)構(gòu)繪制完畢后就執(zhí)行,不必等到加載完畢。2.編寫個(gè)數(shù)不同window.onload不能同時(shí)編寫多個(gè),如果有多個(gè)window.onload方法,只會(huì)執(zhí)行一個(gè) $(document).ready()可以同時(shí)編寫多個(gè),并且都可以得到執(zhí)行3.簡化寫法window.onload沒有簡化寫法 $(document).ready(function(){})可以簡寫成$(function(){});

this

this代表函數(shù)運(yùn)行時(shí),自動(dòng)生成的一個(gè)內(nèi)部對(duì)象,只能在函數(shù)內(nèi)部使用, 隨著函數(shù)使用場合的不同,this的值會(huì)發(fā)生變化。指向: 1.在方法中,this 表示該方法所屬的對(duì)象。 2.如果單獨(dú)使用,this 表示全局對(duì)象。 3.函數(shù)中,this 表示全局對(duì)象。 4.嚴(yán)格模式下,this 是未定義的(undefined)。 5.在事件中,this 表示接收事件的元素。 6.類似 call() 和 apply() 方法可以將 this 引用到任何對(duì)象。 7.箭頭函數(shù)本身是沒有this和arguments的,引用的this實(shí)際上是調(diào)用的是定義時(shí)的上一層作用域的this。

<!DOCTYPE>

<!DOCTYPE> 聲明位于文檔中的最前面的位置,處于 <html> 標(biāo)簽之前。<!DOCTYPE> 聲明不是一個(gè) HTML 標(biāo)簽;它是用來告知 Web 瀏覽器頁面使用了哪種 HTML 版本。在 HTML 4.01 中,<!DOCTYPE> 聲明需引用 DTD (文檔類型聲明), 因?yàn)?HTML 4.01 是基于 SGML (Standard Generalized Markup Language 標(biāo)準(zhǔn)通用標(biāo)記語言)。 DTD 指定了標(biāo)記語言的規(guī)則,確保了瀏覽器能夠正確的渲染內(nèi)容。HTML5 不是基于 SGML,因此不要求引用 DTD。給您 HTML 文檔添加 <!DOCTYPE> 聲明,確保瀏覽器能夠預(yù)先知道文檔類型。

CSS position屬性

absolute:生成絕對(duì)定位的元素,相對(duì)于 static 定位以外的第一個(gè)父元素進(jìn)行定位。 fixed :生成固定定位的元素,相對(duì)于瀏覽器窗口進(jìn)行定位。 relative:生成相對(duì)定位的元素,相對(duì)于其正常位置進(jìn)行定位。 static :默認(rèn)值。沒有定位。 sticky :粘性定位,該定位基于用戶滾動(dòng)的位置。 inherit :規(guī)定應(yīng)該從父元素繼承 position 屬性的值。

js的解構(gòu)

解構(gòu)定義:允許按照一定模式,從數(shù)組和對(duì)象中提取值,對(duì)變量進(jìn)行賦值。 解構(gòu)必須滿足的條件:(模式匹配),只要等號(hào)兩邊的模式相同,左邊的變量就會(huì)被賦予對(duì)應(yīng)的值。 主要介紹2種解構(gòu)常用的類型:數(shù)組解構(gòu)和對(duì)象解構(gòu)。數(shù)組解構(gòu):1.數(shù)組中的變量個(gè)數(shù)比賦值的數(shù)組中個(gè)數(shù)少的解構(gòu):2.數(shù)組中的變量個(gè)數(shù)比賦值的數(shù)組中個(gè)數(shù)多的解構(gòu):3.數(shù)組中的變量中有空字符的解構(gòu):上面的3種數(shù)組解構(gòu),賦值的數(shù)組的數(shù)值按位賦值給另外一方數(shù)組中的變量4.數(shù)組中的變量中有不定參數(shù)(有些時(shí)候也叫擴(kuò)展運(yùn)算符)的解構(gòu):需要注意的是不定參數(shù)必須放最后。5.數(shù)組中的變量中有默認(rèn)值的解構(gòu):如果賦值的數(shù)組個(gè)數(shù)沒有另外一方數(shù)組變量個(gè)數(shù)多,并且變量數(shù)組有默認(rèn),沒有進(jìn)行賦值用默認(rèn),進(jìn)行賦值用賦值的對(duì)象的解構(gòu):兩方也需要相同類型的括號(hào),對(duì)象結(jié)構(gòu)使用大括號(hào){} 普通對(duì)象解構(gòu):對(duì)象跟數(shù)值解構(gòu)不同的一點(diǎn),對(duì)象解構(gòu)不是按位去賦值,是根據(jù)鍵名(屬性名) 來進(jìn)行賦值 有默認(rèn)值的對(duì)象解構(gòu)跟數(shù)組的默認(rèn)值差不多,有賦值就用賦值的,沒有就用默認(rèn)值 有不定參數(shù)的對(duì)象解構(gòu)跟數(shù)組的不定參數(shù)差不多,不定參數(shù)放在最后,不定參數(shù)創(chuàng)建一個(gè)對(duì)象接受的剩下的鍵名鍵值(屬性名屬性值) 有嵌套的對(duì)象解構(gòu)主要注意嵌套層次是不是賦值一方對(duì)象的嵌套層次相同。

js實(shí)現(xiàn)輪播圖思路

1.圖片移動(dòng)實(shí)現(xiàn)原理: 利用浮動(dòng)將所有所有照片依次排成一行,給這一長串圖片添加一個(gè)父級(jí)的遮罩,每次只顯示一張圖,其余的都隱藏起來。對(duì)圖片添加絕對(duì)定位,通過控制left屬性,實(shí)現(xiàn)照片的移動(dòng)。2.圖片移動(dòng)動(dòng)畫原理: 從a位置移動(dòng)到b位置,需要先計(jì)算兩點(diǎn)之間的差值,通過差值和時(shí)間間隔,計(jì)算出每次移動(dòng)的步長,通過添加定時(shí)器,每次移動(dòng)相同的步長,實(shí)現(xiàn)動(dòng)畫效果。3.圖片定位停止原理: 每一張照片都有相同的寬度,每張照片都有一個(gè)絕對(duì)的定位數(shù)值,通過檢測定每次移動(dòng)后,照片當(dāng)前位置和需要到達(dá)位置之間的距離是否小于步長,如果小于,說明已經(jīng)移動(dòng)到位,可以將定時(shí)器清除,來停止動(dòng)畫。4圖片切換原理: 在全局設(shè)置一個(gè)變量,記錄當(dāng)前圖片的位置,每次切換或跳轉(zhuǎn)時(shí),只需要將數(shù)值修改,并調(diào)用圖片頁數(shù)轉(zhuǎn)像素位置函數(shù),再調(diào)用像素運(yùn)動(dòng)函數(shù)即可。5.自動(dòng)輪播原理: 設(shè)置定時(shí)器,一定時(shí)間間隔后,將照片標(biāo)記加1,然后開始切換。6.左右點(diǎn)擊切換原理: 修改當(dāng)前位置標(biāo)記,開始切換。這里需要注意與自動(dòng)輪播之間的沖突。當(dāng)點(diǎn)擊事件觸發(fā)之后,停止自動(dòng)輪播計(jì)時(shí)器,開始切換。當(dāng)動(dòng)畫結(jié)束后再次添加自動(dòng)輪播計(jì)時(shí)器。7.無縫銜接原理: 需要無縫銜接,難度在于最后一頁向后翻到第一頁,和第一頁向前翻到最后一頁。由于圖片的基本移動(dòng)原理。要想實(shí)現(xiàn)無縫銜接,兩張圖片就必須緊貼在一起。所以在第一張的前面需要添加最后一張,最后一張的后面需要添加第一張。首先判斷圖片的位置,是否移動(dòng)到位。當(dāng)滿足當(dāng)前位置,與預(yù)定位置之間的距離小于一步時(shí),認(rèn)定為移動(dòng)到位,并把圖片直接定位到預(yù)定位置。然后判斷,圖片的位置是否需要跳轉(zhuǎn)。 ps:這里一定要在圖片運(yùn)動(dòng)函數(shù)結(jié)束后,在進(jìn)行跳轉(zhuǎn)。8.預(yù)防鬼畜原理: 始終保證輪播圖的運(yùn)動(dòng)動(dòng)畫只有一個(gè),從底層杜絕鬼畜。需要在每次動(dòng)畫開始之前,嘗試停止動(dòng)畫定時(shí)器,然后開始為新的動(dòng)畫添加定時(shí)器。輪播圖鬼畜的本質(zhì)原因就是,同一時(shí)間多個(gè)定時(shí)器添加在圖片上,這些定時(shí)器直接相互沖突,造成圖片的抖動(dòng)。 解決方法:每次執(zhí)行運(yùn)動(dòng)函數(shù)之前,先嘗試清除一下,上一個(gè)輪播圖的定時(shí)器。確保同時(shí)觸發(fā)運(yùn)動(dòng)函數(shù)時(shí),只有一個(gè)定時(shí)器在工作。9.預(yù)防暴力點(diǎn)擊原理: 如果用戶快速點(diǎn)擊觸發(fā)事件,會(huì)在短時(shí)間內(nèi)多次調(diào)用切換函數(shù),雖然動(dòng)畫函數(shù)可以保證,不會(huì)發(fā)生鬼畜,但在照片從最后一張到第一張的切換過程,不會(huì)按照正常的輪播,而是實(shí)現(xiàn)了跳轉(zhuǎn)。所以需要通過添加口令的方式來,限制用戶的點(diǎn)擊。當(dāng)用戶點(diǎn)擊完成后,口令銷毀,動(dòng)畫結(jié)束后恢復(fù)口令。10.小圓點(diǎn)的位置顯示原理: 每次觸發(fā)動(dòng)畫時(shí),通過全局變量標(biāo)記,獲取當(dāng)前頁數(shù),操作清除所有小圓點(diǎn),然后指定一頁添加樣式。11.點(diǎn)擊觸發(fā)跳轉(zhuǎn)的原理: 類似于左右點(diǎn)擊觸發(fā),只是這是將全局頁面標(biāo)記,直接修改,后執(zhí)行動(dòng)畫。需要避免與自動(dòng)輪播定時(shí)器的沖突。

js數(shù)組和對(duì)象的擴(kuò)展

1.Array.from()方法用于將對(duì)象轉(zhuǎn)為真正的數(shù)組(類數(shù)組轉(zhuǎn)數(shù)組) 2.Array.of()方法用于將一組值,轉(zhuǎn)換為數(shù)組。console.log(Array.of(1,2,3,4,4,50));//[1, 2, 3, 4, 4, 50] 3.Object.assign(目標(biāo)對(duì)象,對(duì)象1,對(duì)象2)用于對(duì)象的合并,將源對(duì)象的所有可枚舉屬性,復(fù)制到目標(biāo)對(duì)象。(淺拷貝)

js提升

一、提升(Hosting) 簡單說就是在js代碼執(zhí)行前引擎會(huì)先進(jìn)行預(yù)編譯,預(yù)編譯期間會(huì)將變量聲明與函數(shù)聲明提升至其對(duì)應(yīng)作用域的最頂端。二、變量提升 在ES6之前,JavaScript沒有塊級(jí)作用域(一對(duì)花括號(hào){}即為一個(gè)塊級(jí)作用域),只有全局作用域和函數(shù)作用域。 變量提升即將變量聲明提升到它所在作用域的最開始的部分。 變量聲明的提升是以變量所處的第一層詞法作用域?yàn)椤皢挝弧钡?#xff0c;即全局作用域中聲明的變量會(huì)提升至全局最頂層,函數(shù)內(nèi)聲明的三、函數(shù)提升 即函數(shù)提升只會(huì)提升函數(shù)聲明,而不會(huì)提升函數(shù)表達(dá)式。四、為什么會(huì)有提升? 函數(shù)提升就是為了解決相互遞歸的問題,大體上可以解決像ML語言這樣自下而上的順序問題。 大概是說,變量提升是人為實(shí)現(xiàn)的問題,而函數(shù)提升在當(dāng)初設(shè)計(jì)時(shí)是有目的的。

比較redux和vuex的區(qū)別

redux和vuex的區(qū)別1)vuex是redux的基礎(chǔ)上進(jìn)行改變,對(duì)倉庫的管理更加明確2)使用mutation來替換redux中的reducer3)vuex有自動(dòng)渲染的功能,所以不需要更新redux和flux的區(qū)別1)redux是flux中的一個(gè)實(shí)現(xiàn)2))在redux中我們只能定義一個(gè)store,在flux中我們可以定義多個(gè)3)在redux中,store和dispatch都放到了store,結(jié)構(gòu)更加清晰4)在redux中本身就內(nèi)置State對(duì)象,對(duì)倉庫的管理更加明確

CSS display 屬性

none此元素不會(huì)被顯示。))
block此元素將顯示為塊級(jí)元素,此元素前后會(huì)帶有換行符。
inline默認(rèn)。此元素會(huì)被顯示為內(nèi)聯(lián)元素,元素前后沒有換行符。
inline-block行內(nèi)塊元素。(CSS2.1 新增的值)
list-item此元素會(huì)作為列表顯示。
run-in此元素會(huì)根據(jù)上下文作為塊級(jí)元素或內(nèi)聯(lián)元素顯示。
compactCSS 中有值 compact,不過由于缺乏廣泛支持,已經(jīng)從 CSS2.1 中刪除。
markerCSS 中有值 marker,不過由于缺乏廣泛支持,已經(jīng)從 CSS2.1 中刪除。
table此元素會(huì)作為塊級(jí)表格來顯示(類似 ),表格前后帶有換行符。
inline-table此元素會(huì)作為內(nèi)聯(lián)表格來顯示(類似 ),表格前后沒有換行符。
table-row-group此元素會(huì)作為一個(gè)或多個(gè)行的分組來顯示(類似
table-header-group此元素會(huì)作為一個(gè)或多個(gè)行的分組來顯示(類似
table-footer-group此元素會(huì)作為一個(gè)或多個(gè)行的分組來顯示(類似
table-row此元素會(huì)作為一個(gè)表格行顯示(類似
table-column-group此元素會(huì)作為一個(gè)或多個(gè)列的分組來顯示(類似
table-column此元素會(huì)作為一個(gè)單元格列顯示(類似
table-cell此元素會(huì)作為一個(gè)表格單元格顯示(類似
table-caption此元素會(huì)作為一個(gè)表格標(biāo)題顯示(類似
inherit規(guī)定應(yīng)該從父元素繼承 display 屬性的值。
)。)。)。)。)。)

CSS選擇符

CSS選擇符id選擇器(#myid)類選擇器(.myclassname)標(biāo)簽選擇器(div)相鄰選擇器(h1+p)子選擇器(ul>li)后代選擇器(li a)群組選擇器(div,p{})通配符選擇器(*)屬性選擇器(a[title=""])偽類選擇器(a:hover{}或者li:nth-child{})

CSS中l(wèi)ink和@import的區(qū)別

link屬于HTML標(biāo)簽,@import是CSS提供的頁面被加載時(shí),link引用的css文件會(huì)同時(shí)被加載,而@import引用的css文件要等到頁面被加載完畢再加載import只在IE5以上才能識(shí)別,link是HTML標(biāo)簽,無兼容問題link 引入樣式的權(quán)重大于@import 的引用

CSS中display:none、visibility:hidden和opacity:0;的區(qū)別

display:none;隱藏對(duì)應(yīng)的元素,在文檔布局中不再給它分配空間,它各邊的元素會(huì)合攏。visibility:hidden;隱藏對(duì)應(yīng)的元素,但在文檔布局中仍保留原來的空間。opacity:0;內(nèi)容不可見,占據(jù)空間。

CSS中rgba()和opacity的透明效果區(qū)別

rgba()和 opacity 都能實(shí)現(xiàn)透明效果,但最大的不同是 opacity 作用于元素,以及元素內(nèi)的所有內(nèi)容的透明度;rgba()只作用于元素的顏色或其背景色(設(shè)置 rgba 透明的元素的子元素不會(huì)繼承透明效果)。

CSS的外邊距重疊

在 CSS 當(dāng)中,相鄰的兩個(gè)盒子(可能是兄弟關(guān)系也可能是祖先關(guān)系)的外邊距可以結(jié)合成一個(gè)單獨(dú)的外邊距。這種合并外邊距的方式被稱為折疊,并且因而所結(jié)合成的外邊距稱為折疊外邊距。折疊結(jié)果遵循下列計(jì)算規(guī)則如下兩個(gè)相鄰的外邊距都是正數(shù)時(shí),折疊結(jié)果是它們兩者之間較大的值。兩個(gè)相鄰的外邊距都是負(fù)數(shù)時(shí),折疊結(jié)果是兩者絕對(duì)值的較大值。兩個(gè)外邊距一正一負(fù)時(shí),折疊結(jié)果是兩者之和。

CSS清除浮動(dòng)

清除浮動(dòng)主要是為了解決父元素因?yàn)樽釉馗?dòng)引起的內(nèi)部高度為0的問題。 常見清除浮動(dòng)的方法額外標(biāo)簽法。在最后浮動(dòng)元素后加一個(gè)標(biāo)簽,設(shè)置clear:both;給父級(jí)元素設(shè)置高度給父級(jí)元素添加浮動(dòng)給父級(jí)元素設(shè)置overflow屬性為hidden或者auto使用after偽元素清除.clearfix:after {/*偽元素是行內(nèi)元素 正常瀏覽器清除浮動(dòng)方法*/content: "";display: block;height: 0;clear: both;visibility: hidden;}/*ie6清除浮動(dòng)的方式 *號(hào)只有IE6-IE7執(zhí)行,其他瀏覽器不執(zhí)行*/.clearfix {*zoom: 1;}使用after和before雙偽元素清除.clearfix:before,.clearfix:after {content: "";display: block;clear: both;}.clearfix {zoom: 1;}

CSS3transition過渡和animation動(dòng)畫的區(qū)別

animation屬性類似于transition,他們都是隨著時(shí)間改變?cè)氐膶傩灾?#xff0c;其主要區(qū)別在于: transition需要觸發(fā)一個(gè)事件才會(huì)隨著時(shí)間改變其CSS屬性; animation在不需要觸發(fā)任何事件的情況下,也可以顯式的隨時(shí)間變化來改變?cè)谻SS屬性,達(dá)到一種動(dòng)畫的效果1)動(dòng)畫不需要事件觸發(fā),過渡需要。 2)過渡只有一組(兩個(gè):開始-結(jié)束) 關(guān)鍵幀,動(dòng)畫可以設(shè)置多個(gè)。

前后端開發(fā)中數(shù)據(jù)是怎么交互的

web后端和前端是怎么連接的?網(wǎng)站數(shù)據(jù)處理主要分為三層。 第一層,表示層,這部分可以用HTML代碼,CSS/Javascript代碼來實(shí)現(xiàn)等。通過前端代碼可以實(shí)現(xiàn)網(wǎng)頁的布局和設(shè)計(jì)。這層又可以稱為顯示層。也就是你用瀏覽器打開能看到的網(wǎng)頁。 第二層,是業(yè)務(wù)層,這層是負(fù)責(zé)處理數(shù)據(jù)的。常用的代碼語言有PHP,JSP,Java等。通過這些后臺(tái)處理語言的算法來處理前臺(tái)傳回的數(shù)據(jù)。必要的時(shí)候進(jìn)行操作數(shù)據(jù)庫,然后把結(jié)果返回給前端網(wǎng)頁。 第三層,是數(shù)據(jù)層,這個(gè)就是數(shù)據(jù)庫,用來存儲(chǔ)數(shù)據(jù)的。通過業(yè)務(wù)層的操作可以實(shí)現(xiàn)增刪改數(shù)據(jù)庫的操作。在網(wǎng)頁上填一個(gè)表格然后提交會(huì)有以下幾種數(shù)據(jù)傳輸經(jīng)過: ①你接觸到的是這個(gè)網(wǎng)頁是屬于表示層,這個(gè)網(wǎng)頁一般由HTML標(biāo)簽結(jié)合CSS/JAVASCRIPT來實(shí)現(xiàn)的。這時(shí)候你要先填入數(shù)據(jù)。 ②然后你按提交觸發(fā)后臺(tái)處理機(jī)制,這時(shí)候數(shù)據(jù)會(huì)傳到后臺(tái)的代碼進(jìn)行處理。這部分代碼根據(jù)不同網(wǎng)站可以使PHP,JSP,JAVA等。代碼根據(jù)程序員預(yù)設(shè)的算法將收到的數(shù)據(jù)進(jìn)行處理之后會(huì)相應(yīng)的對(duì)數(shù)據(jù)庫進(jìn)行操作,存儲(chǔ)數(shù)據(jù)等。 ③成功操作完數(shù)據(jù)庫之后,業(yè)務(wù)層的代碼會(huì)再向表示層也就是顯示器端傳回一個(gè)指令通知你表格填寫成功從前端向后臺(tái)傳遞參數(shù)方法一、通過表單傳遞參數(shù) 1.前端部分,在前端jsp頁面設(shè)置form表單,確定需要傳遞的參數(shù)name讓用戶輸入,通過點(diǎn)擊按鈕后submit()提交到后臺(tái) 2.后臺(tái)對(duì)前端請(qǐng)求的反應(yīng),接收數(shù)據(jù),處理數(shù)據(jù)以及返回?cái)?shù)據(jù)。二.通過ajax傳遞參數(shù)(有post和get寫法) 1.ajax是如何將前端數(shù)據(jù)傳到后臺(tái)的type: "POST",//type是ajax的方法url : "<%=path%>/resource/usermenus",//參數(shù)url,要把參數(shù)傳到什么地方data : {parentid:parentid,parentpath:parentpath},//傳遞什么數(shù)據(jù)success : function(data){//sucess表示,當(dāng)數(shù)據(jù)返回成功后要怎么做,返回的數(shù)據(jù)存儲(chǔ)在data 2.后臺(tái)對(duì)前端請(qǐng)求的反應(yīng),接收數(shù)據(jù) 3.前端接收到后端返回的數(shù)據(jù)進(jìn)行處理的

cookie的理解

cookie又叫會(huì)話跟蹤技術(shù),是由web服務(wù)器保存在用戶瀏覽器上的小文本文件,它可以記錄用戶ID、密碼、瀏覽過的網(wǎng)頁、停留的時(shí)間等信息。當(dāng)用戶再次來到該網(wǎng)站時(shí),網(wǎng)站通過讀取cookie,得知用戶相關(guān)信息,就可以做出相應(yīng)的動(dòng)作,如在頁面顯示歡迎用戶標(biāo)語,或者讓用戶不用輸入ID、密碼就直接登錄等等。如果用戶清理了cookie,那么用戶曾登錄過的網(wǎng)站信息就沒有了。優(yōu)點(diǎn)極高的擴(kuò)展性和可用性通過良好的編程,可以控制保存在cookie中的session對(duì)象的大小通過加密技術(shù)和安全傳輸技術(shù),減少cookie被破解的可能只在cookie中存放不敏感數(shù)據(jù),即使被盜也不會(huì)有重大的損失控制cookie的生命周期,使之不會(huì)永久有效。偷盜者可能拿到一個(gè)過期的cookie缺點(diǎn)cookie有數(shù)量和長度的限制。每個(gè)domain最多有20條cookie,長度不能超過4KB,否則會(huì)被裁掉。安全性問題。如果cookie被人攔截了,那個(gè)人就可以取得所有的session信息。即使加密也于事無補(bǔ),因?yàn)閿r截者不需要知道cookie的意義,他只需要原樣轉(zhuǎn)發(fā)就能達(dá)到目的。有些狀態(tài)不可能保存在客戶端。

輸入網(wǎng)址到呈現(xiàn)網(wǎng)頁發(fā)生的過程

a.域名解析DNS解析,每一臺(tái)連上網(wǎng)計(jì)算機(jī)都有一個(gè)唯一標(biāo)識(shí)即它的IP地址,DNS解析就將輸入的網(wǎng)址解析成IP地址。 DNS解析是一個(gè)遞歸查詢的過程,例如要解析“www.baidu.com”時(shí),過程如下:在本地域名服務(wù)器中查詢IP地址,未找到域名;本地域名服務(wù)器會(huì)向根域名服務(wù)器發(fā)送請(qǐng)求,未找到域名;本地域名服務(wù)器向.com頂級(jí)域名服務(wù)器發(fā)送請(qǐng)求,未找到域名;本地域名服務(wù)器向.baidu.com域名服務(wù)器發(fā)送請(qǐng)求,找到該域名,將相應(yīng)的IP返回給本地域名服務(wù)器;b.發(fā)起TCP連接的三次握手HTTP協(xié)議是使用TCP協(xié)議作為其傳輸層協(xié)議的,在拿到服務(wù)器的IP地址后,客戶端瀏覽器會(huì)與服務(wù)器建立TCP連接,該過程包括三次握手:第一次握手:建立連接時(shí),客戶端向服務(wù)端發(fā)送請(qǐng)求報(bào)文(SYN)第二次握手:服務(wù)器收到請(qǐng)求報(bào)文后,如同意連接,則向客戶端發(fā)送確認(rèn)報(bào)文(SYN/ACK)第三次握手:客戶端收到服務(wù)器的確認(rèn)后,再次向服務(wù)器發(fā)送確認(rèn)報(bào)文,完成連接(ACK) 三次握手主要是為了防止已經(jīng)失效的請(qǐng)求報(bào)文字段發(fā)送給服務(wù)器,浪費(fèi)資源。c.建立TCP連接后瀏覽器發(fā)起HTTP請(qǐng)求瀏覽器構(gòu)建HTTP請(qǐng)求報(bào)文,并通過TCP協(xié)議傳送到服務(wù)器的指定端口。HTTP請(qǐng)求報(bào)文一共有三個(gè)部分:報(bào)文首部(請(qǐng)求行+各種首部字段+其他)空行(它的作用是通過一個(gè)空行,告訴服務(wù)器請(qǐng)求頭部到此為止。)報(bào)文主體(應(yīng)被發(fā)送的數(shù)據(jù))通常并不一定要有報(bào)文主體d.服務(wù)端響應(yīng)http請(qǐng)求,返回響應(yīng)報(bào)文 HTTP響應(yīng)報(bào)文由四部分組成:響應(yīng)行、響應(yīng)頭、空行、響應(yīng)體 響應(yīng)行響應(yīng)行一般由協(xié)議版本、狀態(tài)碼及其描述組成響應(yīng)頭響應(yīng)頭用于描述服務(wù)器的基本信息,以及數(shù)據(jù)的描述,服務(wù)器通過這些數(shù)據(jù)的描述信息,可以通知客戶端如何處理等一會(huì)兒它回送的數(shù)據(jù)。 常見的響應(yīng)頭字段含義:Allow:服務(wù)器支持哪些請(qǐng)求方法(如GET、POST等)。Content-Encoding:文檔的編碼(Encode)方法。只有在解碼之后才可以得到Content-Type頭指定的內(nèi)容類型。利用gzip壓縮文檔能夠顯著地減少HTML文檔的下載時(shí)間。Java的GZIPOutputStream可以很方便地進(jìn)行g(shù)zip壓縮,但只有Unix上的Netscape和Windows上的IE4、IE5才支持它。因此,Servlet應(yīng)該通過查看Accept-Encoding頭(即request.getHeader(“Accept- Encoding”))檢查瀏覽器是否支持gzip,為支持gzip的瀏覽器返回經(jīng)gzip壓縮的HTML頁面,為其他瀏覽器返回普通頁面。Content-Length:表示內(nèi)容長度。只有當(dāng)瀏覽器使用持久HTTP連接時(shí)才需要這個(gè)數(shù)據(jù)。如果你想要利用持久連接的優(yōu)勢(shì),可以把輸出文檔寫入 ByteArrayOutputStram,完成后查看其大小,然后把該值放入Content-Length頭,最后通過byteArrayStream.writeTo(response.getOutputStream()發(fā)送內(nèi)容。Content- Type:表示后面的文檔屬于什么MIME類型。Servlet默認(rèn)為text/plain,但通常需要顯式地指定為text/html。由于經(jīng)常要設(shè)置 Content-Type,因此HttpServletResponse提供了一個(gè)專用的方法setContentType。Date:當(dāng)前的GMT時(shí)間,例如,Date:Mon,31Dec200104:25:57GMT。Date描述的時(shí)間表示世界標(biāo)準(zhǔn)時(shí),換算成本地時(shí)間,需要知道用戶所在的時(shí)區(qū)。你可以用setDateHeader來設(shè)置這個(gè)頭以避免轉(zhuǎn)換時(shí)間格式的麻煩。Expires:告訴瀏覽器把回送的資源緩存多長時(shí)間,-1或0則是不緩存。Last-Modified:文檔的最后改動(dòng)時(shí)間。客戶可以通過If-Modified-Since請(qǐng)求頭提供一個(gè)日期,該請(qǐng)求將被視為一個(gè)條件GET,只有改動(dòng)時(shí)間遲于指定時(shí)間的文檔才會(huì)返回,否則返回一個(gè)304(Not Modified)狀態(tài)。Last-Modified也可用setDateHeader方法來設(shè)置。Location:這個(gè)頭配合302狀態(tài)碼使用,用于重定向接收者到一個(gè)新URI地址。表示客戶應(yīng)當(dāng)?shù)侥睦锶ヌ崛∥臋n。Location通常不是直接設(shè)置的,而是通過HttpServletResponse的sendRedirect方法,該方法同時(shí)設(shè)置狀態(tài)代碼為302。Refresh:告訴瀏覽器隔多久刷新一次,以秒計(jì)。Server:服務(wù)器通過這個(gè)頭告訴瀏覽器服務(wù)器的類型。Server響應(yīng)頭包含處理請(qǐng)求的原始服務(wù)器的軟件信息。此域能包含多個(gè)產(chǎn)品標(biāo)識(shí)和注釋,產(chǎn)品標(biāo)識(shí)一般按照重要性排序。Servlet一般不設(shè)置這個(gè)值,而是由Web服務(wù)器自己設(shè)置。Set-Cookie:設(shè)置和頁面關(guān)聯(lián)的Cookie。Servlet不應(yīng)使用response.setHeader(“Set-Cookie”, …),而是應(yīng)使用HttpServletResponse提供的專用方法addCookie。Transfer-Encoding:告訴瀏覽器數(shù)據(jù)的傳送格式。WWW-Authenticate:客戶應(yīng)該在Authorization頭中提供什么類型的授權(quán)信息?在包含401(Unauthorized)狀態(tài)行的應(yīng)答中這個(gè)頭是必需的。例如,response.setHeader(“WWW-Authenticate”, “BASIC realm=\”executives\”“)。注意Servlet一般不進(jìn)行這方面的處理,而是讓W(xué)eb服務(wù)器的專門機(jī)制來控制受密碼保護(hù)頁面的訪問。注:設(shè)置應(yīng)答頭最常用的方法是HttpServletResponse的setHeader,該方法有兩個(gè)參數(shù),分別表示應(yīng)答頭的名字和值。和設(shè)置狀態(tài)代碼相似,設(shè)置應(yīng)答頭應(yīng)該在發(fā)送任何文檔內(nèi)容之前進(jìn)行。setDateHeader方法和setIntHeader方法專門用來設(shè)置包含日期和整數(shù)值的應(yīng)答頭,前者避免了把Java時(shí)間轉(zhuǎn)換為GMT時(shí)間字符串的麻煩,后者則避免了把整數(shù)轉(zhuǎn)換為字符串的麻煩。HttpServletResponse還提供了許多設(shè)置setContentType:設(shè)置Content-Type頭。大多數(shù)Servlet都要用到這個(gè)方法。setContentLength:設(shè)置Content-Length頭。對(duì)于支持持久HTTP連接的瀏覽器來說,這個(gè)函數(shù)是很有用的。addCookie:設(shè)置一個(gè)Cookie(Servlet API中沒有setCookie方法,因?yàn)閼?yīng)答往往包含多個(gè)Set-Cookie頭)。響應(yīng)體 響應(yīng)體就是響應(yīng)的消息體,如果是純數(shù)據(jù)就是返回純數(shù)據(jù),如果請(qǐng)求的是HTML頁面,那么返回的就是HTML代碼,如果是JS就是JS代碼,如此之類。e.瀏覽器頁面渲染解析文檔構(gòu)建DOM樹構(gòu)建渲染樹布局和繪制渲染樹f.斷開TCP連接第一次揮手:客戶端想分手,發(fā)送消息(FIN)給服務(wù)器第二次揮手:服務(wù)器通知客戶端已經(jīng)接受的揮手請(qǐng)求,返回確認(rèn)消息(ACK),但還沒做好分手準(zhǔn)備第三次揮手:服務(wù)器已經(jīng)做好分手準(zhǔn)備,通知客戶端(FIN)第四次揮手:客戶端發(fā)送消息給服務(wù)器(ACK),確認(rèn)分手,服務(wù)器關(guān)閉連接。

瀏覽器渲染原理及流程

1. 瀏覽器會(huì)將HTML解析成一個(gè)DOM樹,DOM 樹的構(gòu)建過程是一個(gè)深度遍歷過程:當(dāng)前節(jié)點(diǎn)的所有子節(jié)點(diǎn)都構(gòu)建好后才會(huì)去構(gòu)建當(dāng)前節(jié)點(diǎn)的下一個(gè)兄弟節(jié)點(diǎn)。2. 將CSS解析成 CSS Rule Tree 。3. 根據(jù)DOM樹和CSSOM來構(gòu)造 Rendering Tree。注意:Rendering Tree 渲染樹并不等同于 DOM 樹,因?yàn)橐恍┫馠eader或display:none的東西就沒必要放在渲染樹中了。4. 有了Render Tree,瀏覽器已經(jīng)能知道網(wǎng)頁中有哪些節(jié)點(diǎn)、各個(gè)節(jié)點(diǎn)的CSS定義以及他們的從屬關(guān)系。下一步操作稱之為layout,顧名思義就是計(jì)算出每個(gè)節(jié)點(diǎn)在屏幕中的位置。5. 再下一步就是繪制,即遍歷render樹,并使用UI后端層繪制每個(gè)節(jié)點(diǎn)。

瀏覽器本地存儲(chǔ)

HTML5中的Web Storage包含了兩種存儲(chǔ)方式,sessionStorage和localStorage。還有indexedDB(適用于存儲(chǔ)字典,人工AI)sessionStorage用于本地存儲(chǔ)一個(gè)會(huì)話中的數(shù)據(jù),這些數(shù)據(jù)只有在同一個(gè)會(huì)話中的頁面才能訪問并且當(dāng)會(huì)話結(jié)束后數(shù)據(jù)也隨之銷毀。因此,sessionStorage不是一種持久化的本地存儲(chǔ),僅僅是會(huì)話級(jí)別的存儲(chǔ)。localStorage用于持久化的本地存儲(chǔ),除非主動(dòng)刪除數(shù)據(jù),否則數(shù)據(jù)永遠(yuǎn)不會(huì)過期首先總的來說,三者都是用于持久化數(shù)據(jù)存儲(chǔ)的手段,都是存儲(chǔ)在瀏覽器端,且同源.localStorage和sessionStorage都是Web存儲(chǔ),大小5M左右,完全存儲(chǔ)在客戶端,它們是因?yàn)楸镜卮鎯?chǔ)數(shù)據(jù)而存在.cookies也是存儲(chǔ)在瀏覽器端的,大小不超過4k,由服務(wù)器端存儲(chǔ)在客戶端。localStorage屬于永久性存儲(chǔ),數(shù)據(jù)存儲(chǔ)量大,而sessionStorage屬于當(dāng)會(huì)話結(jié)束的時(shí)候,存儲(chǔ)的值會(huì)被清空,而cookie是通過設(shè)置過期時(shí)間來存儲(chǔ)的。

cookie,localStorage,sessionStorage區(qū)別

介紹 1.cookie又叫會(huì)話跟蹤技術(shù),是由web服務(wù)器保存在用戶瀏覽器上的小文本文件,它可以記錄用戶ID、密碼、瀏覽過的網(wǎng)頁、停留的時(shí)間等信息。當(dāng)用戶再次來到該網(wǎng)站時(shí),網(wǎng)站通過讀取cookie,得知用戶相關(guān)信息,如果用戶清理了cookie,那么用戶曾登錄過的網(wǎng)站信息就沒有了。 2.sessionStorage和localStorage是H5新增的本地存儲(chǔ)區(qū)別 1.存儲(chǔ)大小的不同localStorage的大小一般為5MsessionStorage的大小一般為5Mcookies的大小一般為4K 2.有效期不同:localStorage的有效期為永久有效,除非你進(jìn)行手動(dòng)刪除。sessionStorage在當(dāng)前會(huì)話下有效,關(guān)閉頁面或者瀏覽器時(shí)會(huì)被清空。cookies在設(shè)置的有效之前有效,當(dāng)超過有效期便會(huì)失效。 3.與服務(wù)器端的通信localStorage不參與服務(wù)器端的通信。sessionStorage不參與服務(wù)器端的通信。cookies參與服務(wù)器端通信,每次都會(huì)攜帶http的頭信息中。(如果使用cookie保存過多數(shù)據(jù)會(huì)帶來性能問題)應(yīng)用場景 1.因?yàn)榭紤]到每個(gè) HTTP 請(qǐng)求都會(huì)帶著 Cookie 的信息,比較常用的一個(gè)應(yīng)用場景就是判斷用戶是否登錄。針對(duì)登錄過的用戶,服務(wù)器端會(huì)在他登錄時(shí)往 Cookie 中插入一段加密過的唯一辨識(shí)單一用戶的辨識(shí)碼,下次只要讀取這個(gè)值就可以判斷當(dāng)前用戶是否登錄啦。曾經(jīng)還使用 Cookie 來保存用戶在電商網(wǎng)站的購物車信息,如今有了 localStorage,現(xiàn)在基本更加方便 2.sessionStorage:可以用來統(tǒng)計(jì)當(dāng)前頁面元素的點(diǎn)擊次數(shù)。 3.localStoragese:常用于長期登錄(判斷用戶是否已登錄),適合長期保存在本地的數(shù)據(jù)。sessionStorage:敏感賬號(hào)一次性登錄;登陸信息用cookie好還是localStorage好?1.建議登陸信息用 cookie。即設(shè)置過期時(shí)間的cookie,看法是 cookie 默認(rèn)會(huì)發(fā)送回到后端,這樣方便后端讀取,而使用localStorage,你需要在每次請(qǐng)求的時(shí)候,都手動(dòng)帶上這個(gè)信息,這大大增加了開發(fā)過程中帶來的困難,非常麻煩,而且還要手動(dòng)維護(hù)過期時(shí)間。2.cookie有時(shí)效,而localStorage如果不手動(dòng)清理則永久保存。3.如果要設(shè)置關(guān)閉網(wǎng)頁/標(biāo)簽就失效,請(qǐng)用SessionStorage。 這個(gè)類似你設(shè)置“不帶時(shí)間的cookie”。

hash值獲取方式

可以通過window.location.hash獲取hash值

document.write和innerHTML的區(qū)別

document.write會(huì)重繪整個(gè)頁面innerHTML重繪頁面的一部分

進(jìn)程和線程的區(qū)別

一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程線程的劃分尺度小于進(jìn)程,使得多線程程序的并發(fā)性高進(jìn)程在執(zhí)行過程中擁有獨(dú)立的內(nèi)存單元,而多個(gè)線程共享內(nèi)存,從而極大提高了程序的運(yùn)行效率每個(gè)獨(dú)立的線程有一個(gè)程序運(yùn)行的入口、順序執(zhí)行序列和程序的出口。但是線程不能夠獨(dú)立執(zhí)行,必須依存在應(yīng)用程序中,由應(yīng)用程序提供多個(gè)線程執(zhí)行控制 從邏輯角度來看,多線程的意義在于一個(gè)應(yīng)用程序中,有多個(gè)執(zhí)行部分可以同時(shí)執(zhí)行。但操作系統(tǒng)并沒有將多個(gè)線程看做多個(gè)獨(dú)立的應(yīng)用,來實(shí)現(xiàn)進(jìn)程的調(diào)度和管理以及資源分配。這就是進(jìn)程和線程的重要區(qū)別

babel原理

Babel 是一個(gè)通用的多功能 JavaScript 編譯器,但與一般編譯器不同的是它只是把同種語言的高版本規(guī)則轉(zhuǎn)換為低版本規(guī)則,而不是輸出另一種低級(jí)機(jī)器可識(shí)別的代碼,并且在依賴不同的拓展插件下可用于不同形式的靜態(tài)分析。(靜態(tài)分析:指在不需要執(zhí)行代碼的前提下對(duì)代碼進(jìn)行分析以及相應(yīng)處理的一個(gè)過程,主要應(yīng)用于語法檢查、編譯、代碼高亮、代碼轉(zhuǎn)換、優(yōu)化、壓縮等等)babel 做了什么 和編譯器類似,babel 的轉(zhuǎn)譯過程也分為三個(gè)階段,這三步具體是:1.解析 Parse 將代碼解析生成抽象語法樹( 即AST ),也就是計(jì)算機(jī)理解我們代碼的方式(擴(kuò)展:一般來說每個(gè) js 引擎都有自己的 AST,比如熟知的 v8,chrome 瀏覽器會(huì)把 js 源碼轉(zhuǎn)換為抽象語法樹,再進(jìn)一步轉(zhuǎn)換為字節(jié)碼或機(jī)器代碼),而 babel 則是通過 babylon 實(shí)現(xiàn)的 。簡單來說就是一個(gè)對(duì)于 JS 代碼的一個(gè)編譯過程,進(jìn)行了詞法分析與語法分析的過程。 2.轉(zhuǎn)換 Transform 對(duì)于 AST 進(jìn)行變換一系列的操作,babel 接受得到 AST 并通過 babel-traverse 對(duì)其進(jìn)行遍歷,在此過程中進(jìn)行添加、更新及移除等操作。 3.生成 Generate 將變換后的 AST 再轉(zhuǎn)換為 JS 代碼, 使用到的模塊是 babel-generator。而 babel-core 模塊則是將三者結(jié)合使得對(duì)外提供的API做了一個(gè)簡化。此外需要注意的是,babel 只是轉(zhuǎn)譯新標(biāo)準(zhǔn)引入的語法,比如ES6箭頭函數(shù):而新標(biāo)準(zhǔn)引入的新的原生對(duì)象,部分原生對(duì)象新增的原型方法,新增的 API 等(Proxy、Set 等), 這些事不會(huì)轉(zhuǎn)譯的,需要引入對(duì)應(yīng)的 polyfill 來解決。

DVA工作流程

總結(jié)

以上是生活随笔為你收集整理的web前端面经的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。