面試題總結(jié)

1.說說你對盒子模型的理解


當對一個文檔進行布局(layout)的時候啥寇,瀏覽器的渲染引擎會根據(jù)標準之一的 CSS 基礎框盒模型(CSS basic box model),將所有元素表示為一個個矩形的盒子(box)

一個盒子由四個部分組成:content、padding、border羔沙、margin

content,即實際內(nèi)容厨钻,顯示文本和圖像

boreder扼雏,即邊框,圍繞元素內(nèi)容的內(nèi)邊距的一條或多條線夯膀,由粗細诗充、樣式、顏色三部分組成

padding诱建,即內(nèi)邊距蝴蜓,清除內(nèi)容周圍的區(qū)域,內(nèi)邊距是透明的俺猿,取值不能為負茎匠,受盒子的background屬性影響

margin,即外邊距押袍,在元素外創(chuàng)建額外的空白汽抚,空白通常指不能放其他元素的區(qū)域

在CSS中,盒子模型可以分成:

W3C 標準盒子模型

IE 怪異盒子模型

默認情況下伯病,盒子模型為W3C?標準盒子模型

標準盒子模型

標準盒子模型,是瀏覽器默認的盒子模型

也就是否过,width/height?只是內(nèi)容高度午笛,不包含?padding?和?border值

IE 怪異盒子模型

也就是,width/height?包含了?padding和?border值

可以通過box-sizing: border-box;來設置為IE怪異盒子模型


2.css選擇器有哪些苗桂?優(yōu)先級药磺?

id選擇器(#box),選擇id為box的元素

類選擇器(.one)煤伟,選擇類名為one的所有元素

標簽選擇器(div)癌佩,選擇標簽為div的所有元素

后代選擇器(#box div),選擇id為box元素內(nèi)部所有的div元素

子選擇器(.one>one_1)便锨,選擇父元素為.one的所有.one_1的元素

相鄰同胞選擇器(.one+.two)围辙,選擇緊接在.one之后的所有.two元素

群組選擇器(div,p),選擇div放案、p的所有元素

優(yōu)先級

!important >內(nèi)聯(lián) > ID選擇器 > 類選擇器 > 標簽選擇器

繼承屬性

在css中姚建,繼承是指的是給父元素設置一些屬性,后代元素會自動擁有這些屬性.

font-size, font-family, color


3.元素水平垂直居中的方法有哪些吱殉?如果元素不定寬高呢掸冤?

實現(xiàn)元素水平垂直居中的方式:

利用定位+margin:auto (開啟定位后,脫離文檔流)

利用定位+margin:負值 (例如盒子100*100,定位top,left偏移后,偏右下方向,需要回-50)

利用定位+transform (定位top,left偏移后,偏右下方向,通過transform: translate(-50%,-50%))

table布局

flex布局

grid布局



4.怎么理解回流跟重繪厘托?什么場景下會觸發(fā)?

回流:布局引擎會根據(jù)各種樣式計算每個盒子在頁面上的大小與位置

重繪:當計算好盒模型的位置稿湿、大小及其他屬性后铅匹,瀏覽器根據(jù)每個盒子特性進行繪制

具體的瀏覽器解析渲染機制如下所示:

解析HTML,生成DOM樹饺藤,解析CSS包斑,生成CSSOM樹

將DOM樹和CSSOM樹結(jié)合,生成渲染樹(Render Tree)

Layout(回流):根據(jù)生成的渲染樹策精,進行回流(Layout)舰始,得到節(jié)點的幾何信息(位置,大醒释唷)

Painting(重繪):根據(jù)渲染樹以及回流得到的幾何信息丸卷,得到節(jié)點的絕對像素

Display:將像素發(fā)送給GPU,展示在頁面上


當我們對?DOM?的修改引發(fā)了?DOM幾何尺寸的變化(比如修改元素的寬询刹、高或隱藏元素等)時谜嫉,瀏覽器需要重新計算元素的幾何屬性,然后再將計算的結(jié)果繪制出來

當我們對?DOM的修改導致了樣式的變化(color或background-color)凹联,卻并未影響其幾何屬性時沐兰,瀏覽器不需重新計算元素的幾何屬性、直接為該元素繪制新的樣式蔽挠,這里就僅僅觸發(fā)了重繪

回流這一階段主要是計算節(jié)點的位置和幾何信息住闯,那么當頁面布局和幾何信息發(fā)生變化的時候,就需要回流

觸發(fā)回流一定會觸發(fā)重繪

除此之外還有一些其他引起重繪行為:

顏色的修改

文本方向的修改

陰影的修改

下面給出避免回流的經(jīng)驗:

如果想設定元素的樣式澳淑,通過改變元素的?class?類名 (盡可能在 DOM 樹的最里層)

避免設置多項內(nèi)聯(lián)樣式

應用元素的動畫比原,使用?position?屬性的?fixed?值或?absolute?值(如前文示例所提)

避免使用?table?布局,table?中每個元素的大小以及內(nèi)容的改動杠巡,都會導致整個?table?的重新計算

對于那些復雜的動畫量窘,對其設置?position: fixed/absolute,盡可能地使元素脫離文檔流氢拥,從而減少對其他元素的影響

使用css3硬件加速蚌铜,可以讓transform、opacity嫩海、filters這些動畫不會引起回流重繪

避免使用 CSS 的?JavaScript?表達式

5.什么是響應式設計冬殃?響應式設計的基本原理是什么?如何做叁怪?

響應式網(wǎng)站設計(Responsive Web design)是一種網(wǎng)絡頁面設計布局造壮,頁面的設計與開發(fā)應當根據(jù)用戶行為以及設備環(huán)境(系統(tǒng)平臺、屏幕尺寸、屏幕定向等)進行相應的響應和調(diào)整

響應式網(wǎng)站常見特點:

同時適配PC + 平板 + 手機等

標簽導航在接近手持終端設備時改變?yōu)榻?jīng)典的抽屜式導航

網(wǎng)站的布局會根據(jù)視口來調(diào)整模塊的大小和位置

實現(xiàn)方式:

媒體查詢:

@mediascreen(min-width:375px)and(max-width:600px){

????????body{font-size:18px;}

}

百分比:

通過百分比單位 " % " 來實現(xiàn)響應式的效果

比如當瀏覽器的寬度或者高度發(fā)生變化時耳璧,通過百分比單位成箫,可以使得瀏覽器中的組件的寬和高隨著瀏覽器的變化而變化,從而實現(xiàn)響應式的效果

vw/vh:

vw表示相對于視圖窗口的寬度旨枯,vh表示相對于視圖窗口高度蹬昌。 任意層級元素,在使用vw單位的情況下攀隔,1vw都等于視圖寬度的百分之一

rem:

在以前也講到皂贩,rem是相對于根元素html的font-size屬性,默認情況下瀏覽器字體大小為16px昆汹,此時1rem = 16px

響應式布局優(yōu)點可以看到:

面對不同分辨率設備靈活性強

能夠快捷解決多設備顯示適應問題

缺點:

僅適用布局明刷、信息、框架并不復雜的部門類型網(wǎng)站

兼容各種設備工作量大满粗,效率低下

代碼累贅辈末,會出現(xiàn)隱藏無用的元素,加載時間加長

其實這是一種折中性質(zhì)的設計解決方案映皆,多方面因素影響而達不到最佳效果

一定程度上改變了網(wǎng)站原有的布局結(jié)構(gòu)挤聘,會出現(xiàn)用戶混淆的情況

6.如果要做優(yōu)化,CSS提高性能的方法有哪些捅彻?

內(nèi)聯(lián)首屏關鍵CSS:

在打開一個頁面组去,頁面首要內(nèi)容出現(xiàn)在屏幕的時間影響著用戶的體驗,而通過內(nèi)聯(lián)css關鍵代碼能夠使瀏覽器在下載完html后就能立刻渲染

異步加載CSS

資源壓縮

合理使用選擇器:

不要嵌套使用過多復雜選擇器步淹,最好不要三層以上

使用id選擇器就沒必要再進行嵌套

通配符和屬性選擇器效率最低从隆,避免使用

建立公共樣式類,把相同樣式提取出來作為公共類使用缭裆,比如我們常用的清除浮動等

減少使用昂貴的屬性:

在頁面發(fā)生重繪的時候键闺,昂貴屬性如box-shadow/border-radius/filter/透明度/:nth-child等,會降低瀏覽器的渲染性能

不要使用@import

不用css表達式幼驶,表達式只是讓你的代碼顯得更加炫酷,但是他對性能的浪費可能是超乎你的想象的


7.對前端工程師這個職位是怎么樣理解的韧衣?它的前景會怎么樣?

我認為前端工程師是最貼近用戶的盅藻,是以用戶需求為中心,通過不同的改進和親身體驗來完成用戶的需求畅铭,讓用戶的交互效果更加舒服氏淑,

以前前端的可能就寫一些頁面,很簡單的工作硕噩,現(xiàn)在可以通過vue假残,react等框架來讓交互效果更加理想,也把后端的一些任務放到前端處理,所以辉懒,前端不僅僅要面對用戶阳惹,還要面對,后端眶俩,產(chǎn)品經(jīng)理莹汤,等所以前端并不局限于前端技術還要會一點后端,會一點產(chǎn)品颠印, 每個前端人員往往都會往全棧的方向去發(fā)展纲岭,當然這也是我的一個目標,這就我對前端開發(fā)人員的理解+

8.說說JavaScript中的數(shù)據(jù)類型线罕?存儲上的差別止潮?

js的數(shù)據(jù)類型分為兩類,一個是基本數(shù)據(jù)類型钞楼,一個是引用數(shù)據(jù)類型

基本數(shù)據(jù)類型有undefined喇闸、null、boolean窿凤、number仅偎、string、symbol

引用數(shù)據(jù)類型有 object

在js的執(zhí)行過程中雳殊,主要有三種數(shù)據(jù)類型內(nèi)存空間橘沥,分別是代碼空間,椇煌海空間座咆,堆空間,其中的代碼空間主要是存儲可執(zhí)行代碼的仓洼,原始類型的數(shù)據(jù)值都是直接保存在棧中的介陶,引用數(shù)據(jù)類型的值是存放在堆空間中的, 原始數(shù)據(jù)類型存儲的是變量的值色建,而引用數(shù)據(jù)類型存儲的是其在堆空間中的地址哺呜。

9.typeof 與 instanceof 區(qū)別

typeof?操作符返回一個字符串,表示未經(jīng)計算的操作數(shù)的類型

typeof 對于原始數(shù)據(jù)類型來說箕戳,除了null都可以正確的顯示類型

對于引用數(shù)據(jù)類型來說某残,除了function函數(shù),都會顯示object

這樣看來typeof它并不能正確的顯示數(shù)據(jù)類型

instanceof?運算符用于檢測構(gòu)造函數(shù)的?prototype?屬性是否出現(xiàn)在某個實例對象的原型鏈上,能判斷這個對象是否是之前那個構(gòu)造函數(shù)生成的對象

typeof與instanceof都是判斷數(shù)據(jù)類型的方法陵吸,區(qū)別如下:

typeof會返回一個變量的基本類型玻墅,instanceof返回的是一個布爾值

instanceof?可以準確地判斷復雜引用數(shù)據(jù)類型,但是不能正確判斷基礎數(shù)據(jù)類型

而typeof?也存在弊端壮虫,它雖然可以判斷基礎數(shù)據(jù)類型(null?除外)澳厢,但是引用數(shù)據(jù)類型中,除了function?類型以外,其他的也無法判斷

10.說說你對閉包的理解剩拢?閉包使用場景

閉包就是可以訪問其他函數(shù)內(nèi)部變量的函數(shù)线得,我們通常用它來定義私有化的變量和方法,創(chuàng)建一個閉包最簡單的方法就是在一個函數(shù)內(nèi)創(chuàng)建一個函數(shù)裸扶,它有三個特性是 函數(shù)內(nèi)可以再嵌套函數(shù)框都,內(nèi)部函數(shù)可以訪問外部的方法和變量,方法和變量不會被垃圾回收機制回收

任何閉包的使用場景都離不開這兩點:

創(chuàng)建私有變量

延長變量的生命周期

11.bind呵晨、call魏保、apply 區(qū)別?如何實現(xiàn)一個bind?

從上面可以看到摸屠,apply谓罗、call、bind三者的區(qū)別在于:

三者都可以改變函數(shù)的this對象指向

三者第一個參數(shù)都是this要指向的對象季二,如果如果沒有這個參數(shù)或參數(shù)為undefined或null檩咱,則默認指向全局window

三者都可以傳參,但是apply是數(shù)組胯舷,而call是參數(shù)列表刻蚯,且apply和call是一次性傳入?yún)?shù),而bind可以分為多次傳入

