Create by jsliang on 2019-2-11 15:30:34
Recently revised in 2019-3-17 21:30:36javascript
Hello 小夥伴們,若是以爲本文還不錯,記得給個 star , 小夥伴們的 star 是我持續更新的動力!GitHub 地址php
【2019-08-16】Hello 小夥伴們,因爲 jsliang 對文檔庫進行了重構,這篇文章中的一些連接可能失效,而 jsliang 缺少精力維護掘金這邊的舊文章,對此深感抱歉。請須要獲取最新文章的小夥伴,點擊上面的 GitHub 地址,去文檔庫查看調整後的文章。css
並非只有特定的季節才能跑路,只由於人跑得多了,這條路就定下來了。html
金三銀四跳槽季,jsliang 於 2019年2月11日 寫下了這篇文章,開始準備本身的面試之旅。前端
至 2019年3月17日 爲止,jsliang 搭建出我的的面試知識體系,海量地翻閱了一些前輩留下的資料,結合我的需求進行了幾場面試,從而進一步完善該文章並進行了發表,但願對準備跳槽或者正在跳槽中的小夥伴有所幫助。vue
不折騰的前端,和鹹魚有什麼區別java
返回目錄css3
請時刻準備好本身的簡歷,無論是互聯網經濟不佳面臨裁人,仍是由於公司內部鬥爭嚴重心亂如麻,仍是由於厭倦了目前的一切……只有隨時更新本身,把本身的簡歷準備好,你才知道哪一刻跑路是最佳選擇。git
返回目錄es6
Hello 小夥伴們好,我叫梁峻榮,網名叫 jsliang,因爲崇拜前端大佬 技術胖(jspang)的緣由,又由於本身學的是前端(JavaScript),因此給本身取了個 jsliang(JavaScriptLiang) 的網名,但願本身能經過創建本身的前端知識體系,從而在前端路上走得更遠。並將本身的經驗分享給小夥伴,攜手小夥伴們一塊兒前行。
下面是講講我的故事:
首先,jsliang 高考後的暑期就聽大學師兄的建議,開始學習編程,那時候學習了 C 語言,以爲世界上最神奇的事情不過如此,敲兩下鍵盤,按下回車,電腦就會一閃一閃地響應咱們!因而在大學的時候,陸陸續續學過 C、C#、.Net 等……。
-_-|| 因爲學得都是基礎,又都還給老師了,在這裏就很少累述了。
而後,在大二就開始接觸 HTML,那時候選修了個《網頁設計基礎》,跟着老師作了個只有幾個頁面的靜態網站。在大三的時候,參加了學校的特訓班,分角色按流程從頭至尾作了個包含角色管理、購物等功能的網站。同時,因爲在特訓班的時候,看到後端使用 ThinkPHP(簡稱 TP),以爲蠻不錯的,因而本身搗鼓,使用 TP 3.2.3 + Bootstrap 3 + MySQL 打造了本身的博客(已下線)。
接着,因爲選修了門 Node.js 的課,因此也跟着大佬的步伐接觸了下 Vue、Koa 這些,那時候對 npm 等諸多不懂,爲了折騰這個,個人前端世界自此打開了個大門。
最後,我在本身的畢業設計中使用 Node.js + Vue + ElementUI + MongoDB 打造了個校園外賣、快遞代拿等功能的社區單頁應用。
在 2018 年 5 月的時候,家裏催促,因而直接出來面試。不像其餘大佬的畢業等於失業,很幸運地 jsliang 面試第一家就給了 offer,因而就進了這家公司,那時候感受本身前面的大學生活白過了,只懂 ES五、jQuery、HTML/HTML五、CSS/CSS3 的皮毛。
在熟悉了三個月的業務,公司給的任務能順利完成後,我以爲本身不夠努力:外面的前端翻天覆地,個人技術卻只是 jQuery is all!
因而 2018 年 8 月,jsliang 開始寫 Markdown,將 5 月份到 8 月份記錄到 Word 文檔上的筆記整理成了 jsliang 的文檔庫,並在 jsliang 的掘金 上發表了第一篇文章。
18 年 8 月至今,jsliang 大體經歷瞭如下這些:
以上,就是 jsliang 的編程生涯。
今兒,在這裏寫寫 jsliang 爲了跳槽,根據我的想法進行的一些前端面試資料整理,小夥伴們以爲不錯的點個贊或者去 GitHub 點個 star,以爲有誤請指出,謝謝~
馬老闆曾經說過,跳槽有兩個緣由:
首先,若是非要給 jsliang 我本身的跳槽定個位,那確定是錢沒給到位,勞動與產出不成正比。在我 2018 年 5 月入職前,與人事的交談中瞭解到每一年的 8 月和 2 月能夠提薪,當初的技術棧是:HTML、CSS、ES5。
而後,2018 年 6 月到 2019 年 1 月,學習並應用到工做中的技術有:
其中 2018 年 8 月剛轉正,也不敢說本身技術進步很大,也不敢說本身項目貢獻很大,爲公司謀了多大利益,因此沒有提薪想法。
2019 年 1 月底感受本身項目也作了,凌晨 4/5/6 點的體育西路也看過了,技術也提高了,因而跟人事交談,指望 2 月能加薪,人事表示年終述職演講得好的給提薪,2 月開工的時候表示提薪名單沒我份……
你沒看錯,提薪全靠 PPT。PPT 裏提升了不給,沒提就是沒有。
當初想法很簡單,你隨便加個 5/600 我也知足了。
最後,jsliang 曾跟項目總監私下談話,建議能夠發展一些新產品,這樣公司或許能獲取一些新收入,我也能夠進一步挑戰個人技術。可是,因爲我司是個老牌子公司,而且大部分依賴於接手電信項目進行擴張……
enm...因此心也委屈了。
在 2018 的努力下,GitHub 破 600 近 700 star,掘金破 10 萬閱讀量,3000 粉絲:
GitHub 見證:點擊查看
掘金見證:點擊查看
1. 熟悉 HTML/HTML五、CSS/CSS三、ES5/ES6。
2. 瞭解 OOP 概念,並嘗試在工做中使用過 OOP 技巧。
3. 對 MVC/MVVM 架構有必定了解,若有 Vue/React/Angular 或者 微信小程序開發經驗更佳。
4. 使用過 Bootstrap 或者 ElementUI 等 UI 庫,並對前端 UI 庫有必定的我的理解。
5. 瞭解 Git、Webpack 等工具。
6. 對 Java、Node.js 等後端編程有必定了解。
7. 一年及以上工做經驗。
複製代碼
該分析數據來自 Boss 直聘
本文的知識點將涉及 HTML、CSS、JS、HTTP、Vue、Webpack、打包工具、性能優化等,沒有前置條件,看得懂能夠瞅瞅複習下,看不懂能夠瞅瞅學習下。
關於面試,在這記下慕課網視頻看到的,我的很是認同的三個問答:
而後在複習面試題的過程當中,我的有些小見解:
當編寫業務代碼中,碰到某個業務 bug 時,我會習慣性地百度這個業務 bug,看看網友是怎麼解決的。可是,學霸級的程序猿,會多走一步,他們會思考產生這個業務 bug 的底層緣由是什麼,下次碰到相似的是如何應用該技術解決。因此,日積月累,個人確比不上人家了。
way 1:面試成功,跟本身公司遞辭呈,走流程,同時跟對面 hr 申請一個月後入職。
way 2:面試成功,跟本身公司遞辭呈,詢問能不能快速離職,收到回覆跟對面 hr 確認時間。【推薦】
way 3:先遞辭呈,同時面試,面試成功的,一概申請走完原公司一個月的流程以後的日子入職。
jsliang 於 2 月底拿到 offer 並遞交辭呈,3 月 - 4 月進入一個月倒計時,4 月第一週才能拿到離職證實。
最後在這裏祝各位小夥伴能找到趁心如意的工做~
HTML 屬於結構層,負責描繪出內容的結構。
CSS 屬於表示層,負責如何顯示有關內容。
JavaScript 屬於行爲層,負責內容應如何對事件作出反應。
語義化的含義就是用正確的標籤作正確的事情,HTML 語義化就是讓頁面的內容結構化,它有以下優勢:
簡單來講,能用 <header>
、<footer>
等 H5 新標籤的就不用 <div class="header">
,不要使用 <div>
來存放段落等……
HTML5 中新增標籤大體有:<header>
、<footer>
、<aside>
、<nav>
、<video>
、<audio>
、<canvas>
等等。
Chrome | Firefox | Safari | IE | Opera | |
---|---|---|---|---|---|
排版引擎 | Blink | Gecko | Webkit | Trident | Blink |
JS 引擎 | V8 | SpiderMonkey | Nitro | Chakra | V8 |
國內一些瀏覽器使用較多的是 Webkit 內核。
<!--[if IE]><![endif]-->
<!--[if !IE]><![endif]-->
/* 設置文字不可選取 */
* {
-moz-user-select: none; /* 火狐 瀏覽器 */
-webkit-user-select: none; /* Webkit 瀏覽器 */
-o-user-select: none; /* Opera 瀏覽器 */
-ms-user-select: none; /* IE10 瀏覽器 */
-khtml-user-select: none; /* 早期瀏覽器 */
user-select: none; /* 默認 */
}
複製代碼
cookies:存儲於瀏覽器端的數據。能夠設置 cookies 的到期時間,若是不設置時間,則在瀏覽器關閉窗口的時候會消失。
session:存儲於服務器端的數據。session 存儲特定用戶會話所需的屬性和配置信息。
cookies 和 session 的區別在於:
sessionStorage:生命週期存在於標籤頁或窗口,用於本地存儲一個會話(session)中的數據,這些數據會隨着窗口或者標籤頁的關閉而被清空。
localStorage:生命週期是永久的,除非用戶主動清除瀏覽器上存儲的 localStorage 信息,不然它將會永久存在。
sessionStorage 和 localStorage 操做方法:setItem
、getItem
以及 removeItem
。
以 localStorage 爲例:
localStorage.getItem('name'); // 獲取 name 的值
localStorage.setItem('name', 'jsliang'); // 設置 name 的值爲 jsliang
localStorage.removeItem('name'); // 刪除 name 的值
複製代碼
參考 1:《前端分享之cookie的使用及單點登陸》
參考 2:《Cookie、session和localStorage、以及sessionStorage之間的區別》
HTML 屬於結構層,負責描繪出內容的結構。
CSS 屬於表示層,負責如何顯示有關內容。
JavaScript 屬於行爲層,負責內容應如何對事件作出反應。
在工做的過程當中,會發現各式各樣的瀏覽器對某個標籤有本身獨特的樣式。
可是在前端開發中,若是不採用統一標準,那麼會產生千奇百怪的 bug。因此爲了減小後期 bug 的出現,前端開發人員會重置一遍 CSS 樣式,儘量地使開發的網頁在各個瀏覽器相差不大。
下面是 jsliang 在使用的樣式重置,固然若是小夥伴有不一樣的想法,能夠去 百度/必應/google 搜索並使用其餘版本的樣式重置:
在工做的過程當中,也許小夥伴須要 div 塊的總寬度爲 100px,而後發現老是被 margin 撐高,這是由於盒模型定義的問題:
CSS 中有個屬性叫 box-sizing
。
box-sizing: border-box
box-sizing: content-box
複製代碼
border-box
中,整個 div
的寬、高,包括 margin
、padding
、border
。content-box
中,整個 div
的寬、高,則不包括上面元素。如上圖,若是一個 div
,你的代碼以下:
div {
box-sizing: border-box;
margin: 10px;
width: 100px;
height: 100px;
padding: 10px;
}
複製代碼
那麼,你的整個寬高仍是 100px
。
可是,若是你的代碼以下:
div {
box-sizing: content-box;
margin: 10px;
width: 100px;
height: 100px;
padding: 10px;
}
複製代碼
那麼,你的整個盒子寬高是 120px
。
若是你在設計頁面中,發現內容區被撐爆了,那麼,請檢查下如今的 border-box
是什麼,最好在引用 reset.css
的時候,就對 border-box
進行統一設置,方便管理。
在 CSS 中,除了咱們經常使用的 px
,還有其餘單位小夥伴們能夠了解一下:
單位 | 描述 |
---|---|
% | 百分比 |
px | 像素。計算機屏幕上的一個點爲 1px 。 |
em | 相對單位。相對於父元素計算,假如某個 p 元素爲 font-size: 12px ,在它內部有個 span 標籤,設置 font-size: 2em ,那麼,這時候的 span 字體大小爲:12 * 2 = 24px |
rem | 相對單位。相對於根元素 html 的 font-size ,假如 html 爲 font-size: 12px ,那麼,在其當中的 div 設置爲 font-size: 2rem ,就是當中的 div 爲 24px 。 |
rpx | 微信小程序相對單位。1rpx = 屏幕寬度 / 750 px。在 750px 的設計稿上,1rpx = 1px。 |
除此以外還有 pt、ex 等單位,但因爲不太好換算,故在此不提。
選擇器是匹配元素的一種模式。
HTML 通過解析生成 DOM Tree;而在 CSS 解析完畢後,須要將解析的結果與 DOM Tree 的內容一塊兒進行分析創建一棵 Render Tree,最終用來進行繪圖。
Render Tree 中的元素與 DOM 元素相對應,但非一一對應:一個 DOM 元素可能會對應多個 renderer,如文本折行後,不一樣的「行」會成爲 render tree 種不一樣的 renderer。也有的 DOM 元素被 Render Tree 徹底無視,好比 display:none 的元素。
在創建 Render Tree 時,瀏覽器就要爲每一個 DOM Tree 中的元素根據 CSS 的解析結果來肯定生成怎樣的 renderer。對於每一個 DOM 元素,必須在全部 Style Rules 中找到符合的 selector 並將對應的規則進行合併。選擇器的「解析」實際是在這裏執行的,在遍歷 DOM Tree 時,從 Style Rules 中去尋找對應的 selector。
在 CSS 的選擇器中,它會按照優先級 從右向左解析,由於這樣匹配元素的時候,能儘可能少地查找,因此選擇器最好寫地簡潔一點。
*
#ID
.class
p
、a
等……p span
、div a
等……a:hover
等……input[type="text"]
等……li:firth-child
、p:nth-child(1)
等……!important -> 行內樣式 -> #id -> .class -> 元素和僞元素 -> * -> 繼承 -> 默認
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Two Column Layout</title>
<style> .container { display: flex; } .child-one { width: 300px; height: 300px; background: red; } .child-two { width: 100%; height: 300px; background: deepskyblue; } </style>
</head>
<body>
<div class="container">
<div class="child-one"></div>
<div class="child-two"></div>
</div>
</body>
</html>
複製代碼
<div>
塊而已。固然,小夥伴們可能會說:jsliang 你要考慮 flex
的兼容性啊!enm...支持全部最新版本的瀏覽器!請更新你的瀏覽器哦親~避免被寄刀片,附上
float
佈局:《css常見佈局》
經典:CSS3 相關屬性你瞭解嗎,說說都有哪些?能說說你工做中經常使用的一些 CSS3 屬性嗎?
那麼,CSS3 新特性都有哪些呢?
爲了方便記憶,咱將它們扔到同一個 HTML 文件上,小夥伴拷貝到本地上打開,能夠看到一個擁有漸變的小球,作着橫向運動,若是你鼠標移動到它上面,它的寬度會放大,而且進行傾斜。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS3 新特性</title>
<style> div { width: 100px; height: 100px; border-radius: 50px; background: linear-gradient(red, orange); box-shadow: 10px 10px 5px #888888; position: relative; transition: width 2s; animation: mymove 5s infinite; } div:hover { width:300px; transform: rotate(7deg); } @keyframes mymove { from { left: 0px; } to { left: 200px; } } </style>
</head>
<body>
<div></div>
</body>
</html>
複製代碼
參考 1:《CSS3 圓角》
參考 2:《CSS3 漸變(Gradients)》
參考 3:《CSS3 transition 屬性》
參考 4:《CSS3 transform 屬性》
參考 5:《CSS3 animation(動畫) 屬性》
參考 6:《CSS3 box-shadow 屬性》
參考 7:《我的總結(css3新特性)》
BFC 就是 塊級格式上下文,它是一個獨立的渲染區域,讓處於 BFC 內部的元素和外部的元素相互隔離,使內外元素的定位不會相互影響。
必定的 CSS 聲明能夠生成 BFC,瀏覽器對生成的 BFC 有一系列的渲染規則,利用這些渲染規則能夠達到必定的佈局效果。
參考文獻:《我對BFC的理解》
行內元素:寬度和高度由內容決定,與其餘元素共佔一行的元素,咱們將其叫行內元素。例如:<span>
、<i>
、<a>
等……
塊級元素:默認寬度由父容器決定,默認高度由內容決定,獨佔一行而且能夠設置寬高的元素,咱們將其叫作塊級元素。例如:<p>
、<div>
、<ul>
等……
在平常開發中,咱們常用 CSS 的 display
屬性來打破二者的壁壘:display: inline-block
,使它們擁有更多的狀態。
在引用 CSS 上,分爲四種形式:行內樣式、內嵌式、連接式以及導入式,下面介紹這四種模式。
直接對 HTML 的標記使用 style 屬性,而後將 CSS 代碼直接寫進去:
<p style="color: #fff; backgournd: deepskyblue;"></p>
複製代碼
將 CSS 寫 <head>
與 </head>
之間,而且用 <style>
和 </style>
標記進行聲明:
<head>
<style> p { color: #fff; background: deepskyblue; } </style>
</head>
複製代碼
經過將 <style>
上的 CSS 提起到指定的 CSS 文件上,而後經過 <link>
的方式在 HTML 上連接起來。
<head>
<link href="reset.css" type="text/css" rel="stylesheet">
</head>
複製代碼
<head>
<style> @import url(reset.css); </style>
</head>
複製代碼
在優先級上,行內樣式 > 連接式 > 內嵌式 > @import 導入式。
Flex 是 Flexible Box 的縮寫,意爲」彈性佈局」,用來爲盒狀模型提供最大的靈活性。
/* 設置 Flex 模式 */
display: flex;
/* 決定元素是橫排仍是豎着排,要不要倒序 */
flex-direction: column;
/* 決定元素換行格式,一行排不下的時候如何排 */
flex-wrap: wrap;
/* flex-flow = flex-direction + flex-wrap */
flex-flow: column wrap;
/* 同一排下對齊方式,空格如何隔開各個元素 */
justify-content: space-between;
/* 同一排下元素如何對齊,頂部對齊、中部對齊仍是其餘 */
align-items: center;
/* 多行對齊方式 */
align-content: space-between;
複製代碼
HTML
<div class="container">
<div class="child"></div>
</div>
複製代碼
CSS
.container {
margin: 0 auto;
width: 300px;
height: 200px;
background: deepskyblue;
display: flex;
/* 實現元素水平居中 */
justify-content: center;
/* 實現元素垂直居中 */
align-items: center;
}
.child {
width: 100px;
height: 100px;
background: #fff;
}
複製代碼
HTML
<div class="container">
<div class="child"></div>
</div>
複製代碼
CSS
.container {
position: relative;
width: 300px;
height: 200px;
background: pink;
margin: 0 auto;
}
.child {
position: absolute;
width: 100px;
height: 100px;
top: 50%;
left: 50%;
/* 下面兩種方式都可 */
/* margin-top: -50px;
margin-left: -50px; */
transform: translate(-50%, -50%);
background: #fff;
}
複製代碼
水平居中:
display: inline-block; text-align: center;
margin: 0 auto;
display: flex; justify-content: center;
垂直居中:
line-height: height
display: flex; align-items: center;
參考文獻:
① 《CSS實現垂直居中的經常使用方法》
② 《CSS 用 position: absolute 與 transform 來居中塊級元素的問題》
HTML 屬於結構層,負責描繪出內容的結構。
CSS 屬於表示層,負責如何顯示有關內容。
JavaScript 屬於行爲層,負責內容應如何對事件作出反應。
<body>
<input type="button" onclick="alert('行內引入')" value="按鈕"/>
<button onclick="alert(123)">點擊我</button>
</body>
複製代碼
<script> window.onload = function() { alert("js 內部引入!"); } </script>
複製代碼
<body>
<div></div>
<script type="text/javascript" src="./js/index.js"></script>
</body>
複製代碼
注意:
<script>
,由於瀏覽器解析順序緣故,若是解析到死循環之類的 JS 代碼,會卡住頁面。關於 prototype
、__proto__
、new
、call()
、apply()
、bind()
、this
這些的知識點,因爲篇幅太長,jsliang 已經抽離了出來,並作了簡潔詳細講解,詳見:
下面放出相關知識點:
__proto__
屬性(原型)等於其構造函數的 prototype
屬性。在 JS 中,最容易混淆的就是做用域的狀況。
在傳統的後端語言(例如 C 語言)中,一對花括號 {}
就是一個塊級做用域,做用域內變量不會相互影響,可是在 JS 中,像 if 條件語句的 {}
就不算一個獨立的做用域:
var x = 1;
console.log(x); // 1
if(true) {
var x = 2;
console.log(x); // 2
}
console.log(x); // 2
複製代碼
因此有時候咱們就須要變通,經過自執行函數建立臨時做用域:
function foo() {
var x = 1;
console.log(x); // 1
if(x) {
(function(x) {
console.log(x); // 1
var x = 2;
console.log(x); // 2
})(x)
}
console.log(x); // 1
}
foo();
複製代碼
說到建立臨時做用域,咱們就不得不談一下閉包。
那麼,什麼是閉包呢?
閉包簡單定義:函數 A 裏面包含了 函數 B,而 函數 B 裏面使用了 函數 A 的變量,那麼 函數 B 被稱爲閉包。
又或者:閉包就是可以讀取其餘函數內部變量的函數
function A() {
var a = 1;
function B() {
console.log(a);
}
return B();
}
複製代碼
for(var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
複製代碼
請問這段代碼輸出什麼?
答案:3 個 3。
解析:首先,for
循環是同步代碼,先執行三遍for
,i 變成了 3;而後,再執行異步代碼setTimeout
,這時候輸出的 i,只能是 3 個 3 了。
for(let i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
複製代碼
在這裏,每一個 let 和代碼塊結合起來造成塊級做用域,當 setTimeout() 打印時,會尋找最近的塊級做用域中的 i,因此依次打印出 0 1 2。
若是這樣講不明白,咱們能夠執行下下面這段代碼:
for(let i = 0; i < 3; i++) {
console.log("定時器外部:" + i);
setTimeout(function() {
console.log(i);
}, 1000);
}
複製代碼
此時瀏覽器依次輸出的是:
定時器外部:0
定時器外部:1
定時器外部:2
0
1
2
複製代碼
即代碼仍是先執行 for
循環,可是當 for
結束執行到了 setTimeout
的時候,它會作個標記,這樣到了 console.log(i)
中,i 就能找到這個塊中最近的變量定義。
for(let i = 0; i < 3; i++) {
(function(i){
setTimeout(function() {
console.log(i);
}, 1000);
})(i)
}
複製代碼
以上,咱們就講解完了閉包及解決閉包的方式。
觀點 1:有些資料表示閉包中產生的大量局部變量,會形成內存消耗過大,從而形成網頁的性能問題。
觀點 2:有些資料表示目前瀏覽器引擎都基於 V8,而 V8 引擎有個 gc 回收機制,不用太過擔憂變量不會被回收。
提示:因此,若是你以爲不夠保險,那就在退出函數以前,將不使用的局部變量所有刪除。
簡單來講,有兩個對象 A 和 B,B = A,當你修改 A 時,B 的值也跟着發生了變化,這時候就叫淺拷貝。若是不發生變化,就叫深拷貝。
let a = 1; let b = a; a = 2; console.log(b)
。當咱們嘗試這樣子寫時,b 在棧內存中開闢了一個新內存,因此 b 的值不會改變,還是 1.let a = [1, 2, 3], b = a; a[0] = 3; console.log(b)
。當咱們嘗試這樣子寫時,b 會偷懶,引用跟 a 同一塊的內存地址,從而 a 的修改會影響 b,使得 b 變成 [3, 1, 3]。function deepClone(obj) {
let objClone = Array.isArray(obj) ? [] : {};
if(obj && typeof obj === "object") {
for(key in obj) {
if(obj.hasOwnProperty(key)) {
// 判斷 obj 子元素是否爲對象,若是是,遞歸複製
if(obj[key] && typeof obj[key] === "object") {
objClone[key] = deepClone(obj[key]);
} else {
// 若是不是,簡單複製
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
let a = [1, 2, 3, 4];
let b = deepClone(a);
a[0] = 2;
console.log(a, b);
// Console
// a = [2, 2, 3, 4];
// b = [1, 2, 3, 4];
複製代碼
注意:採用 JSON 進行的深拷貝,沒法拷貝到 undefined、function、symbol 這類數據,它是有小 bug 的深拷貝。
function deepClone(obj) {
let _obj = JSON.stringify(obj);
let objClone = JSON.parse(_obj);
return objClone
}
let a = [0, 1, [2, 3], 4];
let b = deepClone(a);
a[0] = 1;
a[2][0] = 1;
console.log(a, b);
// Console
// a = [1, 1, [1, 3], 4];
// b = [0, 1, [2, 3], 4];
複製代碼
在前端發展中,隨着先後端分離,前端社區的不斷壯大,前端能作的事情愈來愈多,承受的任務愈來愈重,代碼也就愈來愈長了。就比如 jsliang 我的使用 jQuery 開發的時候,動不動就上千行代碼,這在一個編輯器上看起來就有點亂了。若是碰上沒有代碼摺疊的編輯器,你就更加難受了。
有的小夥伴的編輯器不是 VS Code,也不能進行代碼摺疊
因此,面對愈來愈多的代碼,咱們就急需將這些代碼分門別類,將代碼按功能劃分,將同一功能的代碼整合在一塊兒,因而就有了模塊化開發:一個文件就是一個模塊,當咱們須要某個文件的時候,咱們只須要引用這個模塊便可……
首先,是 CommonJS 的提出,在 Node.js 以及 Webpack 都支持 CommonJS,它規定了一個文件就是一個模塊,文件內部定義的變量屬於這個模塊,不會對外暴露從而污染全局變量的規則。在 CommonJS 中,經過 exports 或者 module.exports 進行導出,經過 require 進行 同步加載 所須要依賴的模塊。因爲它是同步加載模塊的形式,因此比較通用於服務器端。
而後,根據 CommonJS 只能同步加載的問題,AMD 根據瀏覽器的特性,進行了非同步加載模塊的提出。同時,AMD 有個問題,就是在使用 require.js 的時候,必須提早加載全部模塊。
接着,根據 AMD 的問題,CMD 提出來了:經過按需加載的形式,哪裏須要就調用哪裏,而不用等到全部的模塊都加載了再解析。
最後,ECMA 國際推出了 ES6 的 modules。在 ES6 中,經過 export 關鍵字導出模塊,經過 import 關鍵字引用代碼。固然,因爲瀏覽器廠商諸多,ES6 在瀏覽器的尚不支持,目前主流作法是先將 ES6 經過 babel 編譯成 require。
固然,JS 都進行模塊化了,jsliang 想起本身項目中的那一坨 CSS,真心沒有回顧的想法!因此咱們還須要知道爲了方便管理 CSS,大佬們仍是有作事兒的:Less 以及 Sass,這二者使 CSS 的編寫更有組織性和目的性了。
提及模塊化,咱們又能夠順帶說起組件化了,一開始爲了區分這二者,jsliang 也是百度了大量文章,最後成功把本身整蒙了,仍是說說感受能夠的解釋:
組件化更關注的是 UI 部分:彈出框、頭部,內容區、按鈕等,均可以編寫成組件,而後在適用的地方進行引用。而模塊化更側重於功能或者數據的封裝,好比全局的 JSON 配置文件,好比通用的驗證方法,好比規範時間戳等。
因此,說到這裏,咱們就能夠提到前端工程化:將整個開發流程就行工程規劃,從而提升整個團隊的開發效率。
在前端工程化中,最重要的就是提升整個團隊在 編碼 -> 測試 -> 維護 這三個階段的生產效率。團隊的協調相當重要,將每一個任務細分給各個成員,從而獲取極致的工做效率,是管理者最喜歡看到的。而在上面的模塊化和組件化的應用,就屬於前端工程化中的一部分,其目的就是在一些複雜的項目中,方便團隊進行合做開發,提升生產效率。
參考文獻:
① 《到底什麼是前端工程化、模塊化、組件化》
② 《【前端工程化系列】簡談前端模塊化開發與開發規範》
③ 《我的關於模塊化的理解》
④ 《組件化開發和模塊化開發概念辨析》
⑤ 《JavaScript模塊化 --- Commonjs、AMD、CMD、es6 modules》
⑥ 《淺談什麼是前端工程化》
簡單來講,就是增長代碼的可複用性,減小我們的工做,使代碼更加流暢。
function Person(name, phone) {
this.name = name;
this.phone = phone;
this.eat = function() {
console.log(name + " 吃飯");
}
return this;
}
let p1 = new Person("jsliang", "18818881888");
console.log(p1.name); // jsliang
p1.eat(); // jsliang 吃飯
複製代碼
固然,jsliang 只能寫到這裏了,再寫下去就是設計模式等知識點了。
因此但願小夥伴們仍是瞭解下面向對象思想,有助於進一步提高本身。
關於 防抖與節流,jsliang 特地將資料結合起來:
小夥伴們能夠前往 《面試知識點 - JS 防抖與節流》 查看。
ES6 是個大知識點,若是你面試的公司不是 「飽經滄桑」 的那種,那麼必定會出點 ES6 問題,例如:
由於 jsliang 感受本身連 ES6 的門還沒進,因此在這裏就不 自做聰明,推薦下阮一峯大佬的教程:
但願小夥伴們看完能有所收穫,並在工做中大量使用。
在 JavaScript 中,用得較多的之一無疑是數組操做,這裏過一遍數組的一些用法:
map
: 遍歷數組,返回回調返回值組成的新數組forEach
: 沒法break,能夠用try/catch中throw new Error來中止filter
: 過濾some
: 有一項返回true,則總體爲trueevery
: 有一項返回false,則總體爲falsejoin
: 經過指定鏈接符生成字符串push / pop
: 末尾推入和彈出,改變原數組, 返回推入/彈出項【有誤】unshift / shift
: 頭部推入和彈出,改變原數組,返回操做項【有誤】sort(fn) / reverse
: 排序與反轉,改變原數組concat
: 鏈接數組,不影響原數組, 淺拷貝slice(start, end)
: 返回截斷後的新數組,不改變原數組splice(start, number, value...)
: 返回刪除元素組成的數組,value 爲插入項,改變原數組indexOf / lastIndexOf(value, fromIndex)
: 查找數組項,返回對應的下標reduce / reduceRight(fn(prev, cur), defaultPrev)
: 兩兩執行,prev 爲上次化簡函數的return值,cur 爲當前值(從第二項開始)相信小夥伴在工做中耍的已是一套一套的了,或者像 jsliang 同樣只會簡單的使用 push
、map
這幾個,感興趣的小夥伴能夠 百度/bing/google 找找一些 奇技淫巧,說不定對工做效率有很大提高~
推薦:
在 MVVM 架構下,View 和 Model 之間並無直接的聯繫,而是經過 ViewModel 進行交互,Model 和 ViewModel 之間的交互時雙向的,所以 View 數據會同步到 Model 中,而 Model 數據的變化也會當即反應到 View 上。
ViewModel 經過雙向數據綁定把 View 層和 Model 層鏈接了起來,而 View 和 Model 之間的同步工做徹底是自動的,無需人爲干涉,所以開發者只須要關注業務邏輯,不須要手動操做 DOM,不須要關注數據狀態的同步問題,複雜的數據狀態維護徹底由 MVVM 來統一管理。
$el
和數據對象 data 以及事件還未初始化。在 created 階段,Vue 實例的數據對象 data 以及方法的運算有了,$el
尚未。render
函數首次被調用,Vue 實例的 $el 和 data 都初始化了,但仍是掛載在虛擬的 DOM 節點上。在 mounted 階段,Vue 實例掛載到實際的 DOM 操做完成,通常在該過程進行 Ajax 交互。Vue 實例從建立到銷燬的過程,就是生命週期。從開始建立、初始化數據、編譯模板、掛載 DOM -> 渲染、更新 -> 渲染、銷燬等一系列過程,稱之爲 Vue 的生命週期。
8 個,建立前/建立後、掛載前/掛載後、更新前/更新後、銷燬前/銷燬後。Vue 生命週期的做用是方便咱們經過它的生命週期,在業務代碼中更好地操做數據,實現相關功能。
會觸發 4 個生命鉤子:建立前/建立後、掛載前/掛載後
在 beforeMounted
時它執行了 render
函數,對 $el 和 data 進行了初始化,但此時仍是掛載到虛擬的 DOM 節點,而後它在 mounted
時就完成了 DOM 渲染,這時候咱們通常還進行 Ajax 交互。
Vue 採用 數據劫持 結合 發佈者-訂閱者 模式的方式,經過 Object.defineProperty()
來劫持各個屬性的 setter 以及 getter,在數據變更時發佈消息給訂閱者,觸發相應的監聽回調。
dep.notice()
通知時,能調用自身的 update()
方法,並觸發 Compile 中綁定的回調,則功成身退。js 實現簡單的雙向綁定
<body>
<div id="app">
<input type="text" id="txt">
<p id="show"></p>
</div>
<script>
window.onload = function() {
let obj = {};
Object.defineProperty(obj, "txt", {
get: function() {
return obj;
},
set: function(newValue) {
document.getElementById("txt").value = newValue;
document.getElementById("show").innerHTML = newValue;
}
})
document.addEventListener("keyup", function(e) {
obj.txt = e.target.value;
})
}
</script>
</body>
複製代碼
Object.defineProperty 接收三個參數:對象,屬性名,配置對象
這裏使用的是 Object.defineProperty,這是 Vue 2.0 進行雙向數據綁定的寫法。在 Vue 3.0 中,它使用 Proxy 進行數據劫持。
Vue 在 render
中 createElement
的時候,並非產生真實的 DOM 元素,實際上 createElement
描述爲 createNodeDescription
,由於它所包含的信息會告訴 Vue 頁面上須要渲染什麼樣的節點。
所以,咱們將這樣的節點描述爲 「虛擬節點」(Virtual Node),簡稱 VNode。「虛擬 DOM」 是咱們對由 Vue 組件樹創建的整個 VNode 樹的稱呼。
做爲一枚切圖仔,很榮幸地跟小夥伴說:「其實我也不懂 Virtual DOM!」
可是,總會有些面試場合會提到的,因此這裏找了幾篇資料,小夥伴們能夠進一步學習:
其餘的就須要小夥伴本身尋找了,若是以爲有不錯的解析 Virtual DOM 的文檔/視頻,小夥伴也能夠推薦過來哈~
Vue 中 template 就是先轉化成 AST 樹,再獲得 render 函數返回 VNode(Vue 的虛擬 DOM 節點)。
key 的做用就是在更新組件時判斷兩個節點是否相同。相同就複用,不相同就刪除舊的建立新的。
對於 diff 過程來講 key 是起不到提速做用的,詳見:key 的做用
用法:Vue.nextTick( [callback, context] )
參數:
{Function} [callback]
{Object} [context]
說明:在下次 DOM 更新循環結束以後執行延遲迴調。在修改數據以後當即使用這個方法,獲取更新後的 DOM。
案例:
// 修改數據
vm.msg = 'Hello'
// DOM 尚未更新
Vue.nextTick(function () {
// DOM 更新了
})
// 做爲一個 Promise 使用 (2.1.0 起新增,詳見接下來的提示)
Vue.nextTick().then(function () {
// DOM 更新了
})
複製代碼
關於 nextTick 的更多理解,jsliang 就不獻醜了,須要學習的小夥伴能夠查看:
或者自行查找更優秀的資源。
關於 Vue 中的父子組件通信,相信常常開發 Vue 的小夥伴比 jsliang 知道的多不少。
沒怎麼使用 Vue 的小夥伴能夠看下下面的文章,並嘗試本身寫一寫:
下面咱講下使用 bus.js 實現非父子組件通信:
假設在工做中,有三個 .vue 文件:A.vue、B.vue、C.vue。A.vue 是主頁面,B.vue 和 C.vue 相似於頭部導航條和底部導航欄。如今,B.vue 點擊會切換路由,C.vue 須要獲取 B.vue 傳遞的信息。
A.vue
<template>
<div>
<top-nav></top-nav>
<div class="container">
<router-view></router-view>
</div>
<bottom-nav></bottom-nav>
</div>
</template>
複製代碼
bus.js
import Vue from 'vue';
// 使用 Event Bus
const bus = new Vue();
export default bus;
複製代碼
B.vue
<template>
<div class="bottom-nav">
<div class="nav-one" @click="goToPage({path: '/HomeIndex', meta:'首頁'})">
<i class="icon-home"></i>
<span>首頁</span>
</div>
</div>
</template>
<script> import bus from '../utils/bus' export default { methods: { goToPage(route) { this.$router.push(route.path); bus.$emit('meta', route.meta); } } } </script>
複製代碼
C.vue
<template>
<div class="top-nav">
<span class="title">{{title}}</span>
</div>
</template>
<script> import bus from '../utils/bus' export default { data() { return { title: '' } }, created() { bus.$on('meta', msg=> { this.title = msg; }) } } </script>
複製代碼
微信小程序,簡稱小程序,英文名 Mini Program,是一種不須要下載安裝便可使用的應用,它實現了應用「觸手可及」的夢想,用戶掃一掃或搜一下便可打開應用。
- component —————————————————— 組件文件夾
- navBar —— 底部組件
- navBar.js —— 底部組件的 JS 代碼
- navBar.json —— 底部組件的配置文件
- navBar.wxml —— 底部組件的 HTML 代碼
- navBar.wxss —— 底部組件的 CSS 代碼
- pages ————————————————————— 頁面文件夾
- index —— 首頁
- index.js —— 首頁的 JS 代碼
- index.json —— 首頁的配置文件
- index.wxml —— 首頁的 HTML 代碼
- index.wxss —— 首頁的 CSS 代碼
- public ————————————————————— 圖片文件夾
- utils —————————————————————— 工具文件夾
- api.js —— 控制 API 的文件
- md5.js —— 工具 - MD5 加密文件
- timestamp.js —— 工具 - 時間戳文件
- app.json ——————————————————— 設置全局的基礎數據等
- app.wxss ——————————————————— 公共樣式,可經過 import 導入更多
- project.config.json ———————— 項目配置文件
複製代碼
onLoad()
:頁面加載時觸發。onShow()
:頁面顯示/切入前臺時觸發。onReady()
:頁面初次渲染完成時觸發。onHide()
:頁面隱藏/切入後臺時觸發。onUnload()
:頁面卸載時觸發。項目/utils/api.js
// 將請求進行 Promise 封裝
const fetch = ({url, data}) => {
// 打印接口請求的信息
console.log(`【step 1】API 接口:${url}`);
console.log("【step 2】data 傳參:");
console.log(data);
// 返回 Promise
return new Promise((resolve, reject) => {
wx.request({
url: getApp().globalData.api + url,
data: data,
success: res => {
// 成功時的處理
if (res.data.code == 0) {
console.log("【step 3】請求成功:");
console.log(res.data);
return resolve(res.data);
} else {
wx.showModal({
title: '請求失敗',
content: res.data.message,
showCancel: false
});
}
},
fail: err => {
// 失敗時的處理
console.log(err);
return reject(err);
}
})
})
}
/** * code 換取 openId * @data { * jsCode - wx.login() 返回的 code * } */
export const wxLogin = data => {
return fetch({
url: "tbcUser/getWechatOpenId",
data: data
})
}
複製代碼
項目/pages/login/login.js
import {
wxLogin,
} from '../../utils/api.js'
複製代碼
項目/pages/login/login.js
wxLogin({
jsCode: this.data.code
}).then(
res => {
console.log("【step 4】返回成功處理:");
console.log(res.data);
},
err => {
console.log("【step 4】返回失敗處理:");
console.log(err);
}
)
複製代碼
onLoad()
中經過 options
獲取 url 上的參數:代碼演示
<navigator url="../index/index?userId={{userId}}"></navigator>
<!-- 這兩段是分別在 HTML 和 JS 中的代碼 -->
onLoad: function(options) {
console.log(options.userId);
}
複製代碼
wx.setStorageSync('userId', 'jsliang');
wx.getStorageSync('userId');
複製代碼
login.wxml
<text bindtap="clickText" data-labelId="{{userId}}">點擊傳遞數據到 JS</text>
複製代碼
login.js
clickText(e) {
console.log(e.currentTarget.labelid)
}
複製代碼
組件接收數據:component-tag-name
Component({
properties: {
// 這裏定義了innerText屬性,屬性值能夠在組件使用時指定
innerText: {
type: String,
value: 'default value',
}
}
})
複製代碼
使用組件的頁面定義 json
{
"usingComponents": {
"component-tag-name": "../component/component"
}
}
複製代碼
使用組件的頁面 HTML 代碼
<view>
<!-- 如下是對一個自定義組件的引用 -->
<component-tag-name inner-text="Some text"></component-tag-name>
</view>
複製代碼
this.$preload()
預加載用戶可能點擊的第二個頁面。優點:
劣勢:
微信小程序有着低開發成本、低獲客成本、無需下載的優點。
微信小程序看似就是閹割版的 Vue。
關於 瀏覽器解析 URL,jsliang 特地將資料結合起來:
小夥伴們能夠前往 《面試知識點 - JS 防抖與節流》 查看。
關於 重繪與迴流,jsliang 特地將資料結合起來:
小夥伴們能夠前往 《面試知識點 - JS 防抖與節流》 查看。
V8 將內存分爲兩類:新生代內存空間和老生代內存空間。
這二者經過不一樣的算法,對內存進行管理操做。
意外的全局變量:沒法被回收。
定時器:未被正確關閉,致使所引用的外部變量沒法被釋放。
事件監聽:沒有正確銷燬(低版本瀏覽器可能出現)。
閉包:會致使父級中的變量沒法被釋放。
DOM 引用:DOM 被刪除時,內存中的引用未被正確清空。
如何查看內存變化狀況?
使用 Chrome 的 Timeline(新版本 Performance)進行內存標記,可視化查看內存的變化狀況,找出異常點。
目前網絡分層可分爲兩種:OSI 模型和 TCP/IP 模型。
更多詳情能夠查看下面這篇文章,裏面講得很是詳細:
首先,咱們大體區分下狀態碼:
而後,常見的狀態碼:
最後,小夥伴們若是想要了解更多,仍是須要自行查找資料的。
關於 TCP 三次握手與四次揮手,jsliang 特地將資料結合起來:
小夥伴們能夠前往 《面試知識點 - JS 防抖與節流》 查看。
經過優化從而提升頁面的加載速度。
.c {}
而不是 .a .b .c {}
。padding-left: 10px
而不是 padding: 0 0 0 10px
。.a .b * {}
這樣的選擇器,根據從右到左的解析順序在解析過程當中遇到通配符 * {}
會遍歷整個 DOM,性能大大損耗。float
在渲染時計算量比較大,能夠使用 flex 佈局。<script>
標籤放在 body
以後,避免 JS 的執行卡住 DOM 的渲染,最大程度保證頁面儘快地展現出來。display: none
來隱藏,按需顯示。在算法這塊,jsliang 以爲本身仍是比較薄弱的,若是小夥伴們跟 jsliang 同樣,也想豐富下這方面知識,歡迎一塊兒刷 LeetCode 共同進步:
在 【其餘】 這章,本來 jsliang 想談談面試中的一些小技巧,例如談薪;或者講講 HR 面須要詢問的問題,例如工做時長、加班機制、調薪機制等……
可是,最終看來,jsliang 的經歷仍是有所欠缺,所經歷的面試不夠 「盛大」,因此說出的話可能就是 「胡言亂語」、「誤導觀衆」,故在此就不獻醜了,若是小夥伴們想知道更多,能夠經過 QQ 羣:798961601
找到我。
☆ 目前 jsliang 經過 3 天的請假,去了 5 場面試,收穫了 3 份 offer。
☆ 若是小夥伴不知道簡歷該怎麼寫、面試老是鎮靜不下來、總感受面試沒譜,能夠先找 jsliang 聊聊,我會講講我的的面試經歷,以及聽到的其餘小夥伴的經歷~
在觀看這篇文章的過程當中,小夥伴可能會有這些疑問:
回答:
系列套餐你值得擁有!
回答:
每一個人的學習經歷是不一樣的,所擁有的技術、知識點以及工做經驗等都是不一樣的。
因此 jsliang 的目的是經過這篇文章充實本身的同時,順帶挖掘本身的不足,例如面向對象造輪子、算法問題等讓 jsliang 想進一步折騰,並應用到工做中。
所以,小夥伴應該根據本身實際去擴展補充屬於本身的知識點。
畢竟瞭解本身的,只有本身!
回答:
每一個人的目的都是不一樣的,不可能一篇文章寫完全部知識點,同時有些知識點可能 jsliang 也不感興趣、或者 jsliang 的層次不夠,接觸不到。
而且每一個面試官均可能有本身的一套面試題,若是 jsliang 能將全部的面試題都寫出來,那還須要面試官作啥,你們都像考國家證書同樣直接電腦考試吧~(我也期待!!!)
若是小夥伴對文章存有疑問,想快速獲得回覆。
或者小夥伴對 jsliang 我的的前端文檔庫感興趣,也想將本身的前端知識整理出來。
或者小夥伴對文章後續的更新感興趣,掌握更多的面試技巧。
歡迎加 QQ 羣一塊兒探討:798961601
。
本文中的許多內容,也許小夥伴看了會以爲眼熟,由於它們大部分是 jsliang 參考大量文獻,再通過刷選整理,最後根據本身理解後的一些闡述。
下面是我的以爲很是優秀的文章。
查看了下掘金評論區,感謝各位大大的反饋,因爲本人將於 2019年4月1日 入職,故將一些我的以爲不錯的本身沒有察覺的知識點記錄下來,區分於原文,更爲了猴年馬月後的下一次跳槽進一步完善。
意思就是,jsliang 這貨懶得改原文了,小夥伴們看着這裏進行知識點補充
函數 A 裏面包含了 函數 B,而 函數 B 裏面使用了 函數 A 的變量,函數 B 被 return 了出去,那麼 函數 B 被稱爲閉包。
box-sizing
屬性:當值爲 border-box
時,寬度 width = content + padding + border
,包含內邊距與邊框。
當值爲 content-box
時,寬度 width = content
,不包含內邊距與邊框。
em
是一個相對的大小,這裏的相對於元素父元素的 font-size
。
Side Project 對應的中文就是副業、業餘項目或者小項目。
感興趣的小夥伴能夠去了解一下。
push
與 shift
系列:這裏原文已備註是有誤的,只是一時沒空,沒有修改。
原文:!important -> 行內樣式 -> #id -> .class -> 元素和僞元素 -> * -> 繼承 -> 默認
網友:「應該是最後的優先級最高。」
這裏最後的優先級最高應該是指同等級優先級覆蓋。瀏覽器經過 CSSParser 將 CSS 解析成 CSS Rule Tree 的時候,沒錯的話應該是按照原文中的排序先加載,而後同等級的時候,後面的屬性覆蓋前面的屬性。
對於 HTML5 的語義化,ARIA 的意思是 Accessible Rich Internet Application,aria-*
的做用就是描述這個 Tag 在可視化的情境中的具體信息。例如:
aria-label
:爲組件指定內置的文本標籤,用來替代開發者沒有使用 <label>
標籤aria-labelledby
:會讀取與此具備相同的 id
名的值詳情可參考張鑫旭的 《WAI-ARIA無障礙網頁應用屬性徹底展現》
文章描述不夠詳細。
child-tow
中設置 width: 100%
的時候 child-one
的寬度會隨機而變,設置 flex: 1
就不會。因此看我的需求進行設置。float
進行相關的佈局。可參考文章:《深拷貝的終極探索(90%的人不知道)》
Promise
與 async
/await
:文章描述不夠詳細。
原本打算寫的,後面沒時間,給我刪了這塊,評論區有篇文獻參考:
以上,即爲目前評論區的補充,感謝各位小夥伴的點贊支持。
jsliang 廣告推送:
也許小夥伴想了解下雲服務器
或者小夥伴想買一臺雲服務器
或者小夥伴須要續費雲服務器
歡迎點擊 雲服務器推廣 查看!
jsliang 的文檔庫 由 梁峻榮 採用 知識共享 署名-非商業性使用-相同方式共享 4.0 國際 許可協議進行許可。
基於github.com/LiangJunron…上的做品創做。
本許可協議受權以外的使用權限能夠從 creativecommons.org/licenses/by… 處得到。