前端面試總結(jié)

廢話少說(shuō),本文分四個(gè)部分,css、js、知識(shí)點(diǎn)一、知識(shí)點(diǎn)二、React(部分問(wèn)題沒(méi)有給出答案,后續(xù)更新)

css面試問(wèn)題


一、垂直居中問(wèn)題

https://www.cnblogs.com/clj2017/p/9293363.html

1、設(shè)置行高

2、彈性布局(父元素設(shè)置display:flex;子元素設(shè)置align-slef:center)

3、偽元素

父元素設(shè)置:before

content:“”;

display:inline-block;

vertical-align:middle;

height:100%;

4:父元素設(shè)置display:table

子元素設(shè)置display:table-cell;

vertical-align:middle;

二、彈性布局

http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html

容器屬性、項(xiàng)目屬性

1、容器屬性

flex-direction:row | row-reverse | column? | column-reverse

決定項(xiàng)目的排列順序

flex-wrap:wrap | nowrap | wrap-reverse

是否換行

flex-flow:<flex-direction> | <flex-wrap>

flex-direction和flex-wrap簡(jiǎn)寫(xiě)形式

justify-content:flex-start | flex-end | center | space-between | space-around

項(xiàng)目在主軸上的對(duì)齊方式

align-items:flex-start | flex-end | center | baseline | stretch

項(xiàng)目在交叉軸的對(duì)齊方式

align-content:flex-start | flex-end | center | stretch | space-between | space-around

定義了多跟軸線的對(duì)齊方式 ,如果項(xiàng)目只有一根軸線,該屬性不起作用。

2、項(xiàng)目屬性

order

定義項(xiàng)目的排列順序,值越小排列越靠前,默認(rèn)為0.

flex-grow

定義項(xiàng)目的放大比例,默認(rèn)為0,即如果存在剩余空間也不放大

如果所有項(xiàng)目的flex-grow都為1,等分剩余空間。如果一個(gè)項(xiàng)目的flex-grow為2,其他項(xiàng)目的flex-grow都為1,前者占用的剩余空間將比其他項(xiàng)多一倍。

flex-shrink

定義項(xiàng)目的縮小比例,默認(rèn)為1,即如果空間不足,該項(xiàng)目將縮小

flex-basis

分配多余空間之前項(xiàng)目占據(jù)的主軸空間

flex

flex-grow | flex-shrink | flex-basis的簡(jiǎn)寫(xiě)。

align-self:auto | flex-start | flex-end | center | baseline | stretch

單個(gè)項(xiàng)目在交叉的對(duì)齊方式,可與其他項(xiàng)目不一樣

三、BFC

https://blog.csdn.net/sinat_36422236/article/details/88763187

1、定義:塊級(jí)格式化上下文

2、觸發(fā)BFC的條件

⑴浮動(dòng)

⑵position:absolute fixed

⑶display:inline-block | table-cell | flex |

⑷overflow:hidden | scroll | auto

3、BFC解決的問(wèn)題

(1)避免margin重疊

(2)解決浮動(dòng)重疊

(3)解決高度塌陷問(wèn)題

四、清除浮動(dòng)的方式

清除浮動(dòng)主要是為了解決父級(jí)元素因?yàn)樽蛹?jí)浮動(dòng)引起的內(nèi)部高度為0的問(wèn)題。

1、額外標(biāo)簽

在父元素下寫(xiě)一個(gè)標(biāo)簽:用clear:both

2、overflow:hidden;觸發(fā)bfc

3、偽元素:after{clear:both;content:"";display:block;}


js

一、解決浮點(diǎn)數(shù)計(jì)算問(wèn)題

const floatAdd = (arg1, arg2) => {

? var r1, r2, m;

? r1 = arg1.toString().split(".")[1].length;

? r2 = arg2.toString().split(".")[1].length;

? m = Math.pow(10, Math.max(r1, r2));

? var rs = (arg1 * m + arg2 * m) / m;

? console.log(rs);

? return rs;

};

二、數(shù)組扁平化

1、遞歸

2、轉(zhuǎn)化為字符串

var rs = [1, 2, 3, [4, 5, [8, 78], 6]]

? .toString()

? .split(",")

? .map(item => {

? ? return Number(item);

? });

console.log(rs);

三、兩個(gè)數(shù)組求交集

function intersection(arr1,arr2){

return arr1.filter(item=>{

if(arr2.indexOf(item)>-1){

return item

}

})

}

四、數(shù)組去重

var arr2 = [2, 1, 3, 1];

var arr3 = [];

arr2.map(item => {

? if (arr3.indexOf(item) == -1) {

? ? arr3.push(item);

? }

});

console.log(arr3);

五、深拷貝和淺拷貝

淺拷貝方法

1、展開(kāi)運(yùn)算符 ...

2、Object.assign({},對(duì)象)

深拷貝方法

1、JSON.parse(JSON.stringify(對(duì)象))

該方法有局限性

會(huì)忽略u(píng)ndefined

會(huì)忽略symbol

不能序列化函數(shù)

不能解決循環(huán)引用的對(duì)象

2、遞歸

function deepClone(obj) {

? //判斷是否為引用類型

? function isobj(o) {

? ? return (typeof o == "object" || typeof o == "function") && o !== null;

? }

? if (!isobj(obj)) {

? ? throw new Error("非對(duì)象");

? }

? //判斷是否為數(shù)組,是的話解構(gòu)數(shù)組否則結(jié)構(gòu)對(duì)象

? let isArray = Array.isArray(obj);

? let newobj = isArray ? [...obj] : { ...obj };

? Object.keys(newobj).forEach(item => {

? ? newobj[item] = isobj(newobj[item]) ? deepClone(newobj[item]) : newobj[item];

? });

? return newobj;

}

六、繼承

1、原型繼承(通過(guò)prototype)

function Parent(name, age) {

? this.name = "小頭爸爸";

? this.age = 40;

}

function Child() {}

Child.prototype = new Parent();

var child = new Child();

console.log(child.name);

2、構(gòu)造函數(shù)繼承()

function Parent(name) {

? this.name = name;

? this.age = 40;

}

function Child(name) {

? Parent.call(this, name);

}

var child = new Child("大頭兒子");

console.log(child.name);

console.log(child.age);

3、組合繼承

function Box(age) {

this.name = ['Lee', 'Jack', 'Hello']

this.age = age;

}

Box.prototype.run = function () {

return this.name + this.age;

};

function Desk(age) {

Box.call(this, age); //對(duì)象冒充

}

Desk.prototype = new Box(); //原型鏈繼承

var desk = new Desk(100);

alert(desk.run());

4、class繼承

class Parent {

? constructor(value) {

? ? this.value = value;

? }

? getvalue() {

? ? console.log(this.value);

? }

}

class Child extends Parent {

? constructor(value) {

? ? super(value);

? ? this.value = value;

? }

}

let child = new Child(1);

child.getvalue();