bind是返回綁定this之后的函數(shù)桑嘶,apply炊汹、call?則是立即執(zhí)行

實現(xiàn)bind的步驟,我們可以分解成為三部分:

修改this指向

動態(tài)傳遞參數(shù)

兼容new關鍵字

12.說說你對事件循環(huán)的理解

首先逃顶,JavaScript是一門單線程的語言讨便,意味著同一時間內(nèi)只能做一件事,但是這并不意味著單線程就是阻塞以政,而實現(xiàn)單線程非阻塞的方法就是事件循環(huán)

在JavaScript中霸褒,所有的任務都可以分為

同步任務:立即執(zhí)行的任務,同步任務一般會直接進入到主線程中執(zhí)行

異步任務:異步執(zhí)行的任務盈蛮,比如ajax網(wǎng)絡請求废菱,setTimeout定時函數(shù)等

從上面我們可以看到,同步任務進入主線程抖誉,即主執(zhí)行棧殊轴,異步任務進入任務隊列,主線程內(nèi)的任務執(zhí)行完畢為空寸五,會去任務隊列讀取對應的任務梳凛,推入主線程執(zhí)行耿币。上述過程的不斷重復就事件循環(huán)

異步任務還可以細分為微任務與宏任務

微任務

當前(此次事件循環(huán)中)宏任務執(zhí)行完梳杏,在下一個宏任務開始之前需要執(zhí)行的任務,可以理解為回調(diào)事件。

常見的微任務有:

Promise.then

MutaionObserver

Object.observe(已廢棄;Proxy 對象替代)

process.nextTick(Node.js)

宏任務

當前調(diào)用棧中執(zhí)行的代碼成為宏任務十性。

常見的宏任務有:

script (可以理解為外層同步代碼)

setTimeout/setInterval

UI rendering/UI事件

postMessage叛溢、MessageChannel

setImmediate、I/O(Node.js)

13.DOM常見的操作有哪些

1.查找節(jié)點. 2.創(chuàng)建節(jié)點. 3.添加新節(jié)點. 4.刪除節(jié)點. 5.更新節(jié)點.

添加節(jié)點: parentNode.appendChild(existingChild)

innerHtml

創(chuàng)建節(jié)點:document.createElement(“元素名”)

刪除節(jié)點:parentNode.removeChild(existingChild)刪除已有的子節(jié)點劲适,返回值為刪除節(jié)點

更新節(jié)點:parentNode.replaceChild(newChild,existingChild)用新節(jié)點替換父節(jié)點中已有的子節(jié)點

innerHtml不但可以修改一個DOM節(jié)點的文本內(nèi)容楷掉,還可以直接通過HTML片段修改DOM節(jié)點內(nèi)部的子樹

ele.style.styleName = styleValue 修改樣式

查找節(jié)點:document.getElementByid(“id屬性值”) 返回擁有指定id的第一個對象的引用document.getElementsByClassName('class屬性值');返回擁有指定class的對象集合document.getElementsByTagName('標簽名');返回擁有指定標簽名的對象集合document.getElementsByName('name屬性值');返回擁有指定名稱的對象結(jié)合document/element.querySelector('CSS選擇器');僅返回第一個匹配的元素document/element.querySelectorAll('CSS選擇器');返回所有匹配的元素

14.說說你對BOM的理解,常見的BOM對象你了解哪些霞势?

一烹植、是什么

BOM?(Browser Object Model),瀏覽器對象模型愕贡,提供了獨立于內(nèi)容與瀏覽器窗口進行交互的對象

其作用就是跟瀏覽器做一些交互效果,比如如何進行頁面的后退草雕,前進,刷新固以,瀏覽器的窗口發(fā)生變化墩虹,滾動條的滾動薛窥,以及獲取客戶的一些信息如:瀏覽器品牌版本亥鬓,屏幕分辨率

二踊沸、window

Bom的核心對象是window鱼蝉,它表示瀏覽器的一個實例

在瀏覽器中赋秀,window對象有雙重角色我纪,即是瀏覽器窗口的一個接口麻顶,又是全局對象

因此所有在全局作用域中聲明的變量巷折、函數(shù)都會變成window對象的屬性和方法

三闲擦、location

除了?hash之外慢味,只要修改location的一個屬性,就會導致頁面重新加載新URL

location.reload()墅冷,此方法可以重新刷新當前頁面纯路。這個方法會根據(jù)最有效的方式刷新頁面,如果頁面自上一次請求以來沒有改變過寞忿,頁面就會從瀏覽器緩存中重新加載

四驰唬、navigator

navigator?對象主要用來獲取瀏覽器的屬性,區(qū)分瀏覽器類型腔彰。屬性較多叫编,且兼容性比較復雜

五、screen

保存的純粹是客戶端能力信息霹抛,也就是瀏覽器窗口外面的客戶端顯示器的信息搓逾,比如像素寬度和像素高度

六、history

history對象主要用來操作瀏覽器URL的歷史記錄杯拐,可以通過參數(shù)向前霞篡,向后世蔗,或者向指定URL跳轉(zhuǎn)

history.go() 接收一個整數(shù)數(shù)字或者字符串參數(shù):向最近的一個記錄中包含指定字符串的頁面跳轉(zhuǎn)

history.forward():向前跳轉(zhuǎn)一個頁面

history.back():向后跳轉(zhuǎn)一個頁面

history.length:獲取歷史記錄數(shù)

15.Javascript本地存儲的方式有哪些?區(qū)別及應用場景朗兵?

一污淋、方式

javaScript本地緩存的方法我們主要講述以下四種:

cookie

Cookie,類型為「小型文本文件」余掖,指某些網(wǎng)站為了辨別用戶身份而儲存在用戶本地終端上的數(shù)據(jù)寸爆。是為了解決?HTTP無狀態(tài)導致的問題

作為一段一般不超過 4KB 的小型文本數(shù)據(jù),它由一個名稱(Name)盐欺、一個值(Value)和其它幾個用于控制?cookie有效期赁豆、安全性、使用范圍的可選屬性組成

但是cookie在每次請求中都會被發(fā)送冗美,如果不使用?HTTPS并對其加密歌憨,其保存的信息很容易被竊取,導致安全風險墩衙。

sessionStorage

sessionStorage和?localStorage使用方法基本一致务嫡,唯一不同的是生命周期,一旦頁面(會話)關閉漆改,sessionStorage?將會刪除數(shù)據(jù)

localStorage

生命周期:持久化的本地存儲心铃,除非主動刪除數(shù)據(jù),否則數(shù)據(jù)是永遠不會過期的

indexedDB

二挫剑、區(qū)別

關于cookie去扣、sessionStorage、localStorage三者的區(qū)別主要如下:

存儲大蟹啤:cookie數(shù)據(jù)大小不能超過4k愉棱,sessionStorage和localStorage雖然也有存儲大小的限制,但比cookie大得多哲戚,可以達到5M或更大

有效時間:localStorage存儲持久數(shù)據(jù)奔滑,瀏覽器關閉后數(shù)據(jù)不丟失除非主動刪除數(shù)據(jù);?sessionStorage數(shù)據(jù)在當前瀏覽器窗口關閉后自動刪除顺少;cookie設置的cookie過期時間之前一直有效朋其,即使窗口或瀏覽器關閉

數(shù)據(jù)與服務器之間的交互方式,cookie的數(shù)據(jù)會自動的傳遞到服務器脆炎,服務器端也可以寫cookie到客戶端梅猿;?sessionStorage和localStorage不會自動把數(shù)據(jù)發(fā)給服務器,僅在本地保存

三秒裕、應用場景

在了解了上述的前端的緩存方式后袱蚓,我們可以看看針對不對場景的使用選擇:

標記用戶與跟蹤用戶行為的情況,推薦使用cookie

適合長期保存在本地的數(shù)據(jù)(令牌)几蜻,推薦使用localStorage

敏感賬號一次性登錄喇潘,推薦使用sessionStorage

存儲大量數(shù)據(jù)的情況爽撒、在線文檔(富文本編輯器)保存編輯歷史的情況,推薦使用indexedDB

16.什么是防抖和節(jié)流响蓉?有什么區(qū)別?如何實現(xiàn)哨毁?

節(jié)流: n 秒內(nèi)只運行一次枫甲,若在 n 秒內(nèi)重復觸發(fā),只有一次生效

防抖: n 秒后在執(zhí)行該事件扼褪,若在 n 秒內(nèi)被重復觸發(fā)想幻,則重新計時

本質(zhì)上是優(yōu)化高頻率執(zhí)行代碼的一種手段,需要對這類事件進行調(diào)用次數(shù)的限制

二、區(qū)別

相同點:

都可以通過使用?setTimeout?實現(xiàn)

目的都是话浇,降低回調(diào)執(zhí)行頻率脏毯。節(jié)省計算資源

不同點:

函數(shù)防抖,在一段連續(xù)操作結(jié)束后幔崖,處理回調(diào)食店,利用clearTimeout和?setTimeout實現(xiàn)。函數(shù)節(jié)流赏寇,在一段連續(xù)操作中吉嫩,每一段時間只執(zhí)行一次,頻率較高的事件中使用來提高性能

函數(shù)防抖關注一定時間連續(xù)觸發(fā)的事件嗅定,只在最后執(zhí)行一次自娩,而函數(shù)節(jié)流一段時間內(nèi)只執(zhí)行一次

17.如何通過JS判斷一個數(shù)組

1.通過instanceof判斷

let a = [];

a instanceofArray;//true

2.通過constructor判斷

我們知道,實例的構(gòu)造函數(shù)屬性constructor指向構(gòu)造函數(shù)渠退,那么通過constructor屬性也可以判斷是否為一個數(shù)組忙迁。

let a = [1,3,4];

a.constructor === Array;//true

3.通過Object.prototype.toString.call()判斷

?Object.prototype.toString().call()可以獲取到對象的不同類型,例如

let a = [1,2,3]

Object.prototype.toString.call(a) === '[object Array]';//true

4.通過Array.isArray()判斷

Array.isArray()?用于確定傳遞的值是否是一個數(shù)組碎乃,返回一個布爾值姊扔。

let a = [1,2,3]

Array.isArray(a);//true

18.說說你對作用域鏈的理解

一、作用域

作用域梅誓,即變量(變量作用域又稱上下文)和函數(shù)生效(能被訪問)的區(qū)域或集合

我們一般將作用域分成:

全局作用域

函數(shù)作用域

塊級作用域

二旱眯、詞法作用域

詞法作用域,又叫靜態(tài)作用域证九,變量被創(chuàng)建時就確定好了删豺,而非執(zhí)行階段確定的。也就是說我們寫好代碼時它的作用域就確定了愧怜,JavaScript?遵循的就是詞法作用域

三呀页、作用域鏈

當在Javascript中使用一個變量的時候,首先Javascript引擎會嘗試在當前作用域下去尋找該變量拥坛,如果沒找到蓬蝶,再到它的上層作用域?qū)ふ页痉郑源祟愅浦钡秸业皆撟兞炕蚴且呀?jīng)到了全局作用域

19.JavaScript原型,原型鏈 ? 有什么特點丸氛?

一培愁、原型

JavaScript?常被描述為一種基于原型的語言——每個對象擁有一個原型對象

當試圖訪問一個對象的屬性時,它不僅僅在該對象上搜尋缓窜,還會搜尋該對象的原型定续,以及該對象的原型的原型,依次層層向上搜索禾锤,直到找到一個名字匹配的屬性或到達原型鏈的末尾

準確地說私股,這些屬性和方法定義在Object的構(gòu)造器函數(shù)(constructor functions)之上的prototype屬性上,而非實例對象本身

二恩掷、原型鏈

原型對象也可能擁有原型倡鲸,并從中繼承方法和屬性,一層一層黄娘、以此類推峭状。這種關系常被稱為原型鏈 (prototype chain),它解釋了為何一個對象會擁有定義在其他對象中的屬性和方法

在對象實例和它的構(gòu)造器之間建立一個鏈接(它是__proto__屬性逼争,是從構(gòu)造函數(shù)的prototype屬性派生的)宁炫,之后通過上溯原型鏈,在構(gòu)造器中找到這些屬性和方法

下面作出總結(jié):

一切對象都是繼承自Object對象氮凝,Object?對象直接繼承根源對象null

一切的函數(shù)對象(包括?Object?對象)羔巢,都是繼承自?Function?對象

Object?對象直接繼承自?Function?對象

Function對象的__proto__會指向自己的原型對象,最終還是繼承自Object對象

20. 請解釋什么是事件代理

一罩阵、是什么

事件代理竿秆,俗地來講,就是把一個元素響應事件(click稿壁、keydown......)的函數(shù)委托到另一個元素

