推薦:兩年前端程序媛從0到18k的逆襲之路 | 2021年中總結css
求點贊+求分享+求評論,哦耶!!!(基本工資有一部分花在付費學習上)html
(文末有彩蛋。。。)。一個朋友,面試的小哥,天天早晨六點起牀學習,三本兩年多經驗拿了年包 50w
的 offer
。某大佬:前端
你看不少,校招24k
白菜價,誰又拿了大廠的offer。你會發現,他們不但學歷高,並且都十分的努力。我我的挺佩服的。vue
學歷低的想拿大的offer
,除了努力提高本身的技術,你別無選擇。捷徑有人能走,可是你想想這我的是否是你。node
Dear developers
6月徐來,年中總結,認識某人三本兩年多經驗拿了年包 50w 的 offer
,經過相識,清晰了職業規劃,發展方向。2021
年的時間進度條也已過半,咱們彼此或多或少經歷了不少不少不平凡的事發生。下面面試了一些大廠,中廠,小廠的經驗。webpack
每一個人都須要 有目標,有職業規劃,有夢想,有向上的心。(固然,若是你沒有,誰也不強求你)ios
在這裏感謝一下:冴羽大佬,字節強哥,浩月等大佬。git
簡歷發給他們後,只修改一次到達他們的認同(不過我卡學歷,除非某些方面很是優秀),我也發現了不少差距,因此接下來準備繼續學習(卷)。es6
淘系:簡歷上,若有學歷硬傷,過不了簡歷評估;簡歷上不能廢話太多,你要是面試官你但願面試官問你哪些地方,你就往哪些地方寫;項目上也只是寫你作過的哪些事情,技術深度,實際的提高等;若是你有博客,文章網站等均可以寫一寫。github
字節:簡歷上,項目經驗不要大量寫業務描述,須要的是一些技術方面的亮點;區分與其餘人的優點,找個好的簡歷模板(這裏推薦 木及簡歷 百度一下就有),若是你是5年如下經驗的,若是一頁寫不完,要麼是大牛,要麼就是提煉不足,因此無論怎樣,提煉到一頁之內寫完。
一些普通的,你只須要在技能欄裏寫如:精通Vue
技術棧便可,(面試官或hr就瞭解關於Vue項目你基本能掌握便可)。
簡歷:簡潔,主題鮮明。
簡歷細節:
1. 熟練掌握JavaScript,TypeScript,Node,CSS以及ES6的新特性
2. 擅長Vue技術棧,以及其生態,某框架及其實現原理,源碼
3. 有良好的數據結構與算法,能熟練在項目中運用設計模式
4. 熟悉HTTP協議,網絡原理,webpack,babel等等
複製代碼
Vue+Vuex+axios+element ui+echarts+es6
開發H5,app端,PC
端(我作過)eslint
配置,文件,組件,函數,變量命,commit
等),自動化promise
- api all,race,any
等,async/await
es6
的fill,includes,find,Object.keys()
promise
,let/const
,axios
,git flow
,branch
分支等es5,es6
的繼承ui
測試,CI/CD
,容器化,DockerFile
,容器編排k8s
監控sentry
HTML5的新標籤:header,sction,footer,aside,nav,main,article,figure,localStorage和sessionStorage,audio/video/svg等。
CSS3的:定位,static,relative,find,absoulte,sticky。
中小廠:
大廠:
初級要:
中級要:
已知足,走向高級開發(我的帶領太小團隊):
ES6 Module和Commonjs區別:
ES6 Module
靜態引入,編譯時引入Commonjs
動態引入,執行時引入ES6 Module
才能靜態分析,實現Tree-Shaking
let apiList = require('../config/api.js')
if(isDev) {
// 動態也引入執行時引入
apiList = require('../config/api.js')
}
import apiList form '../config/api.js'
if(isDev) {
// 編譯時報錯,只能靜態引入
import apiList from '../config/api_dev.js'
}
複製代碼
Scope Hosting
:
// hello.js
export default 'hello'
// main.js
import str from './hello.js'
console.log(str)
複製代碼
webpack
性能優化-產出代碼base64
編碼bundle
加hash
CDN
加速production
Scope Hosting
babel
:前端開發環境必備工具,同webpack
,須要瞭解基本的配置和使用
環境搭建和基本配置:babel-polyfill,babel-runtime
環境搭建:.babelrc
配置:presets
和plugins
core-js
,regenerator
結合,如何按需引入babel-polyfill
,Babel 7.4
以後棄用babel-polyfill
,推薦直接使用core-js
和regenerator
。
babel-polyfill
按需引入:文件較大,只有一部分功能,無需所有引入,配置按需引入。
babel-polyfill
的問題?
web
系統,則無礙;Lib
,則會有問題;babel-runtime
不會污染全局環境:
babel
細分:
拆分配置和merge
;啓動本地服務;處理ES6
;處理樣式;處理圖片;多入口;抽離css文件;抽離公共代碼;懶加載;處理JSX;處理Vue;webpack優化構建速度:優化babel-loader
,IgnorePlugin
,noParse
,happyPacK
,ParalleIUglifyPlugin
。
前端爲什麼打包構建,好處?
Tree-Shaking
,壓縮,合併),加載更快TS,ES6+,模塊化,SCSS
)Polyfill,postcss,eslint
)經過打包和構建,能夠統一,高效的開發環境;統一的構建流程和產出標準,集成公司構建規範(提測,上線等)。
module, chunk, bundle的區別?
module
各個源碼文件,webpack
中一切皆模塊chunk
多模塊合併成的,如entry
,import()
,splitChunk
bundle
最終的輸出文件loader
和plugin
的區別:loader
模塊轉換器,如less-css
;plugin
擴展插件,如:HtmlWebpackPlugin
。
babel
和webpack
的區別?
babel
-js
新語法編譯工具,不關心模塊化。webpack
-打包構建工具,是多個loader
,plugin
的集合如何產生一個lib
?參考webpack.dll.js ouput library.
output: {
// lib的文件名
filename: 'lodash.js',
// 輸出lib到dist目錄下
path: disPath,
library: 'lodash',
},
複製代碼
爲什麼Proxy
不能被Polyfill
?
Class
能夠用function
模擬Promise
能夠用callback
來模擬Proxy
的功能用Object.defineProperty
沒法模擬
babel-polyfill
和babel-runtime
的區別
babel-polyfill
會污染全局babel-runtime
不會污染全局lib
要用babel-runtime
webpack
如何實現懶加載
import()
Vue React
異步組件Vue-router``React-router
異步加載路由webpack優化構建速度(可用於生產環境)
babel-loader
IgnorePlugin
noParse
happyPack
ParalleIUglifyPlugin
webpack
優化構建速度(不用於生產環境)
項目流程
需求分析:瞭解背景,質疑需求是否合理,需求是否閉環,開發難度如何,是否須要其餘支持,不要急於給排期。技術方案設計:1,求簡,不過渡設計;2,產出文檔,覆盤;3,找準設計重點,組件怎麼設計;4,組內評審;5,和RD,CRD
溝通;6,發出會議結論。
完整項目流程:各個角色(需求分析),技術方案設計,開發,聯調,測試,上線。
如何保證代碼質量,開發,項目質量?
Mock API
Code Review
聯調:1,和RD,CRD技術聯調;2,讓UE肯定視覺效果;3,讓PM肯定產品功能。
加需求:走需求變動流程,按規定走,發起項目組和leader的評審,從新評估排期。
測試:提測發郵件,抄送項目組,測試問題要詳細記錄。
有問題及時溝通,QA和FE天生信息不對稱,當面討論,讓QA幫你復現,須要特定設備才能復現。溝通,及時識別風險,及時彙報。
瞭解:CSS
盒模型,DOM
事件類,HTTP
協議類,原型鏈類,面向對象類,通訊類,前端安全類,前端算法類;渲染機制類,JS運行機制,頁面性能,錯誤監控,業務能力,團隊協做能力,帶人能力。
佈局
浮動,絕對定位,flex-box
,表格佈局,網格佈局。
浮動解決方案:
<div class="left"></div>
<div class="right"></div>
<div class="center"></div>
div {min-height: 100px;}
.left {float: left; width: 300px; background: red;}
.right {float: right;..}
.center { background: yellow; }
絕對定位: absolute
flex box
表格佈局
網格佈局
複製代碼
基本模型,content,padding, border, margin
height-content height, width-content width
標準模型,IE模型的區別:
IE模型:它的寬和高是計算:padding+border
。
CSS3的屬性,CSS如何設置這兩種模型,box-sizing
:content-box
;(標準模型) box-sizing:border-box
(IE
模型)
JS如何設置獲取盒模型的寬和高:dom.style.width/height,dom.currentStyle.width/height
兼容性更好一些:window.getComputeStyle(dom).width/height
;dom.getBoundingClientRect().width/height
BFC(邊距重疊解決方案)塊級格式化上下文:BFC的原理,BFC的渲染規則:
如何建立BFC,給父元素添加:overflow: hidden;
,overflow:auto;
,flow
不爲none
,設置浮動BFC
,position
:不是static/relative
使用BFC的場景:解決邊距重疊問題,解決清除浮動。BFC的元素不會與float元素相互重疊。
DOM事件:1.DOM事件的級別;2.DOM事件模型;3.DOM事件流;4.描述DOM事件捕獲的具體流程;5.Event對象的經常使用應用;6.自定義事件。
DOM事件類,事件級別:
DOM0 element.onclick = function(){}
DOM2 element.addEventListener('click',function(){}, false)
DOM3 element.addEventListener('keyup',function(){}, false)
複製代碼
DOM
事件模型:捕獲,冒泡
事件流:瀏覽器在爲這個當前頁面與用戶作交互的過程當中,點擊屬標,傳到頁面上。
事件流:window
對象,捕獲,目標元素(目標階段)-》冒泡,window對象。
描述DOM事件捕獲的具體流程:window-document-html-body-目標元素
。(document.documentElement
)
Event
對象的經常使用:
event.preventDefault()
阻止默認行爲;event.stopPropagation()
阻止冒泡行爲;event.stopImmediatePropagation()
;event.currentTarget
,當前所綁定的事件;event.target
。
自定義事件:
var eve = new Event('custome');
ev.addEventListener('custome',function(){
console.log('custome');
});
ev.dispatchEvent(eve);
window.addEvenListener('click', function(){}, true);// 捕獲階段觸發
複製代碼
HTTP協議:
HTTP報文的組成部分
請求報文:請求行,請求頭,空行,請求體;響應報文:狀態行,響應頭,空行,響應體。請求行包含:http方法,頁面地址,http協議以及版本;請求頭包含:key-value值,告訴服務器端我要什麼內容。
HTTP協議類的主要特色:簡單快速,靈活,無鏈接,無狀態。
HTTP協議類,HTTP方法:GET,獲取資源,POST,傳輸資源,PUT,更新資源,DELETE,刪除資源,HEAD,得到報文首部。
HTTP協議類:POST和GET的區別:1.GET在瀏覽器回退時是無害的,而POST會再次提交請求;2.GET產生的URL地址能夠被收藏,而POST不能夠;3.GET請求會被瀏覽器主動緩存,而POST不會,除非手動設置;4.GET請求只能進行url編碼,而POST支持多種編碼方式;5.GET請求參數會被完整保留在瀏覽器歷史記錄裏,而POST中的參數不會保留;6.GET請求在URL中傳送的參數是有長度限制的,而POST是沒有限制的;7.對參數的數據類型,GET只接受ASCII字符,而POST沒有限制;8.GET比POST更不安全,由於參數直接暴露在URL中,因此不是用來傳遞敏感信息的;9.GET參數經過URL傳遞的,POST放在Request body中。
HTTP
狀態碼:
1xx
:指示信息,表示請求已接收,繼續處理;2xx
:成功,表示請求已被成功接收;3xx
:重定向,要完成請求必須進行更進一步的操做;4xx
:客戶端錯誤,請求有語法錯誤或請求沒法實現;5xx
:服務器錯誤,服務器未能實現合法的請求。200
ok: 客戶端請求成功206 Partial Content
: 客戶發送了一個帶有Range頭的GET請求,服務器完成了它301 Moved Permanently
: 所請求的頁面已經轉移至新的url302 Found
: 全部請求的頁面已經臨時轉移至新的url304 Not Modified
: 客戶端有緩衝的文檔併發出了一個條件性的請求服務器告訴客戶,原來緩衝的文檔還能夠繼續使用
400
客戶端請求有語法錯誤,不能被服務器所理解401
請求未經受權,這個狀態碼必須和www-Authenticate
報頭域一塊兒使用403
對被請求頁面的訪問被禁止404
請求資源不存在505
服務器發送不可預期的錯誤,原來緩衝的文檔還能夠繼續使用503
請求未完成,服務器臨時過載或宕機,一段時間後可能恢復正常持久鏈接:HTTP1.1版本 1.0不支持
HTTP協議採用「請求-應答」模式,當使用普通模式,即非keep-alive
模式時,每一個請求/應答 客戶和服務器都要新鍵一個鏈接,完成以後當即斷開鏈接(HTTP協議爲無鏈接的協議)。
當使用keep-alive
模式(又稱爲持久鏈接,鏈接重用)時,keep-alive
功能使客戶端到服務器端的鏈接有效,當出現對服務器的後繼請求時,keep-alive
功能避免了創建或從新創建鏈接。
管線化:
管線化:
原型鏈類:建立對象幾種方法,原型,構造函數,實例,原型鏈,instanceof的原理。
建立對象的幾種方法:
// 字面量
var o1 = {name:'o1'};
var o2 = new Object({name:'01'});
// 經過構造函數
var m = function(){this.name='01'}
var m1 = new m();
// Object.create
var p = {name:'o3'};
var o3 = Object.create(p);
複製代碼
原型鏈:
構造函數,new,實例,構造函數-prototype-原型對象-__proto__
原型對象,原型對象constructor
構造函數,實例__proto__
到原型對象。
原型鏈類:實例對象proto
- instanceof - prototype
- 原型,實例對象 -constructor
- 構造函數。
new 運算符:
foo.protoype
。this
)會被指定爲這個新實例,new foo等同於new.foo()
,只能用在不傳遞任何參數的狀況。類與實例:類的聲明;生成實例。
類與繼承:如何實現繼承;繼承的幾種方式。
類的聲明:
function Animal() {
this.name = 'name';
}
// es6 class
class Animal2 {
constructor() {
this.name = name;
}
}
複製代碼
繼承的本質原型鏈:
function Parent1() {
this.name = 'parent';
}
function Child() {
Parent.call(this);
this.type = 'child';
}
複製代碼
缺點是獲取不到父類構造函數prototype上的方法。
function Parent2() {
this.name = 'parent2';
}
function Child2() {
this.type = 'child2';
}
child2.prototype=new Parent2();
複製代碼
原型鏈繼承方式的缺點:原型鏈中的原型對象,引用同一個對象,就是父類的實例對象。
第三種繼承方式:組合方式
function Parent3() {
this.name = 'parent3';
this.play = [1,2,3];
}
function Child3() {
Parent3.call(this);
this.type = 'child3';
}
Child3.prototype = new Parent3();
var s3 = new Child3();
var s4 = new Child4();
s3.play.push(4);
複製代碼
解決1,2不足,缺點就是父級的構造函數執行了兩次。
第四種方式:結合繼承的優化,繼承父類的原型對象(原型式)
function Parent4() {
this.name = 'parent4';
this.play = [1,2,3];
}
function Child4() {
Parent4.call(this);
this.type = 'child4';
}
Child4.prototype = Parent4.prototype
// 數據類型:應用類型和值類型
// constructor指向
複製代碼
第5,組合繼承方式
function Parent5() {
this.name = 'parent5';
this.play = [1,2,3];
}
function Child5() {
Parent5.call(this);
this.play = 'child5';
}
Child5.prototype = Object.create(Parent5.prototype); // __proto__
Child5.prototype.constructor = Child5;
// 構造函數指向Child5
複製代碼
根DNS,頂級DNS,權威DNS,本地DNS,負載均衡
。TCP/IP,UNIX Domain Socket
。URI/URL
:協議名,查詢參數,編碼。webSocket
:全雙工,二進制幀,有狀態。Base64,chunked,壓縮(gzip,deflate)
Wireshark,tcpdump
UDP,QUIC,gRPC
HPACK,Server Push,SPDY
AES,ChaCha
),非對稱加密(RSA,DH
),摘要算法(SHA-2
),證書(X509,CA
),SSL/TLS
(SNI,OCSP,鏈接優化)。CDN
(負載均衡,就近訪問,Squid/Varaish/ATS
WAF
:應用層防禦,訪問控制,審計TCP
三次握手,SYN,SYN.ACK,ACK
;TCP
四次握手關閉鏈接:FIN,ACK/FIN,ACK
什麼是同源策略以及限制
同源策略限制從一個源加載的文檔或腳本如何與另外一個源的資源進行交互。這是一個用於隔離潛在惡意文件的關鍵的安全機制。
AJAX是同源下面的通訊方式,WebSocket不限制同源策略,CORS支持跨源通訊,也支持同源通訊。
如何建立Ajax
XMLHttpRequest
對象的工做流程Object.prototype.toString.call()
var util = {};
util.indexOf = function(array, item) {
for(var i=0; i<array.length; i++) {
if(array[i] === item) {
return i;
}
}
return -1;
};
// 判斷是否爲函數
util.isFunction = function(source) {
return '[Object Function]` === Object.prototype.toString.call(source)
}
// 判斷是否是ie
util.isIE = function() {
var myNav = navigator.userAgent.toLowerCase();
return (myNav.indexOf('msie') !== -1) ? parseInt(myNav.split('mise')[1]) : false;
};
複製代碼
模擬ajax
的功能:
util.json = function(options) {
var opt = {
utl: '',
type: 'get',
data: {},
success: function() {}
error: function() {}
};
util.extend(opt, options);
if(opt.url) {
var xhr = XMLHttpRequest ? new XMLHttpRequest() : new window.ActiveXObject('Microsoft.XMLHTTP');
var data = opt.data, url = opt.url,
type = opt.type.toUpperCase(), dataArr=[];
for(var k in data) {
dataArr.push(K+'='+data[k]);
}
if(type === 'GET') {
url = url + '?' + dataArr.join('&');
xhr.open(type, url.replace(/\?$/g, ''), true);
xhr.send();
}
if(type === 'POST'){
xhr.open(type, url, true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send(dataArr.join('&'));
}
xhr.onload = function() {
if(xhr.status === 200 || xhr.status === 304) {
var res;
if(opt.success && opt.success instanceof Function) {
res = xhr.responseText;
if(typeof res === 'string') {
res = JSON.parse(res);
opt.success.call(xhr.res);
}
}
}else{
if(opt.error && opt.error instanceof Function) {
opt.error.call(xhr.res);
}
}
複製代碼
跨域通訊的幾種方式:
JSONP
Hash
PostMessage
WebSocket
CORS
jsonp
的原理:
util.jsonp = function(url, onsuccess, onerror, charset) {
var callbackName = util.getName('tt_player');
window[callbackName] = function() {
if(onSuccess && utils.isFunction(onSuccess)) {
onSuccess(arguments[0]);
}
};
var script = util.creatScript(url+'&callback='+callbaseName,charset);
script.onload = script.onreadystatechange = function() {
if(!script.readyState || /loader|complete/.test(script.readyState)){
script.onload = script.onreadystatechange = null;
// 移除該script的DOM對象
if(script.parentNode){
script.parentNode.removeChild(script);
}
// 刪除函數或變量
window[callbackName] = null;
}
};
script.onerror = function() {
if(onerror && util.isFunction(onerror)) {
onerror();
}
};
// script標籤的異步加載來實現的
<script src="http://xxx.com/?data = name & callback = 'jsonp'charset = 'utf-8'></script>
複製代碼
<script>
jsonp({data:{}})
</script>
複製代碼
使用webSocket
不受同源策略限制:
var ws = new WebSocket('wss://echo.websocket.org');
ws.onopen = function(evt) {
console.log('');
ws.send('');
};
ws.onmessage = function(evt) {
console.log('');
ws.close();
};
ws.onclose = function(evt) {
console.log('');
};
複製代碼
csrf, xss
-CSRF:一般稱爲跨站請求僞造
Cross-site-request forgery
縮寫CSRF,攻擊原理,防護措施。
CSRF
防護措施:1.token
驗證;2.Referer
驗證;3.隱藏令牌
CSRF
攻擊原理:依賴用戶點擊登陸,下發cookie,引誘點擊,訪問,指向的是網站A的api接口,特別是get類型。加token驗證,註冊成功之後,沒有手動上傳token,沒有帶token就避免了攻擊;Referer
驗證,指頁面來源,是否來自我這個站點下的頁面,是的話執行動做,不是就攔截。
XSS
-Cross-site scripting
跨域腳本攻擊:XSS
原理,向頁面注入腳本,防護措施,讓腳本不能執行
XSS和CSRF區別
XSS
是向你頁面注入JS
去執行,而後JS函數體裏作它想作的事情CSRF
是利用你自己的漏洞去幫助你主動執行那些接口,CSRF依賴於你這個用戶要登陸網站算法:堆,棧,隊列,鏈表;JS的數組自己就具有堆,棧,隊列的特性,push, pop, shift, unshift
堆棧: 先進後出,先進先出,unshift進,pop出.
渲染機制
DOCTYPE
及做用Reflow
Repaint
Layout
DTD
(document type definition
,文檔類型定義)是一系列的語法規則,用來定義XML或(X)HTML的文件類型。瀏覽器會使用它來判斷文檔類型,決定使用何種協議來解析,以及切換瀏覽模式。
DOCTYPE
是用來聲明文檔類型和DTD規範的,一個主要的用途即是文件的合法性驗證,若是文件代碼不合法,那麼瀏覽器解析時便會出一些差錯。
瀏覽器的渲染過程
HTML,HTML Parser,DOM Tree(DOM) (Style sheets-> CSS Parser-> Style Rules)->Attachment->Render Tree(Layout)->Painting->Display
Reflow
重排
定義:DOM結構種的各個元素都有本身的盒子(模型),這些都須要瀏覽器根據各類樣式來計算並根據計算結果將元素放到它該出現的位置,這個過程稱爲reflow。
觸發reflow:
重繪Repaint
當各類盒子的位置,大小以及其餘屬性,例如顏色,字體大小等會肯定下來後,瀏覽器因而把這些元素都各自的特性繪製了一遍,因而頁面的內容出現了,這個過程稱爲repaint。
運行機制:JS的單線程,一個時間以內,JS只能幹一件事;EventLoop事件循環。
任務隊列:同步任務,異步任務。
頁面性能
提高頁面性能的方法:
<meta http-equiv='x-dns-prefetch-control` content='on'>
<link rel = 'dns-prefetch' href="//host_name_to_prefetch.com'>
複製代碼
CDN-讓網絡快速達到服務端,把文件下載下來,尤爲是當頁面第一次打開的時候,瀏覽器緩存是起不到任何做用的,那麼使用CDN是很是明顯的。
預解析DNS,若是你的頁面使用多個域名的時候,你的DNS解析是很是明顯的。
a
標籤,在一些高級瀏覽器裏面是默認打開DNS
預解析的,也就是說你不用加meta
等這句話,也可使用DNS
預解析的,可是若是你的頁面是https
協議開頭的,不少瀏覽器默認是關閉DNS
預解析的,須要強制打開DNS
預解析。異步加載的方式:動態腳本加載;defer;async
異步加載的區別:
defer
是在HTML
解析完以後纔會執行,若是是多個,按照加載的順序依次執行。async
是在加載完以後當即執行,若是是多個,執行順序和加載順序無關。瀏覽器緩存:
緩存的分類:強緩存/協商緩存
// 強緩存
Expires thXXX
Cache-Control: max-age
// 協商緩存
Last-Modified/If-Modified-Since
Etag/If-None-Match
複製代碼
緩存,瀏覽器緩存說的就是你個資源文件在瀏覽器中存在的這個備份,或說是副本。
強緩存就是我問都不問不直接請求,直接拿過來就用了;協商緩存就是瀏覽器發現我本地有這個副本,但我又不肯定用不用它,向服務器問一下,我這個文件要不要用,也就是協商和服務器協商一下,我這個能不能用,它是否是過時了,這個過程叫協商緩存。
強緩存:Expires
:過時時間,值表示絕對時間;Cache-Control:Cache-Control:max-age=3600
相對時間。
協商緩存:Last-Modified
上次修改的時間,If-Modified-Since
請求的時候我給服務器帶的,Etag
解決:服務器下方的資源會給你Etag
值,If-None-Match
。
1.0 缺點:雖然個人時間變了,可是個人內容沒有發生變化,內容沒有發生變化,我徹底能夠從副本中拿。
1.1 過了強緩存的時間,瀏覽器再去向服務器請求,問它,這個資源我可不能夠再用的時候,它會經過If-None-Match
,http
中會加一個這個If-None-Match
key值,而後會加一個value
,這個value
就是服務器下方的Etag
值。
緩存是爲了提升頁面性能優化的.
瞭解錯誤監控類:前端錯誤的分類,錯誤的捕獲方式,上報錯誤的基本原理。前端錯誤的分類:即時運行錯誤,代碼錯誤,資源加載錯誤。即時運行錯誤的捕獲方式:try...catch...
,window.onerror
資源加載錯誤:object.onerror
,performance.getEntries()
,Error
事件
上報錯誤的基本原理:1. 採用ajax通訊的方式上報;2. 利用Image對象上報。
Vuex是一個專爲Vue服務,用於管理頁面的數據狀態,提供統一數據操做的生態系統。它集中於MVC模式中的Model層,規定全部的數據操做必須經過action-mutation-state
,change的流程來進行,再結合Vue
的數據視圖雙向綁定特性來實現頁面的展現更新。
統一的頁面狀態管理以及操做處理,可讓複雜的組件交互變得簡單清晰,同時可在調試模式下進行時光機般的倒退前進操做,查看數據改變過程,使code debug
更加方便。
Vue Components
-Dispath
-Actions
-commit
-Mutations
-Mutate
-State
-Render
。
生命週期流程圖
new Vue
新建Vue
實例,初始化(事件&生命週期),beforeCreate
,初始化(注入&校驗),created
,是否指定'el'選項?是,是否指定'template'選項,是(將template編譯到render函數中),否(將el外部的HTML做爲template編譯);beforeMount
,建立vm.$el
,並用替換el,mounted
,掛載完畢。(當data被修改時,beforeUpdate
,虛擬DOM
從新渲染並應用更新,updated
),當調用vm.$destory
函數時,beforeDestory
,解除綁定銷燬子組件以及事件監聽器,destoryed
。
生命週期建立先後,掛載前/後,更新前/後,銷燬前/後。
beforeCreate
,在beforeCreate
生命週期執行時,data
和methods
中的數據還未初始化,因此此時不能使用data
中的數據和methods
中的方法。created
,data
和methods
初始化完畢,此時可使用methods
中的方法和data
中的數據。beforeMount
,template
模板已經編譯好,但還未掛載到頁面,此時頁面仍是上一個狀態。mounted
,此時Vue實例初始化完成了,DOM掛載完畢,能夠直接操做dom或者使用第三方dom庫。beforeUpdate
,此時data已更新,但還未同步頁面。updated
,data
和頁面都已經更新完成。beforeDestory
,Vue實例進入銷燬階段,但全部的data和methods,指令,過濾器等都處於可用狀態。destoryed
,此時組件已經被銷燬,data,methods等都不可用。v-cloak主要是用來避免頁面加載時出現閃爍的問題,能夠結合CSS的[v-cloak]{display:none}
方式解決這一問題。
組件之間,父子之間的通訊方案:
this.$emit(event.params)
來調用自定義事件parent children
&refs
方法來通訊組件的按需加載是項目優化的一個環節,也能夠下降首屏渲染時間;使用()=>import()
;使用resolve=>require(['./componentA'], resolve)
keep-alive
是Vue
的內置組件,能在組件切換過程當中將狀態保留在內存中,防止重複渲染DOM。chunk
是webpack
打包過程當中的Modules
的集合,是打包過程當中的概念。
JSONP:ajax請求受同源策略影響,不容許進行跨域請求,而script標籤src屬性中的連接卻能夠訪問跨域的Js腳本,利用這個特性,服務端再也不返回JSON格式的數據,而是返回一段調用某個函數的js代碼,在src中進行進行了調用,這樣實現了跨域。
斐波那契數列:
function f(n) {
if(n===0){
return 0;
}else if(n===1){
return 1;
}else{
var fn1 = 0;
var fn2 = 1;
var fnx = 0;
for(var i = 0; i< n-1; i++) {
var newFn = fn2;
fnx = fn1+fn2;
fn1 = fn2;
fn2 = fnx;
}
return fnx;
}
}
複製代碼
遞歸算法:
function fib(count) {
var count = parseInt(count);
if(isNaN(count) || count<=0) {
return 0;
}
function f(count) {
if(count<=2) {
return 1;
}
return f(count-1)+f(count-2);
}
return f(count);
}
複製代碼
求前20個數字:
var arr = [];
arr[1] = 1;
arr[2] = 2;
for(var i = 3; i<20; i++) {
arr[i] = arr[i-1] + arr[i-2];
}
for(var i = 1; i<arr.length; i++) {
console.log(arr[i]);
}
複製代碼
Vue實現數據雙向綁定的:
實現了一個監聽器Observer,對數據對象進行遍歷,包括了屬性對象,利用Object.defineProperty()
屬性都加上setter
和getter
。這樣的話,給這個對象的某個值賦值,就會觸發setter
,那麼就監聽到了數據變化。
實現了一個解析器Compile,解析Vue模板指令,將模板中的遍歷都替換成數據,而後初始化渲染頁面視圖,並將每一個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變更,收到通知,調用更新函數進行數據更新。
實現一個訂閱者Watcher:Watch訂閱者是Observer和Compile之間通訊的橋樑,主要的任務是訂閱Observer中的屬性值變化的消息,當收到屬性值變化的消息時,觸發解析器Compile中的對應的更新函數。
實現一個訂閱器Dep,訂閱器採用發佈-訂閱設計模式,用來收集訂閱者Watcher,對監聽器Observer和訂閱者watcher進行統一管理。
算法
push,pop
push,shift
示例:
{
// 數據域
val: 1,
// 指針域,指向下一個結點
next: {
val: 2,
next:。。。
}
}
// 鏈表
function ListNode(val) {
this.val = val;
this.next = null;
}
複製代碼
二叉樹:在JS中,二叉樹使用對象來定義,它的結構分爲三塊:
二叉樹結點的構造函數:
function TreeNode(val) {
this.val = val;
this.left = this.right = null;
}
// 建立一個二叉樹結點時
const node = new TreeNode(1);
複製代碼
二叉樹遍歷:1.先序遍歷,2.中序遍歷,3.後序遍歷,4.層次遍歷(按照順序規則不一樣)
按照實現方式不一樣:遞歸遍歷;迭代遍歷(先中後序遍歷,層次遍歷)
建立一個由數據域,左右子樹組成的結點,每一顆二叉樹度應該由這三部分組成。
遞歸函數(遞歸式,遞歸邊界)
// 先序遍歷的遍歷實現
// 全部遍歷函數的入參都是根據結點對象
function preorder(root) {
// 遞歸邊界,root爲空
if(!root) {
return
}
// 輸出當前遍歷的結點值
console.log('當前遍歷的結點值' + root.val);
// 遞歸遍歷左子樹:
preorder(root.left);
// 遞歸遍歷右子樹:
preorder(root.right);
}
// 中序遍歷,左子樹,根結點,右子樹
function inorder(root) {
if(!root) {
return
}
// 遞歸遍歷左子樹
inorder(root.left);
// 輸出當前遍歷的結點值
console.log('當前遍歷的結點是', root.val);
// 遞歸遍歷右子樹
inorder(root.right);
}
// 後序遍歷:左子樹,右子樹,根結點
function postorder(root) {
if(!root) {
return
}
// 遞歸遍歷左子樹
postorder(root.left)
// 遞歸遍歷右子樹
postorder(root.right)
// 輸出當前遍歷的結點值
console.log('當前遍歷的結點值是:'+root.val)
}
時間複雜度/空間複雜度
複製代碼
求兩數求和問題
const twoSum = function(nums, target) {
// 這裏我用對象來模擬map的能力
const diffs = {}
// 緩存數組的長度
const len = nums.length
// 遍歷數組
for(let i = 0; i<len; i++) {
// 判斷當前對應的target差值是否存在
if(diffs[target-nums[i]] !== undefined) {
// 如有對應差值,那麼答案get
return [diffs[target-nums[i]], i]
}
// 若沒有對應差值,則記錄當前值
diffs[nums[i]=i
}
}
複製代碼
合併兩個有序數組:
const merge = function(nums1, m, nums2, n) {
// 初始化兩個指針的指向,初始化num1尾部索引k
let i = m-1, j = n-1, k = m+n-1;
// 當兩個數組都沒遍歷完時,指針同步移動
while(i>=0 && j>=0) {
// 取較大的值,從末尾往前填補
if(nums1[i] >= nums2[j]){
num1[k] = nums1[i]
i--;
k--;
}else{
num1[k] = nums2[j]
j--;
k--;
}
}
// nums2留下的狀況,特殊處理一下
while(j>=0){
nums1[k] = num2[j];
j--;
k--;
}
};
複製代碼
字符串:反轉字符串:
const str = 'huang';
// 定義反轉後的字符串
const res = str.split('').reverse().join('');
console.log(res);
複製代碼
迴文字符串:正着讀和倒着讀都同樣
function isPalindrome(str) {
// 先反轉字符串
const reversedstr = str.split('').reverse().join('');
return reversedstr === str
}
複製代碼
具備對稱性:
function isPalindrome(str){
// 緩存字符串的長度
const len = str.length
// 遍歷前半部分,判斷和後半部分是否對稱
for(let i = 0; i<len/2; i++) {
if(str[i] !== str[len-i-1]){
return false
}
}
return true
}
複製代碼
鏈表的合併:
const mergeTwoLists = function(l1,l2) {
// 定義結點,確保鏈表能夠被訪問到
let head = new ListNode()
let cur = head; // cur這裏就是我們那根「針」
while(l1&&l2) {
// 若是l1的結點值較小
if(l1.val <= l2.val) {
// 先串起來l1的結點
cur.next = l1
// l1指針向前一步
l1 = l1.next
}else{
// l2較小時,串起l2的結點
cur.next = l2
// l2指針向前一步
l2 = l2.next
}
// "針"在串起一個結點後,也會往前一步
cur = cur.next
}
// 處理鏈表不等長的狀況
cur.next = l1 !== null ? l1 : l2
// 返回起始點
return head.next
}
複製代碼
單例模式
class SingleDog{
show() {
console.log('我是單例對象')
}
static getInstance() {
// 判斷是否已經new過這個實例
if(!SingleDog.instance) {
SingleDog.instance = new SingleDog()
}
return SingleDog.instance
}
}
複製代碼
閉包:
SingleDog.getInstance = (function() {
// 定義自有變量instance
let instance = null
return function() {
// 判斷自由變量是否爲null
if(!instance) {
instance = new SingleDog()
}
return instance
}
})()
複製代碼
Vue原理:
路由模式:hash/history;
路由配置:動態路由/懶加載
組件渲染過程:1. 初次渲染過程,2.更新過程,3.異步渲染過程。
解析模板爲render函數(或開發環境vue-loader),觸發響應式監聽data屬性,getter和setter,執行render函數生成vnode,path(elem, newNode);修改data,觸發setter,更新執行render函數生成newNode;$nextTick
,彙總data的修改,一次性更新視圖,減小DOM操做次數,提升性能。
路由模式:hash變化會觸發網頁跳轉即瀏覽器的前進後退,hash變化不會刷新頁面,SPA必需的特色:hash永遠不會提交到server端。
history原理表現:用url規範的路由,但跳轉時,刷新頁面,history.pushState
,window.onpopstate
組件化:組件化歷史,數據驅動視圖,MVVM。響應式:Object.defineProperty
,監聽對象(深度),監聽數組,Object.defineProperty
的缺點,Vue.set, Vue.delete
,原生數組。
vdom和diff
:Vnode
結構,Snabbdom
度。模板編譯:with
語法,模板編譯爲render
函數,執行render
函數生成vnode
。
Vue
組件如何通信:父子組件props
和this.$emit
,自定義事件event.$on/event.$off/event.$emit/Vuex
。
雙向數據綁定v-model
的實現原理:
input
元素的value=this.name
input
事件:this.name = $event.target.value
date
更新觸發:re-render
computed
的特色:緩存,data不變,提升性能。什麼時候使用異步組件:加載大組件,異步加載。什麼時候使用deforeDestory
,解綁自定義事件:event.$off
,清除定時器,解綁自定義事件。
vue
優化:
v-show
和v-if
computed
v-for
時加key
,以免和v-if
同時使用(v-for
優先級更高一些,每次v-for
都須要使用v-if
,這些性能是一種消耗。)DOM
事件及時銷燬keep-alive
,data
層級不要太深vue-loader
,在開發環境作編譯(預編譯),前端通用的性能優化,如圖片懶加載,使用SSR。什麼是併發/並行
垃圾回收:1,引用計數垃圾收集;2,標記-清除。
找出數據中重複的元素:
function fun(arr) {
var a = arr.sort();
var result = [];
for(var i = 0; i < arr.length; i++) {
if(arr[i] === arr[i+1] && result.indexOf(arr[i]) == -1) {
result.push(arr[i]);
}
}
return result;
}
複製代碼
new
操做:
var obj = new Da();
var obj = {};
obj.__proto__ = Da.prototype;
Da.call(obj);
複製代碼
深刻淺出防抖函數debounce
,實現原理:
防抖函數debounce
指的是某個函數在某段時間內,不管觸發了多少次回調,都只執行一次。假如咱們設置了一個等待時間3秒的函數,在這個3秒內若是遇到函數調用請求就從新計時3秒,直到新的3秒內沒有函數調用請求,此時執行函數,否則就以此類推從新計時。
實現原理就是利用定時器,函數第一次執行時設定一個定時器,以後調用時發現已經設定過定時器就清空以前的定時器,並從新設定一個新的定時器,若是存在沒有被清空的定時器,當定時器計時結束後觸發函數執行。
判斷:
instanceOf
Constructor
Object.prototype.toString.call()
繼承我總結了:有1,原型鏈繼承,2,借用構造函數繼承,3,組合繼承,4,原型式繼承,5,寄生式繼承,6,寄生組合式繼承。es6中新增的class和extends語法,用來定義類和實現繼承,底層採用了寄生組合式繼承。
this
的指向問題:
onclick
事件中的this遍歷:
Object.keys(obj)
Object.values(obj)
你懂得越多,考慮的就越全面。
❤️關注+點贊+收藏+評論+轉發❤️,原創不易,鼓勵筆者創做更好的文章
我是Jeskson
(達達前端),感謝各位人才的:點贊、收藏和評論,咱們下期見!(如本文內容有地方講解有誤,歡迎指出☞謝謝,一塊兒學習了)
我的網站:1024bibi.com/
github
收錄,歡迎Star
:github.com/webVueBlog/…
特別注意:請在文末添加: 掘金年中主題活動 | 2021 個人半程成長之路徵文活動正在進行中......