組合繼承優(yōu)點(diǎn)是可以用構(gòu)造函數(shù)傳參,可以復(fù)用父類的函數(shù),不會(huì)與父類引用屬性共享,

缺點(diǎn)是子類原型上多了不需要的父類屬性

七、手寫(xiě)call、apply、bind

//手寫(xiě)call、apply、bind

//?Function.prototype.mycall?=?function(context)?{

//???if?(typeof?this?!==?"function")?{

//?????throw?new?TypeError("Error");

//???}

//???context?=?context?||?window;

//???context.fn?=?this;

//???let?args?=?[...arguments].slice(1);

//???let?result?=?context.fn(...args);

//???delete?context.fn;

//???return?result;

//?};

//?function?demo(num1,?num2)?{

//???let?rs?=?num1?+?num2;

//???console.log(rs);

//???return?rs;

//?}

//?demo.mycall(this,?1,?2);

//手寫(xiě)apply

//?Function.prototype.myapply?=?function(context)?{

//???if?(typeof?this?!==?"function")?{

//?????throw?new?Error("Error");

//???}

//???context?=?context?||?window;

//???context.fn?=?this;

//???let?result;

//???if?(arguments[1])?{

//?????result?=?context.fn(...arguments[1]);

//???}?else?{

//?????result?=?context.fn();

//???}

//???delete?context.fn;

//???return?result;

//?};

//?function?demo(num1,?num2)?{

//???let?rs?=?num1?+?num2;

//???console.log(rs);

//???return?rs;

//?}

//?demo.myapply(this,?[1,?2]);

//手寫(xiě)bind

Function.prototype.mybind?=?function(context)?{

??if?(typeof?this?!==?"function")?{

????throw?new?Error("Error");

??}

??console.log(arguments?instanceof?Object);

??let?args?=?[...arguments].slice(1);

??let?self?=?this;

??return?function?F()?{

????if?(this?instanceof?F)?{

??????return?new?self(...args,?...arguments);

????}?else?{

??????return?self.apply(context,?args.concat(...arguments));

????}

??};

};

function?demo(num1,?num2)?{

??let?rs?=?num1?+?num2;

??console.log(rs);

??return?rs;

}

demo.mybind(this,?1)(3,?6);

八、一個(gè)按鈕掛載兩個(gè)onclick事件

1、寫(xiě)兩個(gè).addEventListener(click,fn1 )

addEventListener(click,fn2)

2、寫(xiě)onclick=“fn1();n2()”


知識(shí)點(diǎn)1


一、http緩存

二、git常用命令

三、axios? 攔截器作用 底層原理

axios是什么

axios是基于promise機(jī)制實(shí)現(xiàn)的異步鏈?zhǔn)秸?qǐng)求框架,體積小。

底層原理:promise+ajax

基本api

axios.get()get請(qǐng)求 獲取數(shù)據(jù)

axios.post()post請(qǐng)求 提交數(shù)據(jù)

axios.put()put請(qǐng)求 更新數(shù)據(jù)

axios.delete() 刪除數(shù)據(jù)

用法

對(duì)象使用:axios.get('url',params).then(response=>{

console.log(response)

})

函數(shù)使用:axios({

url:"url",

method:"method",

headers:?{'X-Requested-With':?'XMLHttpRequest'},

}).then((res)=>{console.log(err)}).catch((err)=>{console.log(err)})

axios.defaults.baseURL?=?'https://api.example.com';(設(shè)置基礎(chǔ)路徑)

axios.interceptors.request.use()請(qǐng)求攔截器

axios.interceptors.response.use()響應(yīng)攔截器

用法:

axios.interceptors.request.use((config)=>{

return config

},(error)=>{

return promise.reject(error)

})//兩種攔截器用法一樣。

token怎么從后端獲取

四、優(yōu)化

1、圖片優(yōu)化

⑴很多裝飾類的用css去完成。

⑵雪碧圖

⑶小圖使用base64格式

⑷選擇正確的格式

能使用webp就使用webp(webp兼容性不好,很多瀏覽器不支持)

小圖使用PNG,大部分圖標(biāo)可以用SVG代替

照片使用JPEG

2、DNS預(yù)解析

DNS解析也是需要時(shí)間的,可以通過(guò)預(yù)解析的方式來(lái)預(yù)先獲得域名

<link rel="dns-prefetch" href="http://域名">

3、節(jié)流

如果滾動(dòng)事件會(huì)發(fā)起網(wǎng)絡(luò)請(qǐng)求,我們不希望用戶在滾動(dòng)中一直發(fā)送網(wǎng)絡(luò)請(qǐng)求,而是而一段時(shí)間發(fā)送一次,對(duì)于這種情況我們可以使用節(jié)流

實(shí)現(xiàn)的主要思路:就是將當(dāng)前時(shí)間和上一次執(zhí)行時(shí)間作對(duì)比,如果差值大于設(shè)置的等待時(shí)間就執(zhí)行函數(shù)。

4、防抖

點(diǎn)擊按鈕會(huì)觸發(fā)網(wǎng)絡(luò)請(qǐng)求,我們不希望每次點(diǎn)擊都會(huì)觸發(fā)網(wǎng)絡(luò)請(qǐng)求,而是用戶點(diǎn)擊按鈕一段時(shí)間后沒(méi)有再次點(diǎn)擊的情況才去發(fā)起網(wǎng)絡(luò)請(qǐng)求,對(duì)于這種情況我們可以使用防抖。

// func是用戶傳入需要防抖的函數(shù)// wait是等待時(shí)間const debounce = (func, wait = 50) => {

? // 緩存一個(gè)定時(shí)器id? let timer = 0? // 這里返回的函數(shù)是每次用戶實(shí)際調(diào)用的防抖函數(shù)? // 如果已經(jīng)設(shè)定過(guò)定時(shí)器了就清空上一次的定時(shí)器? // 開(kāi)始一個(gè)新的定時(shí)器,延遲執(zhí)行用戶傳入的方法? return function(...args) {

? ? if (timer) clearTimeout(timer)

? ? timer = setTimeout(() => {

? ? ? func.apply(this, args)

? ? }, wait)

? }

}

5、預(yù)加載

有些資源不需要馬上用到,但是需要盡早獲取,這時(shí)候可以用到預(yù)加載

預(yù)加載其實(shí)是聲明式的fetch,強(qiáng)制瀏覽器請(qǐng)求資源,并且不會(huì)阻塞onload事件,可以使用以下代碼實(shí)現(xiàn)預(yù)加載

<link rel="preload" href="資源">

優(yōu)點(diǎn):降低首屏加載時(shí)間,缺點(diǎn)是兼容性不好

6、預(yù)渲染

可以通過(guò)預(yù)渲染將下載的文件在后臺(tái)渲染

實(shí)現(xiàn):<link rel="prerender" href="資源">

預(yù)渲染雖然可以提高頁(yè)面的加載速度,但是要確保該頁(yè)面大概率會(huì)被用戶在之后打開(kāi),否則就是白白浪費(fèi)資源去渲染。