前面講到幽钢,事件流的都會經(jīng)過三個階段: 捕獲階段 -> 目標階段 -> 冒泡階段,而事件委托就是在冒泡階段完成

事件委托傅是,會把一個或者一組元素的事件委托到它的父層或者更外層元素上匪燕,真正綁定事件的是外層元素,而不是目標元素

當事件響應到目標元素上時喧笔,會通過事件冒泡機制從而觸發(fā)它的外層元素的綁定事件上帽驯,然后在外層元素上去執(zhí)行函數(shù)

從上面應用場景中,我們就可以看到使用事件委托存在兩大優(yōu)點:

減少整個頁面所需的內(nèi)存书闸,提升整體性能

動態(tài)綁定尼变,減少重復工作

21. 談談This對象的理解

一、定義

在絕大多數(shù)情況下浆劲,函數(shù)的調(diào)用方式?jīng)Q定了?this?的值(運行時綁定)

this?關鍵字是函數(shù)運行時自動生成的一個內(nèi)部對象嫌术,只能在函數(shù)內(nèi)部使用哀澈,總指向調(diào)用它的對象

二、綁定規(guī)則

根據(jù)不同的使用場合度气,this有不同的值割按,主要分為下面幾種情況:

默認綁定:

嚴格模式下,不能將全局對象用于默認綁定磷籍,this會綁定到undefined适荣,只有函數(shù)運行在非嚴格模式下,默認綁定才能綁定到全局對象

隱式綁定:

函數(shù)還可以作為某個對象的方法調(diào)用择示,這時this就指這個上級對象

new綁定:

通過構(gòu)建函數(shù)new關鍵字生成一個實例對象,此時this指向這個實例對象

顯示綁定:

apply()晒旅、call()栅盲、bind()是函數(shù)的一個方法,作用是改變函數(shù)的調(diào)用對象废恋。它的第一個參數(shù)就表示改變后的調(diào)用這個函數(shù)的對象谈秫。因此,這時this指的就是這第一個參數(shù)

三鱼鼓、箭頭函數(shù)

在 ES6 的語法中還提供了箭頭函語法拟烫,讓我們在代碼書寫時就能確定?this?的指向(編譯時綁定)

箭頭函數(shù)沒有自己的this指向,它的this指向上一級作用域的this

不能改變this指向

四迄本、優(yōu)先級

綜上硕淑,new綁定優(yōu)先級 > 顯示綁定優(yōu)先級 > 隱式綁定優(yōu)先級 > 默認綁定優(yōu)先級

22. new操作符具體干了什么

一、是什么

在JavaScript中嘉赎,new操作符用于創(chuàng)建一個給定構(gòu)造函數(shù)的實例對象

從上面可以看到:

new?通過構(gòu)造函數(shù)?Person?創(chuàng)建出來的實例可以訪問到構(gòu)造函數(shù)中的屬性

new?通過構(gòu)造函數(shù)?Person?創(chuàng)建出來的實例可以訪問到構(gòu)造函數(shù)原型鏈中的屬性(即實例與構(gòu)造函數(shù)通過原型鏈連接了起來)

二置媳、流程

從上面介紹中,我們可以看到new關鍵字主要做了以下的工作:

創(chuàng)建一個新的對象obj

將對象與構(gòu)建函數(shù)通過原型鏈連接起來

將構(gòu)建函數(shù)中的this綁定到新建的對象obj上

根據(jù)構(gòu)建函數(shù)返回類型作判斷公条,如果是原始值則被忽略拇囊,如果是返回對象,需要正常處理

23.null靶橱,undefined 的區(qū)別

1 null:表示"沒有對象"寥袭,即該處不應該有值

作為函數(shù)的參數(shù),表示該函數(shù)的參數(shù)不是對象关霸。

作為對象原型鏈的終點传黄。

2 undefined:表示"缺少值",就是此處應該有一個值队寇,但是還沒有定義

變量被聲明了尝江,但沒有賦值時,就等于undefined英上。

調(diào)用函數(shù)時炭序,應該提供的參數(shù)沒有提供啤覆,該參數(shù)等于undefined。

對象沒有賦值的屬性惭聂,該屬性的值為undefined窗声。

函數(shù)沒有返回值時,默認返回undefined辜纲。

24.javascript 代碼中的"use strict";是什么意思

使用 "use strict" 指令

"use strict" 指令在 JavaScript 1.8.5 (ECMAScript5) 中新增笨觅。

它不是一條語句,但是是一個字面量表達式耕腾,在 JavaScript 舊版本中會被忽略见剩。

"use strict" 的目的是指定代碼在嚴格條件下執(zhí)行。

嚴格模式下你不能使用未聲明的變量扫俺。

25.同步和異步的區(qū)別

所謂單線程苍苞,就是指在JS引擎中負責解釋和執(zhí)行JavaScript代碼的線程只有一個,一次只能完成一件任務狼纬。如果有多個任務羹呵,就必須排隊,前面一個任務完成疗琉,再執(zhí)行后面一個任務冈欢。如果一個任務耗時過長,那么后面的任務就必須一直等待下去盈简,會拖延整個程序凑耻。我們不妨叫它主線程

在JavaScript中,所有的任務都可以分為

同步任務:立即執(zhí)行的任務柠贤,同步任務一般會直接進入到主線程中執(zhí)行,就是后一個任務等待前一個任務結(jié)束拳话,然后再執(zhí)行,程序的執(zhí)行順序與任務的排列順序是一致的种吸、同步的弃衍。

異步任務:異步執(zhí)行的任務,比如ajax網(wǎng)絡請求坚俗,setTimeout定時函數(shù)等,每一個任務有一個或多個回調(diào)函數(shù)(callback)镜盯,前一個任務結(jié)束后,不是執(zhí)行后一個任務猖败,而是執(zhí)行回調(diào)函數(shù)速缆,后一個任務則是不等前一個任務結(jié)束就執(zhí)行,所以程序的執(zhí)行順序與任務的排列順序是不一致的恩闻、異步的艺糜。

26.談一談箭頭函數(shù)與普通函數(shù)的區(qū)別

一.箭頭函數(shù)都是匿名函數(shù)

普通函數(shù)可以有匿名函數(shù),也可以有具體名函數(shù),但是箭頭函數(shù)都是匿名函數(shù)破停。

二.箭頭函數(shù)不能用于構(gòu)造函數(shù)翅楼,不能使用new

普通函數(shù)可以用于構(gòu)造函數(shù),以此創(chuàng)建對象實例真慢。

三.箭頭函數(shù)中this的指向不同

在普通函數(shù)中毅臊,this總是指向調(diào)用它的對象,如果用作構(gòu)造函數(shù)黑界,this指向創(chuàng)建的對象實例管嬉。

1.箭頭函數(shù)本身不創(chuàng)建this

也可以說箭頭函數(shù)本身沒有this,但是它在聲明時可以捕獲其所在上下文的this供自己使用朗鸠。

2.結(jié)合call()蚯撩,apply()方法使用

箭頭函數(shù)結(jié)合call(),apply()方法調(diào)用一個函數(shù)時,只傳入一個參數(shù)對this沒有影響烛占。

27.JS 數(shù)組和對象的遍歷方式胎挎,以及幾種方式的比較

一、遍歷對象方法:

1.for...in

遍歷輸出的是對象自身的屬性以及原型鏈上可枚舉的屬性

2.Object.keys()

遍歷對象返回的是一個包含對象自身可枚舉屬性的數(shù)組(不含Symbol屬性).

3.Objcet.getOwnPropertyNames()

輸出對象自身的可枚舉和不可枚舉屬性的數(shù)組,不輸出原型鏈上的屬性

二.遍歷數(shù)組方法

1.forEach

2.map

可以對遍歷的每一項做相應的處理,返回每次函數(shù)調(diào)用的結(jié)果組成的數(shù)組

3.for循環(huán)遍歷

4.for...in

5.for...of(es6)

只遍歷出value,不能遍歷出下標,可遍歷出Symbol數(shù)據(jù)類型的屬性,此方法作為遍歷所有數(shù)據(jù)結(jié)構(gòu)的統(tǒng)一的方法


28.如何解決跨域問題

1.什么是跨域扰楼?

跨域:指的是瀏覽器不能執(zhí)行其他網(wǎng)站的腳本呀癣。它是由瀏覽器的同源策略造成的美浦,是瀏覽器對javascript施加的安全限制弦赖。

同源策略:是指協(xié)議,域名浦辨,端口都要相同蹬竖,其中有一個不同都會產(chǎn)生跨域;

1.CORS

跨域資源共享(CORS) 是一種機制流酬,它使用額外的HTTP頭來告訴瀏覽器 讓運行在一個 origin (domain) 上的 Web 應用被準許訪問來自不同源服務器上的指定的資源币厕。當一個資源從與該資源本身所在的服務器不同的域、協(xié)議或端口請求一個資源時芽腾,資源會發(fā)起一個跨域 HTTP 請求旦装。

2.Node 正向代理

代理的思路為,利用服務端請求不會跨域的特性摊滔,讓接口和當前站點同域阴绢。

3.Nginx 反向代理

4.JSONP

JSONP主要就是利用了script標簽沒有跨域限制的這個特性來完成的。

5.Websocket

WebSocket規(guī)范定義了一種 API艰躺,可在網(wǎng)絡瀏覽器和服務器之間建立“套接字”連接

6.window.postMessage

window.postMessage()方法可以安全地實現(xiàn)跨源通信呻袭。通常,對于兩個不同頁面的腳本腺兴,只有當執(zhí)行它們的頁面位于具有相同的協(xié)議(通常為 https)左电,端口號(443 為 https 的默認值),以及主機 (兩個頁面的模數(shù)Document.domain設置為相同的值) 時,這兩個腳本才能相互通信篓足。

29.XML和JSON的區(qū)別

以下是JSON和XML之間的一些區(qū)別:

1段誊、JSON是JavaScript Object Notation;XML是可擴展標記語言纷纫。

2枕扫、JSON是基于JavaScript語言;XML源自SGML辱魁。

3烟瞧、JSON是一種表示對象的方式;XML是一種標記語言染簇,使用標記結(jié)構(gòu)來表示數(shù)據(jù)項参滴。

4纺蛆、JSON不提供對命名空間的任何支持甘耿;XML支持名稱空間。

5么翰、JSON支持數(shù)組青灼;XML不支持數(shù)組暴心。

6、XML的文件相對難以閱讀和解釋杂拨;與XML相比专普,JSON的文件非常易于閱讀。

7弹沽、JSON不使用結(jié)束標記檀夹;XML有開始和結(jié)束標簽。

8策橘、JSON的安全性較低炸渡;XML比JSON更安全。

9丽已、JSON不支持注釋蚌堵;XML支持注釋。

10沛婴、JSON僅支持UTF-8編碼吼畏;XML支持各種編碼。

30.談談你對webpack的看法

webpack?是一個用于現(xiàn)代JavaScript應用程序的靜態(tài)模塊打包工具

靜態(tài)模塊

這里的靜態(tài)模塊指的是開發(fā)階段瘸味,可以被?webpack?直接引用的資源(可以直接被獲取打包進bundle.js的資源)

webpack的能力:

編譯代碼能力宫仗,提高效率,解決瀏覽器兼容問題?

?模塊整合能力旁仿,提高性能藕夫,可維護性孽糖,解決瀏覽器頻繁請求文件的問題?

?萬物皆可模塊能力,項目維護性增強毅贮,支持不同種類的前端模塊類型办悟,統(tǒng)一的模塊化方案,所有資源文件的加載都可以通過代碼控制

31.webpack的打包原理

將根據(jù)文件間的依賴關系對其進行靜態(tài)分析滩褥,然后將這些模塊按指定規(guī)則生成靜態(tài)資源病蛉,當 webpack 處理程序時,會遞歸地構(gòu)建一個依賴關系圖(dependency graph)瑰煎,其中包含應用程序需要的每個模塊铺然,然后將所有這些模塊打包成一個或多個 bundle。

從啟動到結(jié)束會依次執(zhí)行以下三大步驟:

初始化流程:從配置文件和?Shell?語句中讀取與合并參數(shù)酒甸,并初始化需要使用的插件和配置插件等執(zhí)行環(huán)境所需要的參數(shù)

編譯構(gòu)建流程:從 Entry 發(fā)出魄健,針對每個 Module 串行調(diào)用對應的 Loader 去翻譯文件內(nèi)容,再找到該 Module 依賴的 Module插勤,遞歸地進行編譯處理

輸出流程:對編譯后的 Module 組合成 Chunk沽瘦,把 Chunk 轉(zhuǎn)換成文件,輸出到文件系統(tǒng)

32.如何優(yōu)化webpack打包速度

代碼分割

高達 6M 的入口文件顯然是非常影響體驗的农尖,因此優(yōu)化的第一步就是從代碼分割開始析恋。代碼分割通過把項目中的資源模塊按照我們設計的規(guī)則打包到不同的 bundle 中,從而降低應用的啟動成本盛卡,提高響應速度助隧。

速度優(yōu)化

在前面的速度分析中我們已經(jīng)知道了打包速度主要耗費在 loader 的處理上

很顯然在開發(fā)過程中進行 webpack 緩存是極其有必要的,我們在處理樣式文件和 js 文件的 loader 之前添加 cache-loader 將結(jié)果緩存到磁盤中窟扑,可以顯著提升二次構(gòu)建速度

33.說說webpack中常見的Loader喇颁?解決了什么問題漏健?

loader?用于對模塊的"源代碼"進行轉(zhuǎn)換嚎货,在?import?或"加載"模塊時預處理文件

webpack做的事情,僅僅是分析出各種模塊的依賴關系蔫浆,然后形成資源列表殖属,最終打包生成到指定的文件中。

在webpack內(nèi)部中瓦盛,任何文件都是模塊洗显,不僅僅只是js文件

默認情況下,在遇到import或者require加載模塊的時候原环,webpack只支持對js?和?json?文件打包

像css挠唆、sass、png等這些類型的文件的時候嘱吗,webpack則無能為力玄组,這時候就需要配置對應的loader進行文件內(nèi)容的解析

關于配置loader的方式有三種:

配置方式(推薦):在 webpack.config.js文件中指定 loader

內(nèi)聯(lián)方式:在每個 import 語句中顯式指定 loader

CLI 方式:在 shell 命令中指定它們

二、特性

這里繼續(xù)拿上述代碼,來講講loader的特性

從上述代碼可以看到俄讹,在處理css模塊的時候哆致,use屬性中配置了三個loader分別處理css文件

因為loader支持鏈式調(diào)用,鏈中的每個loader會處理之前已處理過的資源患膛,最終變?yōu)閖s代碼摊阀。順序為相反的順序執(zhí)行,即上述執(zhí)行方式為sass-loader踪蹬、css-loader胞此、style-loader

可以通過 loader 的預處理函數(shù),為 JavaScript 生態(tài)系統(tǒng)提供更多能力跃捣。用戶現(xiàn)在可以更加靈活地引入細粒度邏輯豌鹤,例如:壓縮、打包枝缔、語言翻譯和更多其他特性

34.說說webpack中常見的Plugin布疙?解決了什么問題?

Plugin(Plug-in)是一種計算機應用程序愿卸,它和主應用程序互相交互灵临,以提供特定的功能

是一種遵循一定規(guī)范的應用程序接口編寫出來的程序,只能運行在程序規(guī)定的系統(tǒng)下趴荸,因為其需要調(diào)用原純凈系統(tǒng)提供的函數(shù)庫或者數(shù)據(jù)

webpack中的plugin也是如此儒溉,plugin賦予其各種靈活的功能,例如打包優(yōu)化发钝、資源管理顿涣、環(huán)境變量注入等,它們會運行在?webpack?的不同階段(鉤子 / 生命周期)酝豪,貫穿了webpack整個編譯周期

35.說說你對promise的了解

Promise涛碑,譯為承諾,是異步編程的一種解決方案孵淘,比傳統(tǒng)的解決方案(回調(diào)函數(shù))更加合理和更加強大,解決了回調(diào)地獄的問題

瞬間感受到promise解決異步操作的優(yōu)點:

鏈式操作減低了編碼難度

代碼可讀性明顯增強

狀態(tài)

promise對象僅有三種狀態(tài)

pending(進行中)

fulfilled(已成功)

rejected(已失斊颜稀)

特點

對象的狀態(tài)不受外界影響,只有異步操作的結(jié)果瘫证,可以決定當前是哪一種狀態(tài)

一旦狀態(tài)改變(從pending變?yōu)閒ulfilled和從pending變?yōu)閞ejected)揉阎,就不會再變,任何時候都可以得到這個結(jié)果

Promise構(gòu)造函數(shù)接受一個函數(shù)作為參數(shù)背捌,該函數(shù)的兩個參數(shù)分別是resolve和reject

resolve函數(shù)的作用是毙籽,將Promise對象的狀態(tài)從“未完成”變?yōu)椤俺晒Α?/p>

reject函數(shù)的作用是,將Promise對象的狀態(tài)從“未完成”變?yōu)椤笆?/p>

Promise構(gòu)建出來的實例存在以下方法:

then()

then是實例狀態(tài)發(fā)生改變時的回調(diào)函數(shù)毡庆,第一個參數(shù)是resolved狀態(tài)的回調(diào)函數(shù)坑赡,第二個參數(shù)是rejected狀態(tài)的回調(diào)函數(shù)

catch()

catch()方法是.then(null, rejection)或.then(undefined, rejection)的別名巡扇,用于指定發(fā)生錯誤時的回調(diào)函數(shù)

finally()

finally()方法用于指定不管 Promise 對象最后狀態(tài)如何,都會執(zhí)行的操作

36.async函數(shù)是什么,有什么作用

async/await是什么垮衷?

async/await從字面意思上很好理解厅翔,async是異步的意思,await有等待的意思搀突,而兩者的用法上也是如此刀闷。async用于申明一個function是異步的,而await 用于等待一個異步方法執(zhí)行完成仰迁。

也就是這樣一個過程:

async 表示這是一個 async 函數(shù)甸昏,而 await 只能在這個函數(shù)里面使用。

await 表示在這里等待 await 后面的操作執(zhí)行完畢徐许,再執(zhí)行下一句代碼施蜜。

await 后面緊跟著的最好是一個耗時的操作或者是一個異步操作(方法)。

async和await被稱作是異步的終極解決方案

將異步操作變成同步操作

await可以阻塞當前線程雌隅,將異步操作變成同步翻默,被阻塞的線程并沒有被空閑,而是去執(zhí)行其他的操作

釋放異常(拋出異常)

await可以進行求值操作恰起,當await后面跟的是Promise時修械,如果Promise中的操作是resolve(成功),那么await獲取的就是操作成功時的返回值检盼;如果Promise中的操作是reject(失敗)肯污,await獲取的就是操作失敗時的返回值,并且如果在await上加了try catch吨枉,是可以捕捉到異常的

async的作用是將方法的返回值封裝成Promise

37.有使用過vue嗎蹦渣,談談對vue的理解?

vue是什么

Vue.js是一個用于創(chuàng)建用戶界面的漸進式開源JavaScript框架貌亭,也是一個創(chuàng)建單頁應用的Web應用框架

Vue核心特性

#數(shù)據(jù)驅(qū)動(MVVM)

MVVM表示的是?Model-View-ViewModel

Model:模型層柬唯,負責處理業(yè)務邏輯以及和服務器端進行交互

View:視圖層:負責將數(shù)據(jù)模型轉(zhuǎn)化為UI展示出來,可以簡單的理解為HTML頁面

ViewModel:視圖模型層属提,用來連接Model和View权逗,是Model和View之間的通信橋梁

組件化

1.什么是組件化一句話來說就是把圖形美尸、非圖形的各種邏輯均抽象為一個統(tǒng)一的概念(組件)來實現(xiàn)開發(fā)的模式冤议,在Vue中每一個.vue文件都可以視為一個組件2.組件化的優(yōu)勢

降低整個系統(tǒng)的耦合度,在保持接口不變的情況下师坎,我們可以替換不同的組件快速完成需求恕酸,例如輸入框,可以替換為日歷胯陋、時間蕊温、范圍等組件作具體的實現(xiàn)

調(diào)試方便袱箱,由于整個系統(tǒng)是通過組件組合起來的,在出現(xiàn)問題的時候义矛,可以用排除法直接移除組件发笔,或者根據(jù)報錯的組件快速定位問題,之所以能夠快速定位凉翻,是因為每個組件之間低耦合了讨,職責單一,所以邏輯會比分析整個系統(tǒng)要簡單

提高可維護性制轰,由于每個組件的職責單一前计,并且組件在系統(tǒng)中是被復用的,所以對代碼進行優(yōu)化可獲得系統(tǒng)的整體升級

#指令系統(tǒng)

解釋:指令 (Directives) 是帶有 v- 前綴的特殊屬性作用:當表達式的值改變時垃杖,將其產(chǎn)生的連帶影響男杈,響應式地作用于 DOM

常用的指令

條件渲染指令?v-if

列表渲染指令v-for

屬性綁定指令v-bind

事件綁定指令v-on

雙向數(shù)據(jù)綁定指令v-model

38.你對SPA單頁面的理解,它的優(yōu)缺點分別是什么调俘?如何實現(xiàn)SPA應用呢

SPA(single-page application)伶棒,翻譯過來就是單頁應用SPA是一種網(wǎng)絡應用程序或網(wǎng)站的模型,它通過動態(tài)重寫當前頁面來與用戶交互彩库,這種方法避免了頁面之間切換打斷用戶體驗在單頁應用中苞冯,所有必要的代碼(HTML、JavaScript和CSS)都通過單個頁面的加載而檢索侧巨,或者根據(jù)需要(通常是為響應用戶操作)動態(tài)裝載適當?shù)馁Y源并添加到頁面,頁面在任何時間點都不會重新加載

單頁應用優(yōu)缺點

優(yōu)點:

具有桌面應用的即時性舅锄、網(wǎng)站的可移植性和可訪問性

用戶體驗好、快司忱,內(nèi)容的改變不需要重新加載整個頁面

良好的前后端分離皇忿,分工更明確

缺點:

不利于搜索引擎的抓取

首次渲染速度相對較慢

實現(xiàn)一個SPA

#原理

監(jiān)聽地址欄中hash變化驅(qū)動界面變化

用pushsate記錄瀏覽器的歷史,驅(qū)動界面發(fā)送變化

hash?模式