7、懶執(zhí)行

將某些邏輯使用時(shí)在計(jì)算。該技術(shù)可以用于首屏優(yōu)化,一般可以通過(guò)定時(shí)器或者事件調(diào)用來(lái)喚醒

8、懶加載

將不關(guān)鍵的資源延后加載

原理是只加載可視區(qū)域

五、當(dāng)瀏覽器輸入url之后

https://www.cnblogs.com/confach/p/10050013.html

DNS查詢

TCP連接

發(fā)送HTTP請(qǐng)求

Server處理HTTP請(qǐng)求并返回HTTP報(bào)文

瀏覽器解析并render頁(yè)面

HTTP連接斷開(kāi)

六、forEach和map的區(qū)別

1、返回值不一樣,forEach返回值是undefined,map返回值是一個(gè)新的數(shù)組

2、forEach不可中斷,除非拋出異常。

七、this指向問(wèn)題

1、定時(shí)器的this指向問(wèn)題

setTimeout(function(){

console.log(this.name)

},1000)

一般情況下如果在定時(shí)器內(nèi)部使用普通函數(shù),this指向window

改變this指向的方法

⑴that綁定this

⑵使用bind,bind方法返回一個(gè)新函數(shù),call和apply立即執(zhí)行函數(shù),所以只能使用bind方法,否則就失去了定時(shí)器的作用

⑶使用箭頭函數(shù),箭頭函數(shù)沒(méi)有this指向,它的this是繼承外部的作用域。

2、如果直接調(diào)用函數(shù),函數(shù)不管放在哪個(gè)地方,this指向都是window

3、如果對(duì)象調(diào)用函數(shù),this指向被調(diào)用的對(duì)象

4、對(duì)于new的方式,this永遠(yuǎn)綁定在實(shí)例化對(duì)象上,不可改變。

5、箭頭函數(shù)沒(méi)有this指向,它的this是繼承外部的作用域。

八、webpack相關(guān)內(nèi)容

webpack相關(guān)內(nèi)容https://www.runoob.com/w3cnote/es6-setup.html

webpack功能:

1將sass/less 等預(yù)編譯的css語(yǔ)言轉(zhuǎn)換成瀏覽器識(shí)別的css文件

2能夠?qū)⒍鄠€(gè)預(yù)編譯文件打包成一個(gè)文件

3 打包image/styles/assets/scrips/等前端常用的文件

4 搭建開(kāi)發(fā)環(huán)境開(kāi)啟服務(wù)器

5 監(jiān)視文件改動(dòng),熱部署。

webpack構(gòu)建過(guò)程

從entry里配置的module開(kāi)始遞歸解析entry依賴的所有module

每找到一個(gè)module,就會(huì)根據(jù)配置的loader去找對(duì)應(yīng)的轉(zhuǎn)換規(guī)則

對(duì)module進(jìn)行轉(zhuǎn)換后,再解析出當(dāng)前module依賴的module

這些模塊會(huì)以entry為單位分組,一個(gè)entry和其所有依賴的module被分到一個(gè)組Chunk

最后webpack會(huì)把所有Chunk轉(zhuǎn)換成文件輸出

在整個(gè)流程中webpack會(huì)在恰當(dāng)?shù)臅r(shí)機(jī)執(zhí)行plugin里定義的邏輯

webpack打包原理

將所有依賴打包成一個(gè)bundle.js,通過(guò)代碼分割成單元片段按需加載

什么是entry,output?

entry 入口,告訴webpack要使用哪個(gè)模塊作為構(gòu)建項(xiàng)目的起點(diǎn),默認(rèn)為./src/index.js

output 出口,告訴webpack在哪里輸出它打包好的代碼以及如何命名,默認(rèn)為./dist

什么是loader,plugins?

loader是用來(lái)告訴webpack如何轉(zhuǎn)換某一類型的文件,并且引入到打包出的文件中。

plugins(插件)作用更大,可以打包優(yōu)化,資源管理和注入環(huán)境變量

什么是bundle,chunk,module?

bundle是webpack打包出來(lái)的文件,chunk是webpack在進(jìn)行模塊的依賴分析的時(shí)候,代碼分割出來(lái)的代碼塊。module是開(kāi)發(fā)中的單個(gè)模塊

如何利用webpack來(lái)優(yōu)化前端性能

1. 壓縮代碼。uglifyJsPlugin 壓縮js代碼, mini-css-extract-plugin 壓縮css代碼

2. 利用CDN加速,將引用的靜態(tài)資源修改為CDN上對(duì)應(yīng)的路徑,可以利用webpack對(duì)于output參數(shù)和loader的publicpath參數(shù)來(lái)修改資源路徑

3. 刪除死代碼(tree shaking),css需要使用Purify-CSS

4. 提取公共代碼。webpack4移除了CommonsChunkPlugin (提取公共代碼),用optimization.splitChunks和optimization.runtimeChunk來(lái)代替

補(bǔ)充CDN

CDN(Content Delivery Network)是指內(nèi)容分發(fā)網(wǎng)絡(luò),也稱為內(nèi)容傳送網(wǎng)絡(luò),在現(xiàn)有互聯(lián)網(wǎng)基礎(chǔ)上建立一個(gè)內(nèi)容分發(fā)平臺(tái)專門(mén)為網(wǎng)站提供服務(wù),是為加快網(wǎng)絡(luò)訪問(wèn)速度而被優(yōu)化的網(wǎng)絡(luò)覆蓋層,

原理

CDN的基本原理是廣泛采用各種緩存服務(wù)器,將這些緩存服務(wù)器分布到用戶訪問(wèn)相對(duì)集中的地區(qū)或網(wǎng)絡(luò)中,在用戶訪問(wèn)網(wǎng)站時(shí),利用全局負(fù)載技術(shù)將用戶的訪問(wèn)指向距離最近的工作正常的緩存服務(wù)器上,由緩存服務(wù)器直接響應(yīng)用戶請(qǐng)求


知識(shí)點(diǎn)2


一、websocket介紹:https://www.liaoxuefeng.com/wiki/1022910821149312/1103303693824096

websocket簡(jiǎn)單介紹

http://www.itdecent.cn/p/970dcfd174dc

二、koa

Koa 是一個(gè)新的 web 框架,由 Express 幕后的原班人馬打造, 致力于成為 web 應(yīng)用和 API 開(kāi)發(fā)領(lǐng)域中的一個(gè)更小、更富有表現(xiàn)力、更健壯的基石。 通過(guò)利用 async 函數(shù),Koa 幫你丟棄回調(diào)函數(shù),并有力地增強(qiáng)錯(cuò)誤處理。 Koa 并沒(méi)有捆綁任何中間件, 而是提供了一套優(yōu)雅的方法,幫助您快速而愉快地編寫(xiě)服務(wù)端應(yīng)用程序。

三、express

基于nodejs的web開(kāi)發(fā)框架

四、nginx

Nginx?(engine x) 是一個(gè)高性能的HTTP反向代理web服務(wù)器,特點(diǎn)是占有內(nèi)存少,并發(fā)能力強(qiáng),事實(shí)上nginx的并發(fā)能力在同類型的網(wǎng)頁(yè)服務(wù)器中表現(xiàn)較好,中國(guó)大陸使用nginx網(wǎng)站用戶有:百度、京東、新浪、網(wǎng)易、騰訊、淘寶等。

功能:

Nginx是一個(gè)HTTP服務(wù)器,可以將服務(wù)器上的靜態(tài)文件(如HTML、圖片)通過(guò)HTTP協(xié)議展現(xiàn)給客戶端

可以實(shí)現(xiàn)負(fù)載均衡、虛擬主機(jī)

什么是負(fù)載均衡

當(dāng)網(wǎng)站訪問(wèn)量非常大,網(wǎng)站站長(zhǎng)開(kāi)心賺錢(qián)的同時(shí),也攤上事兒了。因?yàn)榫W(wǎng)站越來(lái)越慢,一臺(tái)服務(wù)器已經(jīng)不夠用了。于是將同一個(gè)應(yīng)用部署在多臺(tái)服務(wù)器上,將大量用戶的請(qǐng)求分配給多臺(tái)機(jī)器處理。同時(shí)帶來(lái)的好處是,其中一臺(tái)服務(wù)器萬(wàn)一掛了,只要還有其他服務(wù)器正常運(yùn)行,就不會(huì)影響用戶使用。

Nginx可以通過(guò)反向代理來(lái)實(shí)現(xiàn)負(fù)載均衡。

虛擬主機(jī)

有的網(wǎng)站訪問(wèn)量大,需要負(fù)載均衡。然而并不是所有網(wǎng)站都如此出色,有的網(wǎng)站,由于訪問(wèn)量太小,需要節(jié)省成本,將多個(gè)網(wǎng)站部署在同一臺(tái)服務(wù)器上。

例如將www.aaa.com和www.bbb.com兩個(gè)網(wǎng)站部署在同一臺(tái)服務(wù)器上,兩個(gè)域名解析到同一個(gè)IP地址,但是用戶通過(guò)兩個(gè)域名卻可以打開(kāi)兩個(gè)完全不同的網(wǎng)站,互相不影響,就像訪問(wèn)兩個(gè)服務(wù)器一樣,所以叫兩個(gè)虛擬主機(jī)。

五、nodejs

Node.js 是一個(gè)基于 Chrome V8 引擎的?JavaScript?運(yùn)行環(huán)境。 Node.js 使用了一個(gè)事件驅(qū)動(dòng)、非阻塞式 I/O 的模型。?[1]?

Node 是一個(gè)讓 JavaScript 運(yùn)行在服務(wù)端的開(kāi)發(fā)平臺(tái),它讓 JavaScript 成為與PHPPython、Perl、Ruby?等服務(wù)端語(yǔ)言平起平坐的腳本語(yǔ)言。

特點(diǎn):

單線程

Node可以在不新增額外線程的情況下,依然可以對(duì)任務(wù)進(jìn)行并發(fā)處理 —— Node.js是單線程的。它通過(guò)事件循環(huán)(event loop)來(lái)實(shí)現(xiàn)并發(fā)操作,對(duì)此,我們應(yīng)該要充分利用這一點(diǎn) —— 盡可能的避免阻塞操作,取而代之,多使用非阻塞操作。

非阻塞IO

V8虛擬機(jī)

事件驅(qū)動(dòng)

六、事件驅(qū)動(dòng)

所謂事件驅(qū)動(dòng),簡(jiǎn)單地說(shuō)就是你點(diǎn)什么按鈕(即產(chǎn)生什么事件),電腦執(zhí)行什么操作(即調(diào)用什么函數(shù)).當(dāng)然事件不僅限于用戶的操作. 事件驅(qū)動(dòng)的核心自然是事件。從事件角度說(shuō),事件驅(qū)動(dòng)程序的基本結(jié)構(gòu)是由一個(gè)事件收集器、一個(gè)事件發(fā)送器和一個(gè)事件處理器組成。事件收集器專門(mén)負(fù)責(zé)收集所有事件,包括來(lái)自用戶的(如鼠標(biāo)、鍵盤(pán)事件等)、來(lái)自硬件的(如時(shí)鐘事件等)和來(lái)自軟件的(如操作系統(tǒng)、應(yīng)用程序本身等)。事件發(fā)送器負(fù)責(zé)將收集器收集到的事件分發(fā)到目標(biāo)對(duì)象中。事件處理器做具體的事件響應(yīng)工作,它往往要到實(shí)現(xiàn)階段才完全確定,因而需要運(yùn)用虛函數(shù)機(jī)制(函數(shù)名往往取為類似于HandleMsg的一個(gè)名字)。對(duì)于框架的使用者來(lái)說(shuō),他們唯一能夠看到的是事件處理器。這也是他們所關(guān)心的內(nèi)容

七、非阻塞i/o

非阻塞I/O是指以異步來(lái)執(zhí)行函數(shù),先執(zhí)行同步任務(wù),耗時(shí)任務(wù)放在事件隊(duì)列中,以此輪詢執(zhí)行。

八、webpack和gulp

二者比較

gulp它是基于流的自動(dòng)化構(gòu)建工具。有task處理機(jī)制,入口是src,通過(guò)管道pipe打包文件。配置文件是gulpfile.js

webpack的兩大特點(diǎn):1模塊化 2打包。Webpack實(shí)現(xiàn)了模塊化開(kāi)發(fā)和文件處理。它能夠?qū)⒏鱾€(gè)模塊進(jìn)行按需加載,不會(huì)導(dǎo)致加載了無(wú)用或冗余的代碼。配置文件webpack.config.js

功能:

1將sass/less 等預(yù)編譯的css語(yǔ)言轉(zhuǎn)換成瀏覽器識(shí)別的css文件

2能夠?qū)⒍鄠€(gè)預(yù)編譯文件打包成一個(gè)文件

3 打包image/styles/assets/scrips/等前端常用的文件

4 搭建開(kāi)發(fā)環(huán)境開(kāi)啟服務(wù)器

5 監(jiān)視文件改動(dòng),熱部署。

九、模塊化

模塊化的優(yōu)點(diǎn)

解決命名沖突

提供復(fù)用性

提高代碼可維護(hù)性

實(shí)現(xiàn):

CommonJs

隨著Javasript應(yīng)用進(jìn)軍服務(wù)器端,業(yè)界急需一種標(biāo)準(zhǔn)的模塊化解決方案,于是,CommonJS(www.commonjs.org)應(yīng)運(yùn)而生。它最初是由Kevin Dangoor在他的這篇博文中首次提出。

這是一種被廣泛使用的Javascript模塊化規(guī)范,大家最熟悉的Node.js應(yīng)用中就是采用這個(gè)規(guī)范。在Node.js中,內(nèi)置了module對(duì)象用來(lái)定義模塊, require函數(shù)用來(lái)加載模塊文件,代碼如下:

// utils.js 模塊定義var add = function(a, b) {

? ? return a + b;

};

module.exports = {

? ? add: add

};// 加載模塊var utils = require('./utils');console.log(utils.add(1, 2));

此種模塊化方案特點(diǎn)就是:同步阻塞式加載,無(wú)法實(shí)現(xiàn)按需異步加載。另外,如果想要在瀏覽器中使用CommonJS模塊就需要使用Browserify進(jìn)行解析:

npm install browserify -g

browserify utils.js > bundle.js

當(dāng)然,你也可以使用gulp, webpack等工具進(jìn)行解析打包后引入到瀏覽器頁(yè)面中去。

ES6 Modules

對(duì)于ES6來(lái)說(shuō),不必再使用閉包和封裝函數(shù)等方式進(jìn)行模塊化支持了。在ES6中,從語(yǔ)法層面就提供了模塊化的功能。然而受限于瀏覽器的實(shí)現(xiàn)程度,如果想要在瀏覽器中運(yùn)行,還是需要通過(guò)Babel等轉(zhuǎn)譯工具進(jìn)行編譯。ES6提供了import和export命令,分別對(duì)應(yīng)模塊的導(dǎo)入和導(dǎo)出功能。具體實(shí)例如下:

// demo-export.js 模塊定義var name = "scq000"var sayHello = (name) => {

? console.log("Hi," + name);

}export {name, sayHello};// demo-import.js 使用模塊import {sayHello} from "./demo-export";

sayHello("scq000");

對(duì)于具體的語(yǔ)法細(xì)節(jié),想必大家在日常使用過(guò)程中都已經(jīng)輕車(chē)熟路了。但對(duì)于ES6模塊化來(lái)說(shuō),有以下幾點(diǎn)特性是需要記住的:

ES6使用的是基于文件的模塊。所以必須一個(gè)文件一個(gè)模塊,不能將多個(gè)模塊合并到單個(gè)文件中去。

ES6模塊API是靜態(tài)的,一旦導(dǎo)入模塊后,無(wú)法再在程序運(yùn)行過(guò)程中增添方法。

ES6模塊采用引用綁定(可以理解為指針)。這點(diǎn)和CommonJS中的值綁定不同,如果你的模塊在運(yùn)行過(guò)程中修改了導(dǎo)出的變量值,就會(huì)反映到使用模塊的代碼中去。所以,不推薦在模塊中修改導(dǎo)出值,導(dǎo)出的變量應(yīng)該是靜態(tài)的。

ES6模塊采用的是單例模式,每次對(duì)同一個(gè)模塊的導(dǎo)入其實(shí)都指向同一個(gè)實(shí)例

Webpack中的模塊化方案

作為現(xiàn)代化的前端構(gòu)建工具,Webpack還提供了豐富的功能能夠使我們更加輕易地實(shí)現(xiàn)模塊化。利用Webpack,你不僅可以將Javascript文件進(jìn)行模塊化,同時(shí)還能針對(duì)圖片,css等靜態(tài)資源進(jìn)行模塊化。你可以在代碼里使用CommonJS, ES6等模塊化語(yǔ)法,打包的時(shí)候你也可以根據(jù)需求選擇打包類型,如UMD, AMD等:

module.exports = {

? //...

? output: {

? ? library: 'librayName',

? ? libraryTarget: 'umd', // 配置輸出格式

? ? filename: 'bundle.js'

? }

};

另外,ES6模塊好處很多,但是并不支持按需加載的功能, 而按需加載又是Web性能優(yōu)化中重要的一個(gè)環(huán)節(jié)。好在我們可以借助Webpack來(lái)彌補(bǔ)這一缺陷。Webpack v1版本提供了require.ensureAPI, 而2.x之后使用了import()函數(shù)來(lái)實(shí)現(xiàn)異步加載。具體的代碼示例可以查看我之前所寫(xiě)的前端性能優(yōu)化之加載技術(shù)?這篇文章。

十、mvvm mvc

PS:MVVM(Model-View-ViewModel), 源自于經(jīng)典的 Model–View–Controller(MVC)模式。MVVM 的出現(xiàn)促進(jìn)了 GUI 前端開(kāi)發(fā)與后端業(yè)務(wù)邏輯的分離,極大地提高了前端開(kāi)發(fā)效率。MVVM 的核心是 ViewModel 層,它就像是一個(gè)中轉(zhuǎn)站(value converter),負(fù)責(zé)轉(zhuǎn)換 Model 中的數(shù)據(jù)對(duì)象來(lái)讓數(shù)據(jù)變得更容易管理和使用,該層向上與視圖層進(jìn)行雙向數(shù)據(jù)綁定,向下與 Model 層通過(guò)接口請(qǐng)求進(jìn)行數(shù)據(jù)交互,起呈上啟下作用。View 層展現(xiàn)的不是 Model 層的數(shù)據(jù),而是 ViewModel 的數(shù)據(jù),由 ViewModel 負(fù)責(zé)與 Model 層交互,這就完全解耦了 View 層和 Model 層,這個(gè)解耦是至關(guān)重要的,它是前后端分離方案實(shí)施的最重要一環(huán)。

十一、ajax 、axios、fetch

Ajax

傳統(tǒng) Ajax 指的是 XMLHttpRequest(XHR), 最早出現(xiàn)的發(fā)送后端請(qǐng)求技術(shù),隸屬于原始js中,核心使用XMLHttpRequest對(duì)象,多個(gè)請(qǐng)求之間如果有先后關(guān)系的話,就會(huì)出現(xiàn)回調(diào)地獄。

JQuery ajax 是對(duì)原生XHR的封裝,除此以外還增添了對(duì)JSONP的支持。經(jīng)過(guò)多年的更新維護(hù),真的已經(jīng)是非常的方便了,;如果是硬要舉出幾個(gè)缺點(diǎn),那可能只有:

1.本身是針對(duì)MVC的編程,不符合現(xiàn)在前端MVVM的浪潮

2.基于原生的XHR開(kāi)發(fā),XHR本身的架構(gòu)不清晰。

3.JQuery整個(gè)項(xiàng)目太大,單純使用ajax卻要引入整個(gè)JQuery非常的不合理(采取個(gè)性化打包的方案又不能享受CDN服務(wù))

4.不符合關(guān)注分離(Separation of Concerns)的原則

5.配置和調(diào)用方式非?;靵y,而且基于事件的異步模型不友好。