核心通過監(jiān)聽url中的hash來進行路由跳轉(zhuǎn)(監(jiān)聽url中#后的路徑/hash值,來切換不同的組件,放到router-view上坦仍,完成頁面的一個局部更新 )

history模式

history?模式核心借用?HTML5 history api鳍烁,api?提供了豐富的?router?相關屬性先了解一個幾個相關的api

history.pushState?瀏覽器歷史紀錄添加記錄

history.replaceState修改瀏覽器歷史紀錄中當前紀錄

history.popState?當?history?發(fā)生變化時觸發(fā)

39.SPA首屏加載速度慢的怎么解決?

一繁扎、什么是首屏加載

首屏時間(First Contentful Paint)幔荒,指的是瀏覽器從響應用戶輸入網(wǎng)址地址,到首屏內(nèi)容渲染完成的時間梳玫,此時整個網(wǎng)頁不一定要全部渲染完成爹梁,但需要展示當前視窗需要的內(nèi)容

首屏加載可以說是用戶體驗中最重要的環(huán)節(jié)

二 、加載慢的原因

在頁面渲染的過程提澎,導致加載速度慢的因素可能如下:

網(wǎng)絡延時問題

資源文件體積是否過大

資源是否重復發(fā)送請求去加載了

加載腳本的時候姚垃,渲染內(nèi)容堵塞了

三、解決方案

常見的幾種SPA首屏優(yōu)化方式

減小入口文件體積(使用路由懶加載)

靜態(tài)資源本地緩存(前端利用localstorage)

UI框架按需加載

圖片資源的壓縮

組件重復打包

開啟GZip壓縮

使用SSR

40.Vue路由的實現(xiàn)原理

應用最顯著特點之一就是采用的前端路由系統(tǒng)盼忌,通過改變URL积糯,在不重新請求頁面的情況下掂墓,更新頁面視圖。

更新視圖但不重新請求頁面看成,是前端路由原理的核心之一君编,目前在瀏覽器環(huán)境中這一功能的實現(xiàn)主要有2種方式:

利用URL中的hash("#");

利用History interface在HTML5中新增的方法;

41.Vue中組件和插件有什么區(qū)別?

一川慌、組件是什么

回顧以前對組件的定義:

組件就是把圖形啦粹、非圖形的各種邏輯均抽象為一個統(tǒng)一的概念(組件)來實現(xiàn)開發(fā)的模式,組件是可復用的 Vue 實例, 把一些公共的模塊抽取出來窘游,然后寫成單獨的的工具組件或者頁面,在Vue中每一個.vue文件都可以視為一個組件

組件的優(yōu)勢

降低整個系統(tǒng)的耦合度唠椭,在保持接口不變的情況下,我們可以替換不同的組件快速完成需求忍饰,例如輸入框贪嫂,可以替換為日歷、時間艾蓝、范圍等組件作具體的實現(xiàn)

調(diào)試方便力崇,由于整個系統(tǒng)是通過組件組合起來的,在出現(xiàn)問題的時候赢织,可以用排除法直接移除組件亮靴,或者根據(jù)報錯的組件快速定位問題,之所以能夠快速定位于置,是因為每個組件之間低耦合茧吊,職責單一,所以邏輯會比分析整個系統(tǒng)要簡單

提高可維護性八毯,由于每個組件的職責單一搓侄,并且組件在系統(tǒng)中是被復用的,所以對代碼進行優(yōu)化可獲得系統(tǒng)的整體升級

#二话速、插件是什么

插件通常用來為?Vue?添加全局功能讶踪。插件的功能范圍沒有嚴格的限制——一般有下面幾種:

添加全局方法或者屬性。如:?vue-custom-element

添加全局資源:指令/過濾器/過渡等泊交。如?vue-touch

通過全局混入來添加一些組件選項乳讥。如vue-router

添加?Vue?實例方法,通過把它們添加到?Vue.prototype?上實現(xiàn)廓俭。

一個庫云石,提供自己的?API,同時提供上面提到的一個或多個功能白指。如vue-router

三留晚、兩者的區(qū)別

兩者的區(qū)別主要表現(xiàn)在以下幾個方面:

編寫形式

注冊形式

使用場景:

組件?(Component)?是用來構(gòu)成你的?App?的業(yè)務模塊,它的目標是?App.vue

插件?(Plugin)?是用來增強你的技術棧的功能模塊告嘲,它的目標是?Vue?本身

簡單來說错维,插件就是指對Vue的功能的增強或補充

42.Vue組件之間的通信方式都有哪些?

組件間通信的分類

組件間通信的分類可以分成以下

父子組件之間的通信

兄弟組件之間的通信

祖孫與后代組件之間的通信

非關系組件間之間的通信

組件間通信的方案

整理vue中8種常規(guī)的通信方案

通過 props 傳遞

通過 $emit 觸發(fā)自定義事件

使用 ref

EventBus

$parent 或$root

attrs 與 listeners

Provide 與 Inject

Vuex

小結(jié)

父子關系的組件數(shù)據(jù)傳遞選擇?props?與?$emit進行傳遞橄唬,也可選擇ref

兄弟關系的組件數(shù)據(jù)傳遞可選擇$bus赋焕,其次可以選擇$parent進行傳遞

祖先與后代組件數(shù)據(jù)傳遞可選擇attrs與listeners或者?Provide與?Inject

復雜關系的組件數(shù)據(jù)傳遞可以通過vuex存放共享的變量

43.你了解vue的diff算法嗎?說說看

diff?算法是一種通過同層的樹節(jié)點進行比較的高效算法

vue2中:

其有兩個特點:

比較只會在同層級進行, 不會跨層級比較

在diff比較的過程中仰楚,循環(huán)從兩邊向中間比較

diff?算法在很多場景下都有應用隆判,在?vue?中,作用于虛擬?dom?渲染成真實?dom?的新舊?VNode?節(jié)點比較

vue3中:

事件緩存:將事件緩存僧界,可以理解為變成靜態(tài)的了

添加靜態(tài)標記:Vue2 是全量 Diff侨嘀,Vue3 是靜態(tài)標記 + 非全量 Diff

靜態(tài)提升:創(chuàng)建靜態(tài)節(jié)點時保存,后續(xù)直接復用

使用最長遞增子序列優(yōu)化了對比流程:Vue2 里在 updateChildren() 函數(shù)里對比變更捂襟,在 Vue3 里這一塊的邏輯主要在 patchKeyedChildren() 函數(shù)里咬腕,具體看下面

44.為什么需要Virtual Dom

一、是什么

Real DOM葬荷,真實?DOM涨共,意思為文檔對象模型,是一個結(jié)構(gòu)化文本的抽象宠漩,在頁面渲染出的每一個結(jié)點都是一個真實?DOM?結(jié)構(gòu)举反,如下:

Virtual Dom,本質(zhì)上是以?JavaScript?對象形式存在的對?DOM?的描述

創(chuàng)建虛擬?DOM?目的就是為了更好將虛擬的節(jié)點渲染到頁面視圖中扒吁,虛擬?DOM?對象的節(jié)點與真實?DOM?的屬性一一照應

使用虛擬?DOM?的優(yōu)勢如下:

簡單方便:如果使用手動操作真實?DOM?來完成頁面火鼻,繁瑣又容易出錯,在大規(guī)模應用下維護起來也很困難

性能方面:使用 Virtual DOM雕崩,能夠有效避免真實 DOM 數(shù)頻繁更新凝危,減少多次引起重繪與回流,提高性能

跨平臺:React 借助虛擬 DOM晨逝,帶來了跨平臺的能力蛾默,一套代碼多端運行

兩者的區(qū)別如下:

虛擬 DOM 不會進行排版與重繪操作,而真實 DOM 會頻繁重排與重繪

虛擬 DOM 的總損耗是“虛擬 DOM 增刪改+真實 DOM 差異增刪改+排版與重繪”捉貌,真實 DOM 的總損耗是“真實 DOM 完全增刪改+排版與重繪”

45.Vue3.0的設計目標是什么支鸡?做了哪些優(yōu)化

更小:

Vue3移除一些不常用的?API

引入tree-shaking,可以將無用模塊“剪輯”趁窃,僅打包需要的牧挣,使打包的整體體積變小了

更快:

主要體現(xiàn)在編譯方面:

diff算法優(yōu)化

靜態(tài)提升

事件監(jiān)聽緩存

SSR優(yōu)化

更友好

vue3在兼顧vue2的options API的同時還推出了composition API,大大增加了代碼的邏輯組織和代碼復用能力

TypeScript支持:

Vue3是基于typeScript編寫的醒陆,提供了更好的類型檢查瀑构,能支持復雜的類型推導

API設計一致性:

語法 API

這里當然說的就是composition API,其兩大顯著的優(yōu)化:

優(yōu)化邏輯組織

優(yōu)化邏輯復用

提高自身可維護性

開放更多底層功能

46.Vue3.0 所采用的 Composition Api 與 Vue2.x 使用的 Options Api 有什么不同刨摩?


通常使用Vue2開發(fā)的項目寺晌,普遍會存在以下問題:

代碼的可讀性隨著組件變大而變差

每一種代碼復用的方式世吨,都存在缺點

TypeScript支持有限

然而,當組件變得復雜呻征,導致對應屬性的列表也會增長耘婚,這可能會導致組件難以閱讀和理解

Composition Api

在 Vue3 Composition API 中,組件根據(jù)邏輯功能來組織的陆赋,一個功能所定義的所有 API 會放在一起(更加的高內(nèi)聚沐祷,低耦合)

即使項目很大,功能很多攒岛,我們都能快速的定位到這個功能所用到的所有 API

三赖临、對比

下面對Composition Api與Options Api進行兩大方面的比較?邏輯組織 邏輯復用

邏輯組織:

Options API

可以看到,這種碎片化使得理解和維護復雜組件變得困難

選項的分離掩蓋了潛在的邏輯問題灾锯。此外兢榨,在處理單個邏輯關注點時,我們必須不斷地“跳轉(zhuǎn)”相關代碼的選項塊

#Compostion API

而Compositon API正是解決上述問題挠进,將某個邏輯關注點相關的代碼全都放在一個函數(shù)里色乾,這樣當需要修改一個功能時,就不再需要在文件中跳來跳去

下面舉個簡單例子领突,將處理count屬性相關的代碼放在同一個函數(shù)了

邏輯復用

使用單個mixin似乎問題不大暖璧,但是當我們一個組件混入大量不同的?mixins?的時候

會存在兩個非常明顯的問題:

命名沖突

數(shù)據(jù)來源不清晰

小結(jié)

在邏輯組織和邏輯復用方面,Composition API是優(yōu)于Options API

因為Composition API幾乎是函數(shù)君旦,會有更好的類型推斷澎办。

Composition API對?tree-shaking?友好,代碼也更容易壓縮

Composition API中見不到this的使用金砍,減少了this指向不明的情況

如果是小型組件局蚀,可以繼續(xù)使用Options API,也是十分友好的

47.說一下Vue數(shù)據(jù)響應式的原理

意思就是在改變數(shù)據(jù)的時候恕稠,視圖會跟著更新琅绅。這意味著你只需要進行數(shù)據(jù)的管理,給我們搬磚提供了很大的便利鹅巍。React也有這種特性千扶,但是React的響應式方式跟VUE完全不同。

“vue的數(shù)據(jù)響應式就是當數(shù)據(jù)發(fā)生變化骆捧,通知改變的代碼澎羞。數(shù)據(jù)響應式原理的核心就是采用了數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式來實現(xiàn)數(shù)據(jù)的響應式,通過Object.defineProperty()對數(shù)據(jù)進行攔截,把這些屬性全部轉(zhuǎn)換成getter/setter敛苇,get()方法可以讀取數(shù)據(jù)妆绞、收集依賴,set()方法可以改寫數(shù)據(jù),在數(shù)據(jù)變動時會對數(shù)據(jù)進行比較括饶,如果數(shù)據(jù)發(fā)生了變化株茶,會發(fā)布消息通知訂閱者,觸發(fā)監(jiān)聽回調(diào)巷帝,更新視圖忌卤±匏停”

React是通過this.setState去改變數(shù)據(jù)蒲拉,然后根據(jù)新的數(shù)據(jù)重新渲染出虛擬DOM贫奠,最后通過對比虛擬DOM找到需要更新的節(jié)點進行更新。

也就是說React是依靠著虛擬DOM以及DOM的diff算法做到這一點的堕阔。而關于React這方面的文章,我已經(jīng)寫了很多了颗味,還不了解的同學可以自行復習一下超陆。

而VUE則是利用了Object.defineProperty的方法里面的setter 與getter方法的觀察者模式來實現(xiàn)。

所以在學習VUE的響應式原理之前浦马,先學習兩個預備知識:

Object.defineProperty 與 觀察者模式时呀。

如果你已經(jīng)掌握了,可以直接跳到第三part晶默。

二谨娜、預備知識

2.1?Object.defineProperty

這個方法就是在一個對象上定義一個新的屬性,或者改變一個對象現(xiàn)有的屬性磺陡,并且返回這個對象趴梢。里面有兩個字段 set,get。顧名思義币他,set都是取設置屬性的值坞靶,而get就是獲取屬性的值。

舉個栗子:

varbValue;

varo={};

Object.defineProperty(o,"b",

{get:function(){console.log('監(jiān)聽正在獲取b')returnbValue;},

set:function(newValue){console.log('監(jiān)聽正在設置b')bValue=newValue;},

enumerable:true,configurable:true});

o.b=38;console.log(o.b)

最終打印

監(jiān)聽正在設置b監(jiān)聽正在獲取b38

從在上述栗子中蝴悉,可以看到當我們對 o.b 賦值38的時候彰阴,就會調(diào)用set函數(shù),這時候會通知訂閱者觸發(fā)指令update函數(shù)給bValue修改值拍冠,之后我們就可以通過o.b來獲取這個值尿这,這時候,get函數(shù)被調(diào)用倦微。

掌握到這一步妻味,我們已經(jīng)可以實現(xiàn)一個極簡的VUE雙向綁定了。

48.說說對 React 的理解欣福?有哪些特性责球?

一、是什么

React,用于構(gòu)建用戶界面的 JavaScript 庫雏逾,只提供了 UI 層面的解決方案

遵循組件設計模式嘉裤、聲明式編程范式和函數(shù)式編程概念,以使前端應用程序更高效

使用虛擬?DOM?來有效地操作?DOM栖博,遵循從高階組件到低階組件的單向數(shù)據(jù)流

幫助我們將界面成了各個獨立的小塊屑宠,每一個塊就是組件,這些組件之間可以組合仇让、嵌套典奉,構(gòu)成整體頁面

react?類組件使用一個名為?render()?的方法或者函數(shù)組件return,接收輸入的數(shù)據(jù)并返回需要展示的內(nèi)容

二丧叽、特性

React?特性有很多卫玖,如:

JSX 語法

單向數(shù)據(jù)綁定

虛擬 DOM:

當組件(是Virtual DOM上的組件)的狀態(tài)(state)發(fā)生改變時,一個神奇的diff算法會計算出最少的步驟更新到瀏覽器頁面上踊淳,diff算法尋找到需要變更的DOM節(jié)點假瞬,然后把這個修改更新到瀏覽器的DOM節(jié)點上。

聲明式編程:

而用?React?實現(xiàn)上述功能則如下:

<Mapzoom={4}center={(lat,lng)}>? <Markerposition={(lat,lng)}title={"Hello Marker"}/></Map>

聲明式編程方式使得?React?組件很容易使用迂尝,最終的代碼簡單易于維護

Component

49.說說 Real DOM 和 Virtual DOM 的區(qū)別脱茉?優(yōu)缺點?

一垄开、是什么

Real DOM琴许,真實?DOM,意思為文檔對象模型说榆,是一個結(jié)構(gòu)化文本的抽象虚吟,在頁面渲染出的每一個結(jié)點都是一個真實?DOM?結(jié)構(gòu),如下:

Virtual Dom签财,本質(zhì)上是以?JavaScript?對象形式存在的對?DOM?的描述

創(chuàng)建虛擬?DOM?目的就是為了更好將虛擬的節(jié)點渲染到頁面視圖中串慰,虛擬?DOM?對象的節(jié)點與真實?DOM?的屬性一一照應

二、區(qū)別

兩者的區(qū)別如下:

虛擬 DOM 不會進行排版與重繪操作唱蒸,而真實 DOM 會頻繁重排與重繪

虛擬 DOM 的總損耗是“虛擬 DOM 增刪改+真實 DOM 差異增刪改+排版與重繪”邦鲫,真實 DOM 的總損耗是“真實 DOM 完全增刪改+排版與重繪”

三、優(yōu)缺點

真實?DOM?的優(yōu)勢:易用

缺點:

效率低神汹,解析速度慢庆捺,內(nèi)存占用量過高

性能差:頻繁操作真實 DOM,易于導致重繪與回流

使用虛擬?DOM?的優(yōu)勢如下:

簡單方便:如果使用手動操作真實?DOM?來完成頁面屁魏,繁瑣又容易出錯滔以,在大規(guī)模應用下維護起來也很困難

性能方面:使用 Virtual DOM,能夠有效避免真實 DOM 數(shù)頻繁更新氓拼,減少多次引起重繪與回流你画,提高性能

跨平臺:React 借助虛擬 DOM抵碟,帶來了跨平臺的能力,一套代碼多端運行

缺點:

在一些性能要求極高的應用中虛擬 DOM 無法進行針對性的極致優(yōu)化

首次渲染大量 DOM 時坏匪,由于多了一層虛擬 DOM 的計算拟逮,速度比正常稍慢

50.說說React 生命周期有哪些不同階段?每個階段對應的方法是适滓?

一敦迄、是什么

React整個組件生命周期包括從創(chuàng)建、初始化數(shù)據(jù)凭迹、編譯模板罚屋、掛載Dom→渲染、更新→渲染蕊苗、卸載等一系列過程

二沿后、流程

這里主要講述react16.4之后的生命周期沿彭,可以分成三個階段:

創(chuàng)建階段:

創(chuàng)建階段主要分成了以下幾個生命周期方法:

constructor:在 React 組件掛載之前朽砰,會調(diào)用它的構(gòu)造函數(shù)。

getDerivedStateFromProps:組件創(chuàng)建和更新階段喉刘,不論是props變化還是state變化瞧柔,也會調(diào)用

在每次render方法前調(diào)用,第一個參數(shù)為即將更新的props睦裳,第二個參數(shù)為上一個狀態(tài)的state造锅,可以比較

props?和?state來加一些限制條件,防止無用的state更新,該方法需要返回一個新的對象作為新的state或者返回null

表示state狀態(tài)不需要更新

render:類組件必須實現(xiàn)的方法廉邑,用于渲染DOM結(jié)構(gòu)哥蔚,可以訪問組件state與prop屬性

componentDidMount:組件掛載到真實DOM節(jié)點后執(zhí)行,其在render方法之后執(zhí)行

更新階段:

該階段的函數(shù)主要為如下方法:

getDerivedStateFromProps:同上

shouldComponentUpdate:用于控制組件重新渲染的生命周期蛛蒙,state發(fā)生變化糙箍,組件會進入重新渲染的流程,在這里return false可以阻止組件的更新

render:render() 方法是 class 組件中唯一必須實現(xiàn)的方法牵祟。

getSnapshotBeforeUpdate:觸發(fā)時間為update發(fā)生的時候深夯,在render之后dom渲染之前返回一個值, 讀取到的 DOM 元素狀態(tài)是可以保證與 componentDidUpdate 中一致的

componentDidUpdate:?每次state改變并重新渲染頁面后都會進入這個生命周期卸載或銷毀階段

卸載階段:

componentWillUnmount:在此處完成組件的卸載和數(shù)據(jù)的銷毀诺苹。

51.說說 React中的setState執(zhí)行機制

一個組件的顯示形態(tài)可以由數(shù)據(jù)狀態(tài)和外部參數(shù)所決定咕晋,而數(shù)據(jù)狀態(tài)就是state, 當需要修改里面的值的狀態(tài)需要通過調(diào)用setState來改變,從而達到更新組件內(nèi)部數(shù)據(jù)的作用

setState第一個參數(shù)可以是一個對象收奔,或者是一個函數(shù)掌呜,而第二個參數(shù)是一個回調(diào)函數(shù),用于可以實時的獲取到更新之后的數(shù)據(jù)

在使用setState更新數(shù)據(jù)的時候坪哄,setState的更新類型分成:同步更新质蕉,異步更新

在組件生命周期或React合成事件中呢撞,setState是異步

在setTimeout或者原生dom事件中,setState是同步

對同一個值進行多次 setState饰剥, setState 的批量更新策略會對其進行覆蓋殊霞,取最后一次的執(zhí)行結(jié)果

52.說說對React中類組件和函數(shù)組件的理解?有什么區(qū)別汰蓉?

語法上:

函數(shù)式組件是一個純函數(shù)绷蹲,它是需要接受props參數(shù)并且返回一個React元素就可以了。類組件是需要繼承React.Component的顾孽,而且class組件需要創(chuàng)建render并且返回React元素祝钢,語法上來講更復雜。

狀態(tài)管理:

函數(shù)式組件沒有狀態(tài)管理若厚,類組件有狀態(tài)管理拦英。

調(diào)用方式:

函數(shù)式組件可以直接調(diào)用,返回一個新的React元素测秸;類組件在調(diào)用時是需要創(chuàng)建一個實例的疤估,然后通過調(diào)用實例里的render方法來返回一個React元素。

53.說說對React Hooks的理解霎冯?解決了什么問題铃拇?

一、是什么

Hook?是 React 16.8 的新增特性沈撞。它可以讓你在不編寫?class?的情況下使用?state?以及其他的?React?特性

至于為什么引入hook慷荔,官方給出的動機是解決長時間使用和維護react過程中常遇到的問題,例如:

難以重用和共享組件中的與狀態(tài)相關的邏輯

邏輯復雜的組件難以開發(fā)與維護缠俺,當我們的組件需要處理多個互不相關的 local state 時显晶,每個生命周期函數(shù)中可能會包含著各種互不相關的邏輯在里面

類組件中的this增加學習成本,類組件在基于現(xiàn)有工具的優(yōu)化上存在些許問題

由于業(yè)務變動壹士,函數(shù)組件不得不改為類組件等等

二磷雇、有哪些

上面講到,Hooks讓我們的函數(shù)組件擁有了類組件的特性墓卦,例如組件內(nèi)的狀態(tài)倦春、生命周期

最常見的hooks有如下:

useState

useEffect

useReducer

useCallback

useMemo

useRef

三、解決什么

通過對上面的初步認識落剪,可以看到hooks能夠更容易解決狀態(tài)相關的重用的問題:

每調(diào)用useHook一次都會生成一份獨立的狀態(tài)

通過自定義hook能夠更好的封裝我們的功能

54.說說你對Redux的理解睁本?其工作原理

一、是什么

在react中每個組件的state是由自身進行管理忠怖,包括組件定義自身的state呢堰、組件之間的通信通過props傳遞、使用Context實現(xiàn)數(shù)據(jù)共享等凡泣,如果讓每個組件都存儲自身相關的狀態(tài)枉疼,理論上來講不會影響應用的運行皮假,但在開發(fā)及后期我們將比較難以維護,所以我們可以把數(shù)據(jù)進行集中式的管理骂维,redux就是一個實現(xiàn)上述集中管理的容器的工具惹资,redux并不是只應用在react中,還與其他界面庫一起使用航闺,如Vue

二褪测、工作原理

創(chuàng)建一個store文件夾,新建一個index.js文件

文件中導入redux的createStore方法潦刃,用于創(chuàng)建公共數(shù)據(jù)區(qū)域

創(chuàng)建一個reducer純函數(shù)侮措,接受兩個參數(shù)state,actions分別表示分別表示數(shù)據(jù)和操作state的方法乖杠,返回state數(shù)據(jù)給組件頁面

把reducer作為createStore的參數(shù)拋出

在需要使用的頁面導入store文件分扎,通過store.getState獲取數(shù)據(jù),通過store.dispatch觸發(fā)action修改state數(shù)據(jù)

store.subscrible 方法監(jiān)聽 store 的改變胧洒,避免數(shù)據(jù)不更新

55.說說React 性能優(yōu)化的手段有哪些

一畏吓、是什么

React憑借virtual DOM和diff算法擁有高效的性能,但是某些情況下略荡,性能明顯可以進一步提高

在前面文章中庵佣,我們了解到類組件通過調(diào)用setState方法, 就會導致render汛兜,父組件一旦發(fā)生render渲染,子組件一定也會執(zhí)行render渲染

二通今、如何做

React中如何避免不必要的render?(opens new window)中粥谬,我們了解到如何避免不必要的render來應付上面的問題,主要手段是通過shouldComponentUpdate辫塌、PureComponent漏策、React.memo,這三種形式這里就不再復述

除此之外臼氨, 常見性能優(yōu)化常見的手段有如下:

避免使用內(nèi)聯(lián)函數(shù)

使用 React Fragments 避免額外標記

使用 Immutable:

理解Immutable中?(opens new window)掺喻,我們了解到使用?Immutable可以給?React?應用帶來性能的優(yōu)化,主要體現(xiàn)在減少渲染的次數(shù)

在做react性能優(yōu)化的時候储矩,為了避免重復渲染感耙,我們會在shouldComponentUpdate()中做對比,當返回true執(zhí)行render方法

Immutable通過is方法則可以完成對比持隧,而無需像一樣通過深度比較的方式比較

懶加載組件:

從工程方面考慮即硼,webpack存在代碼拆分能力,可以為應用創(chuàng)建多個包屡拨,并在運行時動態(tài)加載只酥,減少初始包的大小

而在react中使用到了Suspense和?lazy組件實現(xiàn)代碼拆分功能

事件綁定方式:

從性能方面考慮褥实,在render方法中使用bind和render方法中使用箭頭函數(shù)這兩種形式在每次組件render的時候都會生成新的方法實例,性能欠缺

而constructor中bind事件與定義階段使用箭頭函數(shù)綁定這兩種形式只會生成一個方法實例裂允,性能方面會有所改善

服務端渲染:

采用服務端渲染端方式损离,可以使用戶更快的看到渲染完成的頁面

服務端渲染,需要起一個node服務绝编,可以使用express草冈、koa等,調(diào)用react的renderToString方法瓮增,將根組件渲染成字符串怎棱,再輸出到響應中

56.vue、react绷跑、angular區(qū)別

1. 基本概念

Angular 是一個應用設計框架與開發(fā)平臺拳恋,用于創(chuàng)建高效、復雜砸捏、精致的單頁面應用谬运。

React 是一個用于構(gòu)建用戶界面的 JavaScript 庫

Vue (讀音 /vju?/,類似于 view) 是一套用于構(gòu)建用戶界面的漸進式框架垦藏。與其它大型框架不同的是梆暖,Vue 被設計為可以自底向上逐層應用。Vue 的核心庫只關注視圖層掂骏,不僅易于上手轰驳,還便于與第三方庫或既有項目整合。另一方面弟灼,當與現(xiàn)代化的工具鏈以及各種支持類庫結(jié)合使用時级解,Vue 也完全能夠為復雜的單頁應用提供驅(qū)動。

2. 三者比較

2.1 相同點

1.? ? 都是基于javascript/typescript的前端開發(fā)庫田绑,為前端開發(fā)提供高效勤哗、復用性高的開發(fā)方式

2.? ? 都有組件和模板的開發(fā)思想

3.? ? 各自的組件都有生命周期,不用的組件可以卸載掩驱,不占用資源

4.? 都支持指令芒划,如樣式、事件等的指令

2.2 不同點

1.? 創(chuàng)始和發(fā)行不同:

? ? ? ? Angular是由googl提供支持的欧穴,初始發(fā)行于 2016年9月民逼;React由Facebook維護,初始發(fā)行于 2013年3月苔可;Vue是由前google人員創(chuàng)建缴挖,初始發(fā)行于2014年2月

2.? 應用類型不同:

? ? ? ? Angular支持開發(fā)native應用程序、SPA單頁應用程序焚辅、混合應用程序和web應用程序映屋;React支持開發(fā)SPA和移動應用程序苟鸯;Vue支持開發(fā)高級SPA,開始支持native應用程序

3.? 模型不同

? ? ? ? angular基于MVC(模型-視圖-控制器)架構(gòu)棚点;react和vue是基于Virtual DOM(虛擬的文檔對象模型)

4.? 數(shù)據(jù)流流向不同

? ? ? Angular使用的是雙向數(shù)據(jù)綁定早处,React用的是單數(shù)據(jù)流的,而Vue則支持兩者瘫析。

5. 對微應用和微服務的支持不同

? ? ? ? Angular使用的是TypeScript砌梆,因此它更適合于單頁Web應用(single page web application,SPA)贬循,而非微服務咸包。相反,React和Vue的靈活性更適合微應用和微服務的開發(fā)杖虾。

6. 對原生應用的支持不同

? ? ? ? React Native為iOS和Android開發(fā)原生應用烂瘫;Angular的NativeScript已被原生應用所采用,特別是Ionic框架已經(jīng)被廣泛地運用在制作混合應用等方面奇适;Vue的Weex平臺正在開發(fā)之中坟比,尚無下一步使之成為全面跨平臺的計劃。

7. 框架和庫

? ? ? ? Angular 是一個框架而不是一個庫嚷往,因為它提供了關于如何構(gòu)建應用程序的強有力的約束葛账,并且還提供了更多開箱即用的功能。React 和 Vue 是是一種庫皮仁,可以和各種包搭配籍琳。

8. 組件之間傳值方式不同

? ? Angular 中直接的父子組件,父組件可以直接訪問子組件的 public 屬性和方法魂贬,也可以借助于@Input 和 @Output 進行通訊巩割。沒有直接關系的,借助于 Service 單例進行通訊付燥;React 組件之間通過通過prop或者state來通信,不同組件之間還有Rex狀態(tài)管理功能愈犹;Vue組件之間通信通過props 键科,以及Vuex狀態(tài)管理來傳值

57.說說你對 TypeScript 的理解?與 JavaScript 的區(qū)別漩怎?

一勋颖、是什么

TypeScript?是?JavaScript?的類型的超集,支持ES6語法勋锤,支持面向?qū)ο缶幊痰母拍罘沽幔珙悺⒔涌谌础⒗^承茄厘、泛型等

其是一種靜態(tài)類型檢查的語言矮冬,提供了類型注解,在代碼編譯階段就可以檢查出數(shù)據(jù)類型的錯誤

同時擴展了JavaScript?的語法次哈,所以任何現(xiàn)有的JavaScript?程序可以不加改變的在?TypeScript?下工作

為了保證兼容性胎署,TypeScript?在編譯階段需要編譯器編譯成純?JavaScript?來運行,是為大型應用之開發(fā)而設計的語言

二窑滞、特性

TypeScript?的特性主要有如下:

類型批注和編譯時類型檢查?:在編譯時批注變量類型

類型推斷:ts 中沒有批注變量類型會自動推斷變量的類型

類型擦除:在編譯過程中批注的內(nèi)容和接口會在運行時利用工具擦除

接口:ts 中用接口來定義對象類型

枚舉:用于取值被限定在一定范圍內(nèi)的場景

Mixin:可以接受任意類型的值

泛型編程:寫代碼時使用一些以后才指定的類型

名字空間:名字只在該區(qū)域內(nèi)有效琼牧,其他區(qū)域可重復使用該名字而不沖突

元組:元組合并了不同類型的對象,相當于一個可以裝不同類型數(shù)據(jù)的數(shù)組

三哀卫、區(qū)別