PS:MVVM(Model-View-ViewModel), 源自于經(jīng)典的 Model–View–Controller(MVC)模式。MVVM 的出現(xiàn)促進(jìn)了 GUI 前端開(kāi)發(fā)與后端業(yè)務(wù)邏輯的分離,極大地提高了前端開(kāi)發(fā)效率。MVVM 的核心是 ViewModel 層,它就像是一個(gè)中轉(zhuǎn)站(value converter),負(fù)責(zé)轉(zhuǎn)換 Model 中的數(shù)據(jù)對(duì)象來(lái)讓數(shù)據(jù)變得更容易管理和使用,該層向上與視圖層進(jìn)行雙向數(shù)據(jù)綁定,向下與 Model 層通過(guò)接口請(qǐng)求進(jìn)行數(shù)據(jù)交互,起呈上啟下作用。View 層展現(xiàn)的不是 Model 層的數(shù)據(jù),而是 ViewModel 的數(shù)據(jù),由 ViewModel 負(fù)責(zé)與 Model 層交互,這就完全解耦了 View 層和 Model 層,這個(gè)解耦是至關(guān)重要的,它是前后端分離方案實(shí)施的最重要一環(huán)。

axios

axios 是一個(gè)基于Promise 用于瀏覽器和 nodejs 的 HTTP 客戶端,本質(zhì)上也是對(duì)原生XHR的封裝,只不過(guò)它是Promise的實(shí)現(xiàn)版本,符合最新的ES規(guī)范,它本身具有以下特征:

注:

1、從瀏覽器創(chuàng)建XMLHttpRequest

2、node.js發(fā)送http請(qǐng)求

3、支持promiseAPI

4、攔截請(qǐng)求和響應(yīng)

5、轉(zhuǎn)換請(qǐng)求和響應(yīng)

6、取消請(qǐng)求

7、JSON數(shù)據(jù)的自動(dòng)轉(zhuǎn)換

8、客戶端對(duì)防止XSRF的支持

PS:防止CSRF:就是讓你的每個(gè)請(qǐng)求都帶一個(gè)從cookie中拿到的key, 根據(jù)瀏覽器同源策略,假冒的網(wǎng)站是拿不到你cookie中得key的,這樣,后臺(tái)就可以輕松辨別出這個(gè)請(qǐng)求是否是用戶在假冒網(wǎng)站上的誤導(dǎo)輸入,從而采取正確的策略。

axios既提供了并發(fā)的封裝,而且體積也較小,當(dāng)之無(wú)愧現(xiàn)在最應(yīng)該選用的請(qǐng)求的方式。

fetch

fetch號(hào)稱是AJAX的替代品,是在ES6出現(xiàn)的,使用了ES6中的promise對(duì)象。Fetch是基于promise設(shè)計(jì)的。Fetch的代碼結(jié)構(gòu)比起ajax簡(jiǎn)單多了,參數(shù)有點(diǎn)像jQuery ajax。但是,一定記住fetch不是ajax的進(jìn)一步封裝,而是原生js,沒(méi)有使用XMLHttpRequest對(duì)象。

fetch的優(yōu)點(diǎn):

1.符合關(guān)注分離,沒(méi)有將輸入、輸出和用事件來(lái)跟蹤的狀態(tài)混雜在一個(gè)對(duì)象里

2.更好更方便的寫(xiě)法

坦白說(shuō),上面的理由對(duì)我來(lái)說(shuō)完全沒(méi)有什么說(shuō)服力,因?yàn)椴还苁荍query還是Axios都已經(jīng)幫我們把xhr封裝的足夠好,使用起來(lái)也足夠方便,為什么我們還要花費(fèi)大力氣去學(xué)習(xí)fetch?

我認(rèn)為fetch的優(yōu)勢(shì)主要優(yōu)勢(shì)就是:

1.? 語(yǔ)法簡(jiǎn)潔,更加語(yǔ)義化

2.? 基于標(biāo)準(zhǔn) Promise 實(shí)現(xiàn),支持 async/await

3.? 同構(gòu)方便,使用 [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch)

4.更加底層,提供的API豐富(request, response)

5.脫離了XHR,是ES規(guī)范里新的實(shí)現(xiàn)方式

十二、有關(guān)于異步的問(wèn)題

promise

是異步編程的一種解決方案。

從語(yǔ)法上說(shuō),Promise 是一個(gè)對(duì)象,從它可以獲取異步操作的消息。

Promise 狀態(tài)以及狀態(tài)的特點(diǎn)

Promise 異步操作有三種狀態(tài):pending(進(jìn)行中)、fulfilled(已成功)和 rejected(已失敗)。除了異步操作的結(jié)果,任何其他操作都無(wú)法改變這個(gè)狀態(tài)。

Promise 對(duì)象只有:從 pending 變?yōu)?fulfilled 和從 pending 變?yōu)?rejected 的狀態(tài)改變。只要處于 fulfilled 和 rejected ,狀態(tài)就不會(huì)再變了即 resolved(已定型)。

狀態(tài)的缺點(diǎn)

無(wú)法取消 Promise ,一旦新建它就會(huì)立即執(zhí)行,無(wú)法中途取消。

如果不設(shè)置回調(diào)函數(shù),Promise 內(nèi)部拋出的錯(cuò)誤,不會(huì)反應(yīng)到外部。

當(dāng)處于 pending 狀態(tài)時(shí),無(wú)法得知目前進(jìn)展到哪一個(gè)階段(剛剛開(kāi)始還是即將完成)。、

then 方法接收兩個(gè)函數(shù)作為參數(shù),第一個(gè)參數(shù)是 Promise 執(zhí)行成功時(shí)的回調(diào),第二個(gè)參數(shù)是 Promise 執(zhí)行失敗時(shí)的回調(diào),兩個(gè)函數(shù)只會(huì)有一個(gè)被調(diào)用。

generator

yield是ES6的新關(guān)鍵字,使生成器函數(shù)執(zhí)行暫停,yield關(guān)鍵字后面的表達(dá)式的值返回給生成器的調(diào)用者。它可以被認(rèn)為是一個(gè)基于生成器的版本的return關(guān)鍵字。

yield關(guān)鍵字實(shí)際返回一個(gè)IteratorResult(迭代器)對(duì)象,它有兩個(gè)屬性,value和done,分別代表返回值和是否完成。

yield無(wú)法單獨(dú)工作,需要配合generator(生成器)的其他函數(shù),如next,懶漢式操作,展現(xiàn)強(qiáng)大的主動(dòng)控制特性。

function *gen() {

? ? yield 'hello';

? ? yield 'world';

? ? return true;

}

以上代碼定義了一個(gè)簡(jiǎn)單的 generator,看起來(lái)就像一個(gè)普通的函數(shù),區(qū)別是function關(guān)鍵字后面有個(gè)*號(hào),函數(shù)體內(nèi)可以使用yield語(yǔ)句進(jìn)行流程控制。

?var iter?=?gen();

?var a?= iter.next();

?console.log(a);?// {value:'hello', done:false}

?var b?= iter.next();

?console.log(b);?// {value:'world', done:false}

?var c?= iter.next();

?console.log(c);?// {value:true, done:true}