TypeScript 是 JavaScript 的超集巨坊,擴展了 JavaScript 的語法

TypeScript 可處理已有的 JavaScript 代碼,并只對其中的 TypeScript 代碼進行編譯

TypeScript 文件的后綴名 .ts (.ts此改,.tsx趾撵,.dts),JavaScript 文件是 .js

在編寫 TypeScript 的文件的時候就會自動編譯成 js 文件

58.說說你對 TypeScript 中泛型的理解带斑?應用場景鼓寺?

一、是什么

泛型程序設計(generic programming)是程序設計語言的一種風格或范式

泛型允許我們在強類型程序設計語言中編寫代碼時使用一些以后才指定的類型勋磕,在實例化時作為參數(shù)指明這些類型 在typescript中妈候,定義函數(shù),接口或者類的時候挂滓,不預先定義好具體的類型苦银,而在使用的時候在指定類型的一種特性

二、應用場景

通過上面初步的了解赶站,后述在編寫?typescript?的時候幔虏,定義函數(shù),接口或者類的時候贝椿,不預先定義好具體的類型想括,而在使用的時候在指定類型的一種特性的時候,這種情況下就可以使用泛型

靈活的使用泛型定義類型烙博,是掌握typescript?必經(jīng)之路

59.說說你對微信小程序的理解瑟蜈?優(yōu)缺點?

一渣窜、是什么

小程序是一種不需要下載安裝即可使用的應用铺根,它實現(xiàn)了應用“觸手可及”的夢想,用戶掃一掃或者搜一下即可打開應用

也體現(xiàn)了“用完即走”的理念乔宿,用戶不用關心是否安裝太多應用的問題位迂。應用將無處不在,隨時可用,但又無需安裝卸載

二掂林、優(yōu)缺點

優(yōu)點:

隨搜隨用臣缀,用完即走:使得小程序可以代替許多APP,或是做APP的整體嫁接党饮,或是作為閹割版功能的承載體

流量大肝陪,易接受:小程序借助自身平臺更加容易引入更多的流量

安全

開發(fā)門檻低

降低兼容性限制

缺點:

用戶留存:及相關數(shù)據(jù)顯示,小程序的平均次日留存在13%左右刑顺,但是雙周留存驟降到僅有1%

體積限制:微信小程序只有2M的大小氯窍,這樣導致無法開發(fā)大型一些的小程序

受控微信:比起APP,尤其是安卓版的高自由度蹲堂,小程序要面對很多來自微信的限制狼讨,從功能接口,甚至到類別內(nèi)容柒竞,都要接受微信的管控

60.說說你對發(fā)布訂閱政供、觀察者模式的理解?區(qū)別朽基?

一布隔、觀察者模式

觀察者模式定義了對象間的一種一對多的依賴關系,當一個對象的狀態(tài)發(fā)生改變時稼虎,所有依賴于它的對象都將得到通知衅檀,并自動更新

觀察者模式屬于行為型模式,行為型模式關注的是對象之間的通訊霎俩,觀察者模式就是觀察者和被觀察者之間的通訊

二哀军、發(fā)布訂閱模式

發(fā)布-訂閱是一種消息范式,消息的發(fā)送者(稱為發(fā)布者)不會將消息直接發(fā)送給特定的接收者(稱為訂閱者)打却。而是將發(fā)布的消息分為不同的類別杉适,無需了解哪些訂閱者(如果有的話)可能存在

同樣的,訂閱者可以表達對一個或多個類別的興趣柳击,只接收感興趣的消息猿推,無需了解哪些發(fā)布者存在

三、區(qū)別

在觀察者模式中捌肴,觀察者是知道Subject的彤守,Subject一直保持對觀察者進行記錄。然而哭靖,在發(fā)布訂閱模式中,發(fā)布者和訂閱者不知道對方的存在侈离。它們只有通過消息代理進行通信近弟。

在發(fā)布訂閱模式中漫雷,組件是松散耦合的惩系,正好和觀察者模式相反敌呈。

觀察者模式大多數(shù)時候是同步的,比如當事件觸發(fā)震桶,Subject就會去調(diào)用觀察者的方法。而發(fā)布-訂閱模式大多數(shù)時候是異步的(使用消息隊列)

61.項目做過哪些性能優(yōu)化

一、體驗優(yōu)化

從用戶角度而言坯沪,優(yōu)化能夠讓頁面加載得更快、對用戶的操作響應得更及時擒滑,能夠給用戶提供更為友好的體驗腐晾。

1,首屏渲染優(yōu)化丐一,請求少藻糖、加載體積小、善用緩存

2库车,動畫優(yōu)化巨柒,避免某些動畫造成頁面的卡頓

3,優(yōu)化用戶的操作感官柠衍,提升視覺反饋洋满,比如 hover 小手,讓用戶一眼就知道是否可操作

4珍坊,長列表復用 dom牺勾,優(yōu)化滾動效果及頁面卡頓現(xiàn)象,減少頁面一次性渲染的數(shù)量

5垫蛆,骨架屏的使用

6禽最,組件的預加載,懶加載

二袱饭、提升頁面性能

減少 http 請求 和 冗余數(shù)據(jù)

組件川无,路由懶加載

配置 nginx 優(yōu)化

優(yōu)化 webpack 打包機制

使用 CDN

預渲染

SSR

圖片轉(zhuǎn) base64

后臺分布式部署,負載均衡

62.描述瀏覽器的渲染過程虑乖,DOM樹和渲染樹的區(qū)別

瀏覽器的渲染過程:

解析 HTML 構(gòu)建 DOM(DOM 樹)懦趋,并行請求 css/image/js

CSS 文件下載完成,開始構(gòu)建 CSSOM(CSS 樹)

CSSOM 構(gòu)建結(jié)束后疹味,和 DOM 一起生成 Render Tree(渲染樹)

布局(Layout):計算出每個節(jié)點在屏幕中的位置

顯示(Painting):通過顯卡把頁面畫到屏幕上

DOM 樹 和 渲染樹 的區(qū)別:

DOM 樹與 HTML 標簽一一對應仅叫,包括 head 和隱藏元素

渲染樹不包括 head 和隱藏元素,大段文本的每一個行都是獨立節(jié)點糙捺,每一個節(jié)點都有對應的 css 屬性

63.你認為什么樣的前端代碼是好的

1.如何評價代碼質(zhì)量的高低诫咱?

代碼質(zhì)量的評價有很強的主觀性,描述代碼質(zhì)量的詞匯也有很多洪灯,比如可讀性坎缭、可維護性、靈活、優(yōu)雅掏呼、簡潔等坏快,這些詞匯是從不同的維度去評價代碼質(zhì)量的。它們之間有互相作用憎夷,并不是獨立的莽鸿,比如,代碼的可讀性好拾给、可擴展性好就意味著代碼的可維護性好祥得。代碼質(zhì)量高低是一個綜合各種因素得到的結(jié)論。我們并不能通過單一的維度去評價一段代碼的好壞鸣戴。

2.最常用的評價標準有哪幾個啃沪?

最常用到幾個評判代碼質(zhì)量的標準是:可維護性、可讀性窄锅、可擴展性创千、靈活性、簡潔性入偷、可復用性追驴、可測試性。其中疏之,可維護性殿雪、可讀性、可擴展性又是提到最多的锋爪、最重要的三個評價標準丙曙。

64.從瀏覽器地址欄輸入url到顯示頁面的步驟

瀏覽器根據(jù)請求的 URL 交給 DNS 域名解析,找到真實 IP其骄,向服務器發(fā)起請求亏镰;

服務器交給后臺處理完成后返回數(shù)據(jù),瀏覽器接收文件(HTML拯爽、JS索抓、CSS、圖像等)毯炮;

瀏覽器對加載到的資源(HTML逼肯、JS、CSS 等)進行語法解析桃煎,建立相對應的內(nèi)部數(shù)據(jù)結(jié)構(gòu)(如 HTML 的 DOM)篮幢;

載入解析到的資源文件,渲染頁面为迈,完成洲拇。

65.http請求報文響應報文的格式

HTTP請求報文格式

客戶端連上服務器后奈揍,向服務器發(fā)出獲取某個Web資源的消息,稱之為客戶端向服務器發(fā)送了一個HTTP請求赋续。

HTTP請求報文主要由

請求行(說明請求類型,要訪問的資源以及使用http版本)

請求頭部(用來說明服務器要使用的附加信息)

空行另患、請求正文組成纽乱。

例如,GET /index.html HTTP/1.1

HTTP響應報文格式

所謂響應其實就是服務器對請求處理的結(jié)果昆箕,或者如果瀏覽器請求的直接就是一個靜態(tài)資源的話鸦列,響應的就是這個資源本身。HTTP響應報文主要由:

狀態(tài)行(http協(xié)議版本號鹏倘,狀態(tài)碼薯嗤,狀態(tài)信息)

消息頭部(用來說明客戶端要使用的一些附加信息)

空行、響應正文組成纤泵。