當(dāng)執(zhí)行g(shù)en()的時(shí)候,并不執(zhí)行 generator 函數(shù)體,而是返回一個(gè)迭代器。迭代器具有next()方法,每次調(diào)用 next() 方法,函數(shù)就執(zhí)行到y(tǒng)ield語(yǔ)句的地方。next() 方法返回一個(gè)對(duì)象,其中value屬性表示 yield 關(guān)鍵詞后面表達(dá)式的值,done 屬性表示是否遍歷結(jié)束。generator 生成器通過(guò)next和yield的配合實(shí)現(xiàn)流程控制,上面的代碼執(zhí)行了三次 next() ,generator 函數(shù)體才執(zhí)行完畢。

async

async 函數(shù)返回一個(gè) Promise 對(duì)象

function testAwait(){? return new Promise((resolve) => {? ? ? setTimeout(function(){? ? ? ? ? console.log("testAwait");

? ? ? ? ? resolve();

? ? ? }, 1000);

? });} async function helloAsync(){? await testAwait();

? console.log("helloAsync");

}helloAsync();// testAwait// helloAsync

await針對(duì)所跟不同表達(dá)式的處理方式:

Promise 對(duì)象:await 會(huì)暫停執(zhí)行,等待?Promise 對(duì)象 resolve,然后恢復(fù) async 函數(shù)的執(zhí)行并返回解析值。

非 Promise 對(duì)象:直接返回對(duì)應(yīng)的值。

十三、Object.keys()和Reflect.ownKeys()區(qū)別

Object.keys()返回屬性key,但不包括不可枚舉的屬性

Reflect.ownKeys()返回所有屬性key

他們兩個(gè)都不能遍歷原型上的屬性

擴(kuò)展

for in

for in一般用于遍歷對(duì)象的屬性;

作用于數(shù)組的for in除了會(huì)遍歷數(shù)組元素外,還會(huì)遍歷自定義可枚舉的屬性,以及原型鏈上可枚舉的屬性;

作用于數(shù)組的for in的遍歷結(jié)果是數(shù)組的索引,且都為字符串型,不能用于運(yùn)算;

某些情況下,可能按照隨機(jī)順序遍歷數(shù)組元素;

for of

ES6中添加的循環(huán)語(yǔ)法;

for of支持遍歷數(shù)組、類對(duì)象(例如DOM NodeList對(duì)象)、字符串、Map對(duì)象、Set對(duì)象;

for of不支持遍歷普通對(duì)象,可通過(guò)與Object.keys()搭配使用遍歷;

for of遍歷后的輸出結(jié)果為數(shù)組元素的值;

十四、頁(yè)面卡頓的原因

1、js運(yùn)行時(shí)間太長(zhǎng)

2、head加載js時(shí)一直沒(méi)加載出來(lái)

3、dom過(guò)多

4、首屏加載資源過(guò)大(解決:默認(rèn)資源站位)

十五、瀏覽器存儲(chǔ)(cookie 、webstorage)

https://www.cnblogs.com/qiujianmei/p/10824682.html


React

一、子組件向父組件傳值

父子組件通信不僅可以傳值,還可以傳遞方法,父組件將更新數(shù)據(jù)的方法拿給子組件使用,子組件將自身的數(shù)據(jù)傳入這個(gè)方法并調(diào)用,以此來(lái)改變父組件的數(shù)據(jù)。

就是父組件給子組件傳遞一個(gè)方法,子組件將自己的數(shù)據(jù)傳入這個(gè)方法并調(diào)用,就能改變父組件數(shù)據(jù)

二、父組件調(diào)用子組件的方法

先向子組件傳方法,子組件通過(guò)父組件傳遞的方法向父組件傳遞方法,父組件獲取到子組件的方法直接調(diào)用。

三、state和prop的區(qū)別

2-1.prop用于定義外部接口,state用于記錄內(nèi)部狀態(tài)

2-2,prop 的賦值在外部世界使用組件時(shí),state的賦值在組件內(nèi)部,

2-3,組件不應(yīng)該改變prop的值,而state存在的目的就是讓組件來(lái)改變的

四、修改數(shù)據(jù)應(yīng)該在哪個(gè)生命周期里面

didMount、didUpdate()

五、虛擬dom

1、瀏覽器資源對(duì)dom節(jié)點(diǎn)開(kāi)銷很大,而且頻繁改變dom結(jié)點(diǎn),會(huì)引發(fā)重繪和回流,非常影響性能。

2、虛擬dom存在的意義就是為了減少對(duì)實(shí)際dom的操作,js運(yùn)行速度很快,通過(guò)對(duì)比新舊dom,有針對(duì)性的把差異部分渲染到頁(yè)面上

3、虛擬dom原理:

⑴用js模擬dom樹(shù),并渲染dom樹(shù)

⑵比較新老dom樹(shù),得到比較的差異對(duì)象

⑶把差異對(duì)象應(yīng)用到渲染的dom樹(shù)

4、js創(chuàng)建虛擬dom

5、diff算法

作用:是用來(lái)計(jì)算出 Virtual DOM 中被改變的部分,然后針對(duì)該部分進(jìn)行原生DOM操作。

createElement(tag,props,children)

策略:策略一(tree diff):

Web UI中DOM節(jié)點(diǎn)跨層級(jí)的移動(dòng)操作特別少,可以忽略不計(jì)。

? 策略二(component diff):

擁有相同類的兩個(gè)組件 生成相似的樹(shù)形結(jié)構(gòu),

擁有不同類的兩個(gè)組件 生成不同的樹(shù)形結(jié)構(gòu)。

? 策略三(element diff):

對(duì)于同一層級(jí)的一組子節(jié)點(diǎn),通過(guò)唯一id區(qū)分。

六、react生命周期

https://www.cnblogs.com/kdcg/p/9182393.html

1、construtor():構(gòu)造函數(shù)

組建加載前最先調(diào)用一次,僅調(diào)用一次

作用:定義狀態(tài)機(jī)變量

2、componentWillMount

組件初始渲染(render()被調(diào)用)前調(diào)用,僅調(diào)用一次。

如果這個(gè)函數(shù)調(diào)用的setState改變了組件的某些狀態(tài),react會(huì)等待setState完成后再渲染組件

注意子組件也有componentWillMount函數(shù),在父組件的該函數(shù)調(diào)用后在調(diào)用。

3、render()

執(zhí)行:componentWillMount調(diào)用之后,componentDidMount調(diào)用之前

作用:渲染掛載組件。

觸發(fā):⑴初始化加載頁(yè)面,⑵狀態(tài)機(jī)改變setState,⑶接受新的props(父組件更新)

注意:這是組件必要參數(shù),不能在該函數(shù)內(nèi)使用setState改變狀態(tài)機(jī)

4、componentDidMount()

執(zhí)行:render()之后被調(diào)用,僅調(diào)用一次。

作用:渲染掛載組件

注意:子組件也有該函數(shù),在父組件調(diào)用前調(diào)用,如果該函數(shù)有setState改變狀態(tài)機(jī),將重新渲染組件,如果需要在頁(yè)面初始化之后才改變狀態(tài)機(jī)的,可以將網(wǎng)絡(luò)請(qǐng)求放在該函數(shù)內(nèi)。

5、componentWillReceiveProps()

執(zhí)行:組件渲染后,當(dāng)組件接收新的參數(shù)時(shí)被調(diào)用,

6、shouldComponentUpDate(nextProps,nextState)

執(zhí)行:組件執(zhí)行render()函數(shù)之后,接收新的props或state時(shí)被調(diào)用,即每次執(zhí)行setState都會(huì)執(zhí)行該函數(shù),來(lái)判斷是否重新渲染組件,默認(rèn)返回true,接收兩個(gè)參數(shù)。

作用:如果有些變化不需要執(zhí)行渲染組件,可在該函數(shù)內(nèi)阻止,

注意:不能在該函數(shù)內(nèi)使用setState來(lái)改變狀態(tài)機(jī)。

7、componentDidUpdate()

執(zhí)行:組件重新渲染后調(diào)用,初始化渲染的時(shí)候該方法不會(huì)被調(diào)用。

作用:使用該方法可以在組件更新后操作dom元素

8、componentWillUnmount()

執(zhí)行:組件卸載之前被調(diào)用

作用:在該方法中執(zhí)行必要的清理,比如無(wú)效的定時(shí)器

注意:當(dāng)一個(gè)頁(yè)面中存在父子組件的時(shí)候,要特別注意componentDidMount的使用,因?yàn)樽咏M件componentDidMount會(huì)比父組件先調(diào)用,從而引起父子組件傳參錯(cuò)誤

七、Component與PureComponent的區(qū)別

https://www.cnblogs.com/ly0612/p/11954414.html

PureComponent簡(jiǎn)單實(shí)現(xiàn)了shouldComponentUpdate()的功能。當(dāng)然數(shù)據(jù)結(jié)構(gòu)比較復(fù)雜就不行了。

PureComponent缺點(diǎn)

可能會(huì)因深層的數(shù)據(jù)不一致而產(chǎn)生錯(cuò)誤的否定判斷,從而shouldComponentUpdate結(jié)果返回false,界面得不到更新。

八、怎么寫(xiě)一個(gè)組件

https://blog.csdn.net/donspeng/article/details/83421136

組件目的是為了提高代碼復(fù)用性,另外,組件必須功能單一,復(fù)用性高。如果想實(shí)現(xiàn)復(fù)用性強(qiáng)的特點(diǎn)的話,可以用高階組件的思想,傳參數(shù)通過(guò)props

九、connect()參數(shù)有幾個(gè)

函數(shù)將被調(diào)用兩次。第一次是設(shè)置參數(shù),第二次是組件與 Redux store 連接:connect(mapStateToProps, mapDispatchToProps, mergeProps)(MyComponent)。

十、路由

十一、react優(yōu)化

十二、服務(wù)器渲染

十三、react hooks方法有哪些方法

1、基礎(chǔ) Hook

useState

useEffect

useContext

2、額外的 Hook

useReducer

useCallback

useMemo

useRef

useImperativeHandle

useLayoutEffect

useDebugValue

十四、setState

什么時(shí)候setState是同步的

1、React通過(guò)addEventListener直接添加事件處理函數(shù),

2、通過(guò)setTimeout/setInterval產(chǎn)生異步調(diào)用

原理解析:

在React的setState函數(shù)實(shí)現(xiàn)中,會(huì)根據(jù)一個(gè)變量 isBatchingUpdate 來(lái)判斷是直接同步更新this.state還是放到隊(duì)列中異步更新 。這個(gè)變量默認(rèn)為false即同步執(zhí)行,而當(dāng) React 在調(diào)用事件處理函數(shù)之前就會(huì)調(diào)用這個(gè) batchedUpdates,這個(gè)函數(shù)會(huì)把isBatchingUpdate變?yōu)閠rue,然后異步執(zhí)行setState。

React使用了事務(wù)的機(jī)制,React的每個(gè)生命周期和合成事件都處在一個(gè)大的事務(wù)當(dāng)中。在事務(wù)的前置鉤子中調(diào)用batchedUpdates方法修改isBatchingUpdates變量為true,在后置鉤子中將變量置為false。原生綁定事件和setTimeout異步的函數(shù)沒(méi)有進(jìn)入到React的事務(wù)當(dāng)中,或者當(dāng)他們執(zhí)行時(shí),剛剛的事務(wù)已近結(jié)束了,后置鉤子觸發(fā)了,所以此時(shí)的setState會(huì)直接進(jìn)入非批量更新模式,表現(xiàn)在我們看來(lái)成為了同步SetState

十五、淺談redux

最外層是Provider(react-redux解構(gòu)出來(lái))<Provider store={store}>

然后是store, store里面是reducer

reducer傳兩個(gè)參數(shù)(state,action)返回新的state

頁(yè)面用connect(mapstate,dispatchstate,組件)或者使用裝飾器

為什么reducer是純函數(shù)

因?yàn)椴荒芨淖冚斎胫祍tate,說(shuō)白了就是reducer傳state和action返回新的state

為什么這樣設(shè)計(jì)

因?yàn)轫?yè)面渲染需要比較新舊state,react比較state比較的是地址(也就是淺比較,如果深比較耗費(fèi)性能)所以必須返回新的state,否則頁(yè)面不更新

首先得先知道什么是純函數(shù)

1、相同的輸入永遠(yuǎn)返回相同的輸出

2、不能修改輸入值

3、不依賴外部環(huán)境

4、無(wú)任何副作用

十六、React組件有那些

可分為函數(shù)組件,class組件、渲染組件、組合組件、有狀態(tài)組件、無(wú)狀態(tài)組件、高階組件、自定義組件

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • JS中的塊級(jí)作用域 1.with 2.try.. catch 3.let, const 變量提升和函數(shù)提升 包括變...
    杰米桀彌閱讀 796評(píng)論 1 3
  • 前端目錄 HTML相關(guān) CSS相關(guān) JAVASCRIPT相關(guān) DOM相關(guān) HTTP相關(guān) VUE相關(guān) 算法相關(guān) 網(wǎng)絡(luò)...
    keyuan0214閱讀 486評(píng)論 0 2
  • 在找工作的這段時(shí)間,其實(shí)面試了挺多的公司,關(guān)于前端技術(shù)方面被提問(wèn)到了很多,常見(jiàn)的幾類問(wèn)題,我會(huì)在下文中一一給你解釋...
    Marin_chen閱讀 639評(píng)論 0 8
  • 面試題鏈接地址 https://juejin.im/post/5cbff661e51d456e693f48ec#h...
    祝家莊打烊閱讀 595評(píng)論 0 1
  • 1.不包含掘金小冊(cè) 掘金小冊(cè)的內(nèi)容就不在這總結(jié)了,下邊的內(nèi)容是其他一些小細(xì)節(jié),面試分為筆試和口頭面對(duì)面交流。本大綱...
    足夠幸運(yùn)閱讀 558評(píng)論 0 2

友情鏈接更多精彩內(nèi)容