66.Token cookie session 區(qū)別

1.Session會話:客戶端A訪問服務器骆姐,服務器存儲A的數(shù)據(jù)value,把key返回給客戶端A捏题,客戶端A下次帶著key(session?ID)來訪問服務器玻褪,服務器就能給出客戶端A的數(shù)據(jù)。如果負載均衡公荧,客戶端A訪問了另一個服務器带射,那個服務器沒有客戶端A的數(shù)據(jù)。

2.Cookie:客戶端A訪問服務器循狰,服務器返回cookie給客戶端A窟社,客戶端A存儲cookie,下次需要帶著cookie訪問服務器绪钥,服務器返回相應的數(shù)據(jù)灿里。

3.Token令牌:客戶端A訪問服務器,服務器給了客戶端token昧识,客戶端A拿著token訪問服務器钠四,服務器驗證token,返回數(shù)據(jù)跪楞。

二缀去、下面詳細介紹一下session、cookie甸祭、token的區(qū)別缕碎,詳細如下:

1.session和cookie區(qū)別:

·??????數(shù)據(jù)存放位置不同:Session數(shù)據(jù)是存在服務器中的,cookie數(shù)據(jù)存放在瀏覽器當中池户。

·??????安全程度不同:cookie放在服務器中不是很安全咏雌,session放在服務器中凡怎,相對安全。

·??????性能使用程度不同:session放在服務器上赊抖,訪問增多會占用服務器的性能统倒;考慮到減輕服務器性能方面,應使用cookie氛雪。

·??????數(shù)據(jù)存儲大小不同:單個cookie保存的數(shù)據(jù)不能超過4K房匆,session存儲在服務端,根據(jù)服務器大小來定报亩。

2.token和session區(qū)別:

·??????token是開發(fā)定義的浴鸿,session是http協(xié)議規(guī)定的;

·??????token不一定存儲弦追,session存在服務器中岳链;

·??????token可以跨域,session不可以跨域劲件,它是與域名綁定的掸哑。

67.CORS跨域的原理

什么是 CORS?

CORS?全稱?Cross-Origin Resource Sharing寇仓,即跨域資源共享举户。

CORS?是一種基于?HTTP Header?的機制,該機制通過允許服務器標示除了它自己以外的其它域遍烦。服務器端配合瀏覽器實現(xiàn)?CORS?機制俭嘁,可以突破瀏覽器對跨域資源訪問的限制,實現(xiàn)跨域資源請求服猪。

CORS 驗證機制

CORS?的驗證機制分兩種模式:簡單請求和預檢請求供填。

簡單請求

簡單請求模式下瀏覽器直接發(fā)送請求,并在請求頭中攜帶?Origin罢猪。 服務器端接到請求后近她,會根據(jù)自己的跨域規(guī)則,通過響應頭?Access-Control-Allow-Origin?來返回驗證結(jié)果膳帕。

預檢請求

需要預檢的請求必須首先使用?OPTIONS?方法發(fā)起一個預檢請求到服務器粘捎,服務器基于預檢請求的信息來判斷是否接受接下來的實際請求。

68.什么是MVVM

1危彩、什么是MVVM

MVVM攒磨,是Model-View-ViewModel的簡寫,是M-V-VM三部分組成汤徽。

Model:模型層娩缰,負責處理業(yè)務邏輯以及和服務器端進行交互

View:視圖層:負責將數(shù)據(jù)模型轉(zhuǎn)化為UI展示出來,可以簡單的理解為HTML頁面

ViewModel:視圖模型層谒府,用來連接Model和View拼坎,是Model和View之間的通信橋梁

MVVM采用雙向數(shù)據(jù)綁定浮毯,view中數(shù)據(jù)變化將自動反映到viewmodel上,反之泰鸡,model中數(shù)據(jù)變化也將會自動展示在頁面上债蓝。把Model和View關聯(lián)起來的就是ViewModel。ViewModel負責把Model的數(shù)據(jù)同步到View顯示出來鸟顺,還負責把View的修改同步回Model惦蚊。

MVVM核心思想,是關注model的變化讯嫂,讓MVVM框架利用自己的機制自動更新DOM,也就是所謂的數(shù)據(jù)-視圖分離兆沙,數(shù)據(jù)不會影響視圖欧芽。

69.說說你對版本管理的理解?常用的版本管理工具有哪些葛圃?

一千扔、是什么

版本控制(Version control),是維護工程藍圖的標準作法库正,能追蹤工程藍圖從誕生一直到定案的過程曲楚。此外,版本控制也是一種軟件工程技巧褥符,借此能在軟件開發(fā)的過程中龙誊,確保由不同人所編輯的同一程序文件都得到同步

透過文檔控制,能記錄任何工程項目內(nèi)各個模塊的改動歷程喷楣,并為每次改動編上序號

版本控制系統(tǒng)在當今的軟件開發(fā)中趟大,被認為是理所當然的配備工具之一,根據(jù)類別可以分成:

本地版本控制系統(tǒng)

集中式版本控制系統(tǒng):

SVN

TortoiseSVN是一款非常易于使用的跨平臺的 版本控制/版本控制/源代碼控制軟件

CVS

CVS是版本控制系統(tǒng)铣焊,是源配置管理(SCM)的重要組成部分逊朽。使用它,您可以記錄源文件和文檔的歷史記錄

老牌的版本控制系統(tǒng)曲伊,它是基于客戶端/服務器的行為使得其可容納多用戶叽讳,構(gòu)成網(wǎng)絡也很方便

這一特性使得CVS成為位于不同地點的人同時處理數(shù)據(jù)文件(特別是程序的源代碼)時的首選

分布式版本控制系統(tǒng)

Git

Git是目前世界上最先進的分布式版本控制系統(tǒng),旨在快速高效地處理從小型到大型項目的所有事務

特性:易于學習坟募,占用內(nèi)存小岛蚤,具有閃電般快速的性能

使用Git和Gitlab搭建版本控制環(huán)境是現(xiàn)在互聯(lián)網(wǎng)公司最流行的版本控制方式

HG

Mercurial是一個免費的分布式源代碼管理工具。它可以有效地處理任何規(guī)模的項目婿屹,并提供簡單直觀的界面

Mercurial是一種輕量級分布式版本控制系統(tǒng)灭美,采用?Python語言實現(xiàn),易于學習和使用昂利,擴展性強

三届腐、總結(jié)

版本控制系統(tǒng)的優(yōu)點如下:

記錄文件所有歷史變化铁坎,這是版本控制系統(tǒng)的基本能力

隨時恢復到任意時間點,歷史記錄功能使我們不怕改錯代碼了

支持多功能并行開發(fā)犁苏,通常版本控制系統(tǒng)都支持分支硬萍,保證了并行開發(fā)的可行

多人協(xié)作并行開發(fā),對于多人協(xié)作項目围详,支持多人協(xié)作開發(fā)的版本管理將事半功倍

70.說說你對Git的理解朴乖?

一、是什么

git助赞,是一個分布式版本控制軟件买羞,最初目的是為更好地管理Linux內(nèi)核開發(fā)而設計分布式版本控制系統(tǒng)的客戶端并不只提取最新版本的文件快照,而是把代碼倉庫完整地鏡像下來雹食。這么一來畜普,任何一處協(xié)同工作用的服務器發(fā)生故障,事后都可以用任何一個鏡像出來的本地倉庫恢復(GIT就是一個共享代碼庫群叶,代碼放在網(wǎng)上統(tǒng)一管理吃挑,大家誰修改了代碼都可以在網(wǎng)上改,這樣可以實現(xiàn)多人并發(fā)開發(fā)一個大項目)

項目開始街立,只有一個原始版?zhèn)}庫舶衬,別的機器可以clone這個原始版本庫,那么所有clone的機器赎离,它們的版本庫其實都是一樣的逛犹,并沒有主次之分

所以在實現(xiàn)團隊協(xié)作的時候,只要有一臺電腦充當服務器的角色蟹瘾,其他每個人都從這個“服務器”倉庫clone一份到自己的電腦上圾浅,并且各自把各自的提交推送到服務器倉庫里,也從服務器倉庫中拉取別人的提交

github實際就可以充當這個服務器角色憾朴,其是一個開源協(xié)作社區(qū)狸捕,提供Git倉庫托管服務,既可以讓別人參與你的開源項目众雷,也可以參與別人的開源項目

二灸拍、工作原理

當我們通過git init創(chuàng)建或者git clone一個項目的時候,項目目錄會隱藏一個.git子目錄砾省,其作用是用來跟蹤管理版本庫的

Git?中所有數(shù)據(jù)在存儲前都計算校驗和鸡岗,然后以校驗和來引用,所以在我們修改或者刪除文件的時候编兄,git能夠知道

Git用以計算校驗和的機制叫做 SHA-1 散列(hash轩性,哈希), 這是一個由 40 個十六進制字符(0-9 和 a-f)組成字符串狠鸳,基于 Git 中文件的內(nèi)容或目錄結(jié)構(gòu)計算出來揣苏,如下:

當我們修改文件的時候悯嗓,git就會修改文件的狀態(tài),可以通過git status進行查詢卸察,狀態(tài)情況如下:

已修改(modified):表示修改了文件脯厨,但還沒保存到數(shù)據(jù)庫中。

已暫存(staged):表示對一個已修改文件的當前版本做了標記坑质,使之包含在下次提交的快照中合武。

已提交(committed):表示數(shù)據(jù)已經(jīng)安全的保存在本地數(shù)據(jù)庫中。

文件狀態(tài)對應的涡扼,不同狀態(tài)的文件在Git中處于不同的工作區(qū)域稼跳,主要分成了四部分:

工作區(qū):相當于本地寫代碼的區(qū)域,如 git clone 一個項目到本地吃沪,相當于本地克隆了遠程倉庫項目的一個副本

暫存區(qū):暫存區(qū)是一個文件岂贩,保存了下次將提交的文件列表信息,一般在 Git 倉庫目錄中

本地倉庫:提交更新巷波,找到暫存區(qū)域的文件,將快照永久性存儲到 Git 本地倉庫

遠程倉庫:遠程的倉庫卸伞,如 github

71.說說Git常用的命令有哪些

從上圖可以看到抹镊,git日常簡單的使用就只有上圖6個命令:

add

commit

push

pull

clone

checkout

72.說說 git 發(fā)生沖突的場景?如何解決荤傲?

一垮耳、是什么

一般情況下,出現(xiàn)沖突的場景有如下:

多個分支代碼合并到一個分支時

多個分支向同一個遠端分支推送

具體情況就是遂黍,多個分支修改了同一個文件(任何地方)或者多個分支修改了同一個文件的名稱

如果兩個分支中分別修改了不同文件中的部分终佛,是不會產(chǎn)生沖突,直接合并即可

應用在命令中雾家,就是push铃彰、pull、stash芯咧、rebase等命令下都有可能產(chǎn)生沖突情況牙捉,從本質(zhì)上來講,都是merge和patch(應用補毒挫)時產(chǎn)生沖突

二邪铲、總結(jié)

當Git無法自動合并分支時,就必須首先解決沖突无拗,解決沖突后带到,再提交,合并完成

解決沖突就是把Git合并失敗的文件手動編輯為我們希望的內(nèi)容英染,再提交

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末揽惹,一起剝皮案震驚了整個濱河市被饿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌永丝,老刑警劉巖锹漱,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異慕嚷,居然都是意外死亡哥牍,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門喝检,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嗅辣,“玉大人,你說我怎么就攤上這事挠说≡杼罚” “怎么了?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵损俭,是天一觀的道長蛙奖。 經(jīng)常有香客問我,道長杆兵,這世上最難降的妖魔是什么雁仲? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮琐脏,結(jié)果婚禮上攒砖,老公的妹妹穿的比我還像新娘。我一直安慰自己日裙,他們只是感情好吹艇,可當我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著昂拂,像睡著了一般受神。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上政钟,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天路克,我揣著相機與錄音,去河邊找鬼养交。 笑死精算,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的碎连。 我是一名探鬼主播灰羽,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了廉嚼?” 一聲冷哼從身側(cè)響起玫镐,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎怠噪,沒想到半個月后恐似,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡傍念,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年矫夷,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片憋槐。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡双藕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出阳仔,到底是詐尸還是另有隱情忧陪,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布近范,位于F島的核電站嘶摊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏评矩。R本人自食惡果不足惜更卒,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望稚照。 院中可真熱鬧,春花似錦俯萌、人聲如沸果录。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽弱恒。三九已至,卻和暖如春棋恼,著一層夾襖步出監(jiān)牢的瞬間返弹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工爪飘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留义起,地道東北人。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓师崎,卻偏偏與公主長得像默终,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,630評論 2 359