初中级前端面试题
初中級前端面試題
轉載地址:https://juejin.cn/post/6844903950500495373#comment
從前端學習到找一份合適的工作,大大小小的面試必不可少,所以我對初級前端面試題進行了初步整理,也方便自己查閱,也希望對小伙伴們有所幫助!
HTML
HTML語義化
HTML語義化就是讓頁面內容結構化,它有如下優點
1、易于用戶閱讀,樣式丟失的時候能讓頁面呈現清晰的結構。 2、有利于SEO,搜索引擎根據標簽來確定上下文和各個關鍵字的權重。 3、方便其他設備解析,如盲人閱讀器根據語義渲染網頁 4、有利于開發和維護,語義化更具可讀性,代碼更好維護,與CSS3關系更和諧 復制代碼如:
<header>代表頭部 <nav>代表超鏈接區域 <main>定義文檔主要內容 <article>可以表示文章、博客等內容 <aside>通常表示側邊欄或嵌入內容 <footer>代表尾部 復制代碼HTML5新標簽
有<header>、<footer>、<aside>、<nav>、<video>、<audio>、<canvas>等... 復制代碼CSS
盒子模型
盒模型分為標準盒模型和怪異盒模型(IE模型)
box-sizing:content-box //標準盒模型 box-sizing:border-box //怪異盒模型 復制代碼 標準盒模型:元素的寬度等于style里的width+padding+border寬度如下代碼,整個寬高還是120px
div{box-sizing: content-box;margin: 10px;width: 100px;height: 100px;padding: 10px; } 復制代碼怪異盒模型:元素寬度等于style里的width寬度
如下代碼,整個寬高還是100px
div{box-sizing: border-box;margin: 10px;width: 100px;height: 100px;padding: 10px; } 復制代碼注意:如果你在設計頁面中,發現內容區被撐爆了,那么就先檢查一下border-sizing是什么,最好在引用reset.css的時候,就對border-sizing進行統一設置,方便管理
rem與em的區別
rem是根據根的font-size變化,而em是根據父級的font-size變化
rem:相對于根元素html的font-size,假如html為font-size:12px,那么,在其當中的div設置為font-size:2rem,就是當中的div為24px
em:相對于父元素計算,假如某個p元素為font-size:12px,在它內部有個span標簽,設置font-size:2em,那么,這時候的span字體大小為:12*2=24px
CSS選擇器
css常用選擇器
通配符:* ID選擇器:#ID 類選擇器:.class 元素選擇器:p、a 等 后代選擇器:p span、div a 等 偽類選擇器:a:hover 等 屬性選擇器:input[type="text"] 等 復制代碼css選擇器權重
!important -> 行內樣式 -> #id -> .class -> 元素和偽元素 -> * -> 繼承 -> 默認
CSS新特性
transition:過渡 transform:旋轉、縮放、移動或者傾斜 animation:動畫 gradient:漸變 shadow:陰影 border-radius:圓角 復制代碼行內元素和塊級元素
行內元素(display: inline)
寬度和高度是由內容決定,與其他元素共占一行的元素,我們將其叫行內元素,例如:<span> 、 <i> 、 <a>等
塊級元素(display: block)
默認寬度由父容器決定,默認高度由內容決定,獨占一行并且可以設置寬高的元素,我們將其叫做塊級元素,例如:<p> 、<div> 、<ul>等
在平時,我們經常使用CSS的display: inline-block,使它們擁有更多的狀態
絕對定位和相對定位的區別
position: absolute
絕對定位:是相對于元素最近的已定位的祖先元素
position: relative
相對定位:相對定位是相對于元素在文檔中的初始位置
Flex布局
juejin.im/post/684490…
BFC
什么是BFC?
BFC格式化上下文,它是一個獨立的渲染區域,讓處于 BFC 內部的元素和外部的元素相互隔離,使內外元素的定位不會相互影響
如何產生BFC?
display: inline-block
position: absolute/fixed
BFC作用
BFC最大的一個作用就是:在頁面上有一個獨立隔離容器,容器內的元素和容器外的元素布局不會相互影響
解決上外邊距重疊;重疊的兩個box都開啟bfc; 解決浮動引起高度塌陷;容器盒子開啟bfc 解決文字環繞圖片;左邊圖片div,右邊文字容器p,將p容器開啟bfc 復制代碼水平垂直居中
Flex布局
display: flex //設置Flex模式 flex-direction: column //決定元素是橫排還是豎著排 flex-wrap: wrap //決定元素換行格式 justify-content: space-between //同一排下對齊方式,空格如何隔開各個元素 align-items: center //同一排下元素如何對齊 align-content: space-between //多行對齊方式 復制代碼水平居中
行內元素:display: inline-block; 塊級元素:margin: 0 auto; Flex: display: flex; justify-content: center 復制代碼垂直居中
行高 = 元素高:line-height: height flex: display: flex; align-item: center 復制代碼less,sass,styus三者的區別
變量
Sass聲明變量必須是『$』開頭,后面緊跟變量名和變量值,而且變量名和變量值需要使用冒號:分隔開。
Less 聲明變量用『@』開頭,其余等同 Sass。
Stylus 中聲明變量沒有任何限定,結尾的分號可有可無,但變量名和變量值之間必須要有『等號』。
作用域
Sass:三者最差,不存在全局變量的概念
Less:最近的一次更新的變量有效,并且會作用于全部的引用!
Stylus:Sass 的處理方式和 Stylus 相同,變量值輸出時根據之前最近的一次定義計算,每次引用最近的定義有效;
嵌套
三種 css 預編譯器的「選擇器嵌套」在使用上來說沒有任何區別,甚至連引用父級選擇器的標記 & 也相同
繼承
Sass和Stylus的繼承非常像,能把一個選擇器的所有樣式繼承到另一個選擇器上。使用『@extend』開始,后面接被繼承的選擇器。Stylus 的繼承方式來自 Sass,兩者如出一轍。 Less 則又「獨樹一幟」地用偽類來描述繼承關系;
導入@Import
Sass 中只能在使用 url() 表達式引入時進行變量插值
$device: mobile; @import url(styles.#{$device}.css); 復制代碼Less 中可以在字符串中進行插值
@device: mobile; @import "styles.@{device}.css"; 復制代碼Stylus 中在這里插值不管用,但是可以利用其字符串拼接的功能實現
device = "mobile" @import "styles." + device + ".css" 復制代碼總結
Sass和Less語法嚴謹、Stylus相對自由。因為Less長得更像 css,所以它可能學習起來更容易。
Sass 和 Compass、Stylus 和 Nib 都是好基友。
Sass 和 Stylus 都具有類語言的邏輯方式處理:條件、循環等,而 Less 需要通過When等關鍵詞模擬這些功能,這方面 Less 比不上 Sass 和 Stylus
Less 在豐富性以及特色上都不及 Sass 和 Stylus,若不是因為 Bootstrap 引入了 Less,可能它不會像現在這樣被廣泛應用(個人愚見)
link與@import區別與選擇
<style type="text/css">@import url(CSS文件路徑地址); </style> <link href="CSSurl路徑" rel="stylesheet" type="text/css" / 復制代碼link功能較多,可以定義 RSS,定義 Rel 等作用,而@import只能用于加載 css;
當解析到link時,頁面會同步加載所引的 css,而@import所引用的 css 會等到頁面加載完才被加載;
@import需要 IE5 以上才能使用;
link可以使用 js 動態引入,@import不行
多行元素的文本省略號
overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical 復制代碼JavaScript
JS的幾條基本規范
1、不要在同一行聲明多個變量 2、請使用===/!==來比較true/false或者數值 3、使用對象字面量替代new Array這種形式 4、不要使用全局變量 5、Switch語句必須帶有default分支 6、函數不應該有時候有返回值,有時候沒有返回值 7、For循環必須使用大括號 8、IF語句必須使用大括號 9、for-in循環中的變量 應該使用var關鍵字明確限定作用域,從而避免作用域污染復制代碼
JS引用方法
行內引入
<body><input type="button" οnclick="alert('行內引入')" value="按鈕"/><button οnclick="alert(123)">點擊我</button> </body> 復制代碼內部引入
<script>window.onload = function() {alert("js 內部引入!");} </script> 復制代碼外部引入
<body><div></div><script type=“text/javascript” src="./js/index.js"></script>
</body>
復制代碼
注意
1,不推薦寫行內或者HTML中插入<script>,因為瀏覽器解析順序緣故,如果解析到死循環之類的JS代碼,會卡住頁面 2,建議在onload事件之后,即等HTML、CSS渲染完畢再執行代碼 復制代碼JS的基本數據類型
Undefined、Null、Boolean、Number、String、新增:Symbol
數組操作
在 JavaScript 中,用得較多的之一無疑是數組操作,這里過一遍數組的一些用法
map: 遍歷數組,返回回調返回值組成的新數組 forEach: 無法break,可以用try/catch中throw new Error來停止 filter: 過濾 some: 有一項返回true,則整體為true every: 有一項返回false,則整體為false join: 通過指定連接符生成字符串 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 為當前值(從第二項開始) 復制代碼JS有哪些內置對象
Object是JavaScript中所有對象的父對象數據封裝對象:Object、Array、Boolean、Number和String
其他對象:Function、Arguments、Math、Date、RegExp、Error
復制代碼
get請求傳參長度的誤區
誤區:我們經常說get請求參數的大小存在限制,而post請求的參數大小是無限制的
實際上HTTP 協議從未規定 GET/POST 的請求長度限制是多少。對get請求參數的限制是來源與瀏覽器或web服務器,瀏覽器或web服務器限制了url的長度。為了明確這個概念,我們必須再次強調下面幾點:
1、HTTP 協議 未規定 GET 和POST的長度限制
2、GET的最大長度顯示是因為 瀏覽器和 web服務器限制了 URI的長度
3、不同的瀏覽器和WEB服務器,限制的最大長度不一樣
4、要支持IE,則最大長度為2083byte,若只支持Chrome,則最大長度 8182byte
補充get和post請求在緩存方面的區別
-
get請求類似于查找的過程,用戶獲取數據,可以不用每次都與數據庫連接,所以可以使用緩存。
-
post不同,post做的一般是修改和刪除的工作,所以必須與數據庫交互,所以不能使用緩存。因此get請求適合于請求緩存。
閉包
什么是閉包?
函數A 里面包含了 函數B,而 函數B 里面使用了 函數A 的變量,那么 函數B 被稱為閉包。
又或者:閉包就是能夠讀取其他函數內部變量的函數
function A() {var a = 1;function B() {console.log(a);}return B(); } 復制代碼閉包的特征
- 函數內再嵌套函數
- 內部函數可以引用外層的參數和變量
- 參數和變量不會被垃圾回收制回收
對閉包的理解
使用閉包主要是為了設計私有的方法和變量。閉包的優點是可以避免全局變量的污染,缺點是閉包會常駐內存,會增大內存使用量,使用不當很容易造成內存泄露。在js中,函數即閉包,只有函數才會產生作用域的概念
閉包 的最大用處有兩個,一個是可以讀取函數內部的變量,另一個就是讓這些變量始終保持在內存中
閉包的另一個用處,是封裝對象的私有屬性和私有方法
閉包的好處
能夠實現封裝和緩存等
閉包的壞處
就是消耗內存、不正當使用會造成內存溢出的問題
使用閉包的注意點
由于閉包會使得函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存泄露
解決方法是:在退出函數之前,將不使用的局部變量全部刪除
閉包的經典問題
for(var i = 0; i < 3; i++) {setTimeout(function() {console.log(i);}, 1000); } 復制代碼這段代碼輸出
答案:3個3 解析:首先,for 循環是同步代碼,先執行三遍 for,i 變成了 3;然后,再執行異步代碼 setTimeout,這時候輸出的 i,只能是 3 個 3 了 復制代碼有什么辦法依次輸出0 1 2
第一種方法
使用let
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) } 復制代碼JS作用域及作用域鏈
作用域
在JavaScript中,作用域分為 全局作用域 和 函數作用域
全局作用域
代碼在程序的任何地方都能被訪問,window 對象的內置屬性都擁有全局作用域
函數作用域
在固定的代碼片段才能被訪問
例子:
作用域有上下級關系,上下級關系的確定就看函數是在哪個作用域下創建的。如上,fn作用域下創建了bar函數,那么“fn作用域”就是“bar作用域”的上級。
作用域最大的用處就是隔離變量,不同作用域下同名變量不會有沖突。
變量取值:到創建 這個變量 的函數的作用域中取值
作用域鏈
一般情況下,變量取值到 創建 這個變量 的函數的作用域中取值。
但是如果在當前作用域中沒有查到值,就會向上級作用域去查,直到查到全局作用域,這么一個查找過程形成的鏈條就叫做作用域鏈
原型和原型鏈
原型和原型鏈的概念
每個對象都會在其內部初始化一個屬性,就是prototype(原型),當我們訪問一個對象的屬性時,如果這個對象內部不存在這個屬性,那么他就會去prototype里找這個屬性,這個prototype又會有自己的prototype,于是就這樣一直找下去
原型和原型鏈的關系
instance.constructor.prototype = instance.__proto__ 復制代碼原型和原型鏈的特點
JavaScript對象是通過引用來傳遞的,我們創建的每個新對象實體中并沒有一份屬于自己的原型副本。當我們修改原型時,與之相關的對象也會繼承這一改變
當我們需要一個屬性的時,Javascript引擎會先看當前對象中是否有這個屬性, 如果沒有的
就會查找他的Prototype對象是否有這個屬性,如此遞推下去,一直檢索到 Object 內建對象
組件化和模塊化
組件化
為什么要組件化開發
有時候頁面代碼量太大,邏輯太多或者同一個功能組件在許多頁面均有使用,維護起來相當復雜,這個時候,就需要組件化開發來進行功能拆分、組件封裝,已達到組件通用性,增強代碼可讀性,維護成本也能大大降低
組件化開發的優點
很大程度上降低系統各個功能的耦合性,并且提高了功能內部的聚合性。這對前端工程化及降低代碼的維護來說,是有很大的好處的,耦合性的降低,提高了系統的伸展性,降低了開發的復雜度,提升開發效率,降低開發成本
組件化開發的原則
-
專一
-
可配置性
-
標準性
-
復用性
-
可維護性
模塊化
為什么要模塊化
早期的javascript版本沒有塊級作用域、沒有類、沒有包、也沒有模塊,這樣會帶來一些問題,如復用、依賴、沖突、代碼組織混亂等,隨著前端的膨脹,模塊化顯得非常迫切
模塊化的好處
-
避免變量污染,命名沖突
-
提高代碼復用率
-
提高了可維護性
-
方便依賴關系管理
模塊化的幾種方法
- 函數封裝
}
復制代碼
缺陷:外部可以睡意修改內部成員,這樣就會產生意外的安全問題
復制代碼
- 立即執行函數表達式(IIFE)
- var myModule = (function(){var var1 = 1;var var2 = 2;
<span>function</span> <span><span>fn1</span></span>(){} <span>function</span> <span><span>fn2</span></span>(){}
return {
總結:這樣在模塊外部無法修改我們沒有暴露出來的變量、函數
fn1: fn1,
fn2: fn2
};
})();
復制代碼缺點:功能相對較弱,封裝過程增加了工作量,仍會導致命名空間污染可能、閉包是有成本的
復制代碼圖片的預加載和懶加載
- 預加載:提前加載圖片,當用戶需要查看時可直接從本地緩存中渲染
- 懶加載:懶加載的主要目的是作為服務器前端的優化,減少請求數或延遲請求數
兩種技術的本質:兩者的行為是相反的,一個是提前加載,一個是遲緩甚至不加載。預加載則會增加服務器前端壓力,懶加載對服務器有一定的緩解壓力作用。
mouseover和mouseenter的區別
mouseover:當鼠標移入元素或其子元素都會觸發事件,所以有一個重復觸發,冒泡的過程。對應的移除事件是mouseout
mouseenter:當鼠標移除元素本身(不包含元素的子元素)會觸發事件,也就是不會冒泡,對應的移除事件是mouseleave
解決異步回調地獄
promise、generator、async/await
對This對象的理解
this總是指向函數的直接調用者(而非間接調用者)
如果有new關鍵字,this指向new出來的那個對象
在事件中,this指向觸發這個事件的對象,特殊的是,IE中的attachEvent中的this總是指向全局對象Window
Vue
vue生命周期
什么是Vue生命周期?
Vue 實例從創建到銷毀的過程,就是生命周期。也就是從開始創建、初始化數據、編譯模板、掛載Dom→渲染、更新→渲染、卸載等一系列過程,我們稱這是 Vue 的生命周期
Vue生命周期的作用是什么?
它的生命周期中有多個事件鉤子,讓我們在控制整個Vue實例的過程時更容易形成好的邏輯
Vue生命周期總共有幾個階段?
它可以總共分為8個階段:創建前/后, 載入前/后,更新前/后,銷毀前/銷毀后
第一次頁面加載會觸發哪幾個鉤子?
第一次頁面加載時會觸發 beforeCreate, created, beforeMount, mounted 這幾個鉤子
DOM渲染在哪個周期中就已經完成?
DOM 渲染在 mounted 中就已經完成了
每個生命周期適合哪些場景?
生命周期鉤子的一些使用方法:
beforecreate : 可以在這加個loading事件,在加載實例時觸發
created : 初始化完成時的事件寫在這里,如在這結束loading事件,異步請求也適宜在這里調用
mounted : 掛載元素,獲取到DOM節點
updated : 如果對數據統一處理,在這里寫上相應函數
beforeDestroy : 可以做一個確認停止事件的確認框
nextTick : 更新數據后立即操作dom
v-show與v-if區別
v-show是css切換,v-if是完整的銷毀和重新創建
使用 頻繁切換時用v-show,運行時較少改變時用v-if
v-if=‘false’ v-if是條件渲染,當false的時候不會渲染
開發中常用的指令有哪些
v-model :一般用在表達輸入,很輕松的實現表單控件和數據的雙向綁定
v-html: 更新元素的 innerHTML
v-show 與 v-if: 條件渲染, 注意二者區別
使用了v-if的時候,如果值為false,那么頁面將不會有這個html標簽生成 v-show則是不管值為true還是false,html元素都會存在,只是CSS中的display顯示或隱藏 復制代碼v-on : click: 可以簡寫為@click,@綁定一個事件。如果事件觸發了,就可以指定事件的處理函數 v-for:基于源數據多次渲染元素或模板塊 v-bind: 當表達式的值改變時,將其產生的連帶影響,響應式地作用于 DOM
語法:v-bind:title="msg" 簡寫::title="msg" 復制代碼綁定class的數組用法
對象方法 v-bind:class="{'orange': isRipe, 'green': isNotRipe}"
數組方法 v-bind:class="[class1, class2]"
行內 v-bind:style="{color: color, fontSize: fontSize+'px' }"
組件之間的傳值通信
父組件給子組件傳值
使用props,父組件可以使用props向子組件傳遞數據
父組件vue模板father.vue
<template><child :msg="message"></child> </template><script>
import child from ‘./child.vue’;
export default {
components: {
child
},
data () {
return {
message: ‘father message’;
}
}
}
</script>
復制代碼子組件vue模板child.vue:
<template><div>{{msg}}</div> </template><script> export default {props: {msg: {type: String,required: true}} } </script> 復制代碼子組件向父組件通信
父組件向子組件傳遞事件方法,子組件通過$emit觸發事件,回調給父組件
父組件vue模板father.vue:
<template><child @msgFunc="func"></child> </template><script>
import child from ‘./child.vue’;
export default {
components: {
child
},
methods: {
func (msg) {
console.log(msg);
}
}
}
</script>
復制代碼子組件vue模板child.vue:
<template><button @click="handleClick">點我</button> </template><script> export default {props: {msg: {type: String,required: true}},methods () {handleClick () {//........this.$emit('msgFunc');}} } </script> 復制代碼非父子,兄弟組件之間通信
可以通過實例一個vue實例Bus作為媒介,要相互通信的兄弟組件之中,都引入Bus,然后通過分別調用Bus事件觸發和監聽來實現通信和參數傳遞
Bus.js可以是這樣:
import Vue from 'vue' export default new Vue() 復制代碼在需要通信的組件都引入Bus.js:
<template><button @click="toBus">子組件傳給兄弟組件</button> </template><script>
import Bus from ‘…/common/js/bus.js’
export default{
methods: {
toBus () {
Bus.$emit(‘on’, ‘來自兄弟組件’)
}
}
}
</script>
復制代碼另一個組件也import Bus.js 在鉤子函數中監聽on事件
import Bus from '../common/js/bus.js' export default {data() {return {message: ''}},mounted() {Bus.$on('on', (msg) => {this.message = msg})}} 復制代碼路由跳轉方式
1,<router-link to='home'> router-link標簽會渲染為<a>標簽,咋填template中的跳轉都是這種;2,另一種是編程是導航 也就是通過js跳轉 比如 router.push('/home') 復制代碼MVVM
M - Model,Model 代表數據模型,也可以在 Model 中定義數據修改和操作的業務邏輯V - View,View 代表 UI 組件,它負責將數據模型轉化為 UI 展現出來VM - ViewModel,ViewModel 監聽模型數據的改變和控制視圖行為、處理用戶交互,簡單理解就是一個同步 View 和 Model 的對象,連接 Model 和 View 復制代碼computed和watch有什么區別?
computed:
1. computed是計算屬性,也就是計算值,它更多用于計算值的場景 2. computed具有緩存性,computed的值在getter執行后是會緩存的,只有在它依賴的屬性值改變之后,下一次獲取computed的值時才會重新調用對應的getter來計算 3. computed適用于計算比較消耗性能的計算場景 復制代碼watch:
1. 更多的是「觀察」的作用,類似于某些數據的監聽回調,用于觀察props $emit或者本組件的值,當數據變化時來執行回調進行后續操作 2. 無緩存性,頁面重新渲染時值不變化也會執行 復制代碼小結:
1. 當我們要進行數值計算,而且依賴于其他數據,那么把這個數據設計為computed 2. 如果你需要在某個數據變化時做一些事情,使用watch來觀察這個數據變化 復制代碼key
key是為Vue中的vnode標記的唯一id,通過這個key,我們的diff操作可以 更準確、更快速
準確:
如果不加key,那么vue會選擇復用節點(Vue的就地更新策略),導致之前節點的狀態被保留下來,會產生一系列的bug快速:
key的唯一性可以被Map數據結構充分利用組件中的data為什么是函數?
為什么組件中的data必須是一個函數,然后return一個對象,而new Vue實例里,data可以直接是一個對象?
// data data() {return {message: "子組件",childName:this.name} }// new Vue
new Vue({
el: ‘#app’,
router,
template: ‘<App/>’,
components: {App}
})
復制代碼因為組件是用來復用的,JS里對象是引用關系,這樣作用域沒有隔離,而new Vue的實例,是不會被復用的,因此不存在引用對象問題
Class 與 Style 如何動態綁定?
Class 可以通過對象語法和數組語法進行動態綁定:
對象語法
<div v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>data: {
isActive: true,
hasError: false
}
復制代碼數組語法
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>data: {activeClass: 'active',errorClass: 'text-danger' } 復制代碼Style 也可以通過對象語法和數組語法進行動態綁定:
對象語法
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>data: {
activeColor: ‘red’,
fontSize: 30
}
復制代碼數組語法
<div v-bind:style="[styleColor, styleSize]"></div>data: {styleColor: {color: 'red'},styleSize:{fontSize:'23px'} } 復制代碼vue的單項數據流
所有的 prop 都使得其父子 prop 之間形成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中,但是反過來則不行。這樣會防止從子組件意外改變父級組件的狀態,從而導致你的應用的數據流向難以理解
額外的,每次父級組件發生更新時,子組件中所有的 prop 都將會刷新為最新的值。這意味著你不應該在一個子組件內部改變 prop。如果你這樣做了,Vue 會在瀏覽器的控制臺中發出警告。子組件想修改時,只能通過 $emit 派發一個自定義事件,父組件接收到后,由父組件修改
有兩種常見的試圖改變一個 prop 的情形 :
這個 prop 用來傳遞一個初始值;這個子組件接下來希望將其作為一個本地的 prop 數據來使用
在這種情況下,最好定義一個本地的 data 屬性并將這個 prop 用作其初始值:
props: ['initialCounter'], data: function () {return {counter: this.initialCounter} } 復制代碼這個 prop 以一種原始的值傳入且需要進行轉換
在這種情況下,最好使用這個 prop 的值來定義一個計算屬性
props: ['size'], computed: {normalizedSize: function () {return this.size.trim().toLowerCase()} } 復制代碼keep-alive
keep-alive 是 Vue 內置的一個組件,可以使被包含的組件保留狀態,避免重新渲染 ,其有以下特性:
- 一般結合路由和動態組件一起使用,用于緩存組件;
- 提供 include 和 exclude 屬性,兩者都支持字符串或正則表達式, include 表示只有名稱匹配的組件會被緩存,exclude 表示任何名稱匹配的組件都不會被緩存 ,其中 exclude 的優先級比 include 高;
- 對應兩個鉤子函數 activated 和 deactivated ,當組件被激活時,觸發鉤子函數 activated,當組件被移除時,觸發鉤子函數 deactivated。
v-model 的原理
vue 項目中主要使用 v-model 指令在表單 input、textarea、select 等元素上創建雙向數據綁定,我們知道 v-model 本質上不過是語法糖,v-model 在內部為不同的輸入元素使用不同的屬性并拋出不同的事件:
- text 和 textarea 元素使用 value 屬性和 input 事件;
- checkbox 和 radio 使用 checked 屬性和 change 事件;
- select 字段將 value 作為 prop 并將 change 作為事件;
以 input 表單元素為例:
<input v-model='something'> 復制代碼相當于
<input v-bind:value="something" v-on:input="something = $event.target.value"> 復制代碼如果在自定義組件中,v-model 默認會利用名為 value 的 prop 和名為 input 的事件,如下所示:
父組件: <ModelChild v-model="message"></ModelChild>子組件:
<div>{{value}}</div>props:{
value: String
},
methods: {
test1(){
this.$emit(‘input’, ‘小紅’)
},
},
復制代碼nextTick()
在下次DOM更新循環結束之后執行延遲回調。在修改數據之后,立即使用的這個回調函數,獲取更新后的DOM
// 修改數據 vm.msg = 'Hello' // DOM 還未更新 Vue.nextTick(function () {// DOM 更新 }) 復制代碼vue插槽
個人覺得這篇文章寫的還可以:www.cnblogs.com/chinabin199…
單個插槽
當子組件模板只有一個沒有屬性的插槽時, 父組件傳入的整個內容片段將插入到插槽所在的 DOM 位置, 并替換掉插槽標簽本身 復制代碼命名插槽
solt元素可以用一個特殊的特性name來進一步配置如何分發內容。 多個插槽可以有不同的名字。 這樣可以將父組件模板中 slot 位置, 和子組件 slot 元素產生關聯,便于插槽內容對應傳遞 復制代碼作用域插槽
可以訪問組件內部數據的可復用插槽(reusable slot) 在父級中,具有特殊特性 slot-scope 的<template> 元素必須存在, 表示它是作用域插槽的模板。slot-scope 的值將被用作一個臨時變量名, 此變量接收從子組件傳遞過來的 prop 對象 復制代碼vue-router有哪幾種導航鉤子
第一種:是全局導航鉤子:router.beforeEach(to,from,next),作用:跳轉前進行判斷攔截
第二種:組件內的鉤子
第三種:單獨路由獨享組件
vuex
vuex是什么?
vuex 就是一個倉庫,倉庫里放了很多對象。其中 state 就是數據源存放地,對應于一般 vue 對象里面的 datastate 里面存放的數據是響應式的,vue 組件從 store 讀取數據,若是 store 中的數據發生改變,依賴這相數據的組件也會發生更新
它通過 mapState 把全局的 state 和 getters 映射到當前組件的 computed 計算屬性
復制代碼Vuex有5種屬性: 分別是 state、getter、mutation、action、module;
state
Vuex 使用單一狀態樹,即每個應用將僅僅包含一個store 實例,但單一狀態樹和模塊化并不沖突。存放的數據狀態,不可以直接修改里面的數據mutations
mutations定義的方法動態修改Vuex 的 store 中的狀態或數據getters
類似vue的計算屬性,主要用來過濾一些數據action
actions可以理解為通過將mutations里面處里數據的方法變成可異步的處理數據的方法,簡單的說就是異步操作數據。view 層通過 store.dispath 來分發 action總結
vuex 一般用于中大型 web 單頁應用中對應用的狀態進行管理,對于一些組件間關系較為簡單的小型應用,使用 vuex 的必要性不是很大,因為完全可以用組件 prop 屬性或者事件來完成父子組件之間的通信,vuex 更多地用于解決跨組件通信以及作為數據中心集中式存儲數據你有對 Vue 項目進行哪些優化?
代碼層面的優化
v-if 和 v-show 區分使用場景 computed 和 watch 區分使用場景 v-for 遍歷必須為 item 添加 key,且避免同時使用 v-if 長列表性能優化 事件的銷毀 圖片資源懶加載 路由懶加載 第三方插件的按需引入 優化無限列表性能 服務端渲染 SSR or 預渲染 復制代碼Webpack 層面的優化
Webpack 對圖片進行壓縮 減少 ES6 轉為 ES5 的冗余代碼 提取公共代碼 模板預編譯 提取組件的 CSS 優化 SourceMap 構建結果輸出分析 Vue 項目的編譯優化 復制代碼基礎的 Web 技術的優化
開啟 gzip 壓縮 瀏覽器緩存 CDN 的使用 使用 Chrome Performance 查找性能瓶頸 復制代碼ES6
var、let、const之間的區別
var聲明變量可以重復聲明,而let不可以重復聲明
var是不受限于塊級的,而let是受限于塊級
var會與window相映射(會掛一個屬性),而let不與window相映射
var可以在聲明的上面訪問變量,而let有暫存死區,在聲明的上面訪問變量會報錯
const聲明之后必須賦值,否則會報錯
const定義不可變的量,改變了就會報錯
const和let一樣不會與window相映射、支持塊級作用域、在聲明的上面訪問變量會報錯
解構賦值
數組解構
let [a, b, c] = [1, 2, 3] //a=1, b=2, c=3 let [d, [e], f] = [1, [2], 3] //嵌套數組解構 d=1, e=2, f=3 let [g, ...h] = [1, 2, 3] //數組拆分 g=1, h=[2, 3] let [i,,j] = [1, 2, 3] //不連續解構 i=1, j=3 let [k,l] = [1, 2, 3] //不完全解構 k=1, l=2 復制代碼對象解構
let {a, b} = {a: 'aaaa', b: 'bbbb'} //a='aaaa' b='bbbb' let obj = {d: 'aaaa', e: {f: 'bbbb'}} let {d, e:{f}} = obj //嵌套解構 d='aaaa' f='bbbb' let g; (g = {g: 'aaaa'}) //以聲明變量解構 g='aaaa' let [h, i, j, k] = 'nice' //字符串解構 h='n' i='i' j='c' k='e' 復制代碼函數參數的定義
一般我們在定義函數的時候,如果函數有多個參數時,在es5語法中函數調用時參數必須一一對應,否則就會出現賦值錯誤的情況,來看一個例子:
function personInfo(name, age, address, gender) {console.log(name, age, address, gender) } personInfo('william', 18, 'changsha', 'man') 復制代碼上面這個例子在對用戶信息的時候需要傳遞四個參數,且需要一一對應,這樣就會極易出現參數順序傳錯的情況,從而導致bug,接下來來看es6解構賦值是怎么解決這個問題的:
function personInfo({name, age, address, gender}) {console.log(name, age, address, gender) } personInfo({gender: 'man', address: 'changsha', name: 'william', age: 18}) 復制代碼這么寫我們只知道要傳聲明參數就行來,不需要知道參數的順序也沒關系
交換變量的值
在es5中我們需要交換兩個變量的值需要借助臨時變量的幫助,來看一個例子:
var a=1, b=2, c c = a a = b b = c console.log(a, b) 復制代碼來看es6怎么實現:
let a=1, b=2; [b, a] = [a, b] console.log(a, b) 復制代碼是不是比es5的寫法更加方便呢
函數默認參數
在日常開發中,經常會有這種情況:函數的參數需要默認值,如果沒有默認值在使用的時候就會報錯,來看es5中是怎么做的:
function saveInfo(name, age, address, gender) {name = name || 'william'age = age || 18address = address || 'changsha'gender = gender || 'man'console.log(name, age, address, gender) } saveInfo() 復制代碼在函數離 main先對參數做一個默認值賦值,然后再使用避免使用的過程中報錯,再來看es6中的使用的方法:
function saveInfo({name= 'william', age= 18, address= 'changsha', gender= 'man'} = {}) {console.log(name, age, address, gender) } saveInfo() 復制代碼在函數定義的時候就定義了默認參數,這樣就免了后面給參數賦值默認值的過程,是不是看起來簡單多了
forEach、for in、for of三者區別
forEach更多的用來遍歷數
for in 一般常用來遍歷對象或json
for of數組對象都可以遍歷,遍歷對象需要通過和Object.keys()
for in循環出的是key,for of循環出的是value
使用箭頭函數應注意什么?
1、用了箭頭函數,this就不是指向window,而是父級(指向是可變的)
2、不能夠使用arguments對象
3、不能用作構造函數,這就是說不能夠使用new命令,否則會拋出一個錯誤
4、不可以使用yield命令,因此箭頭函數不能用作 Generator 函數Set、Map的區別
應用場景Set用于數據重組,Map用于數據儲存
Set:
1,成員不能重復
2,只有鍵值沒有鍵名,類似數組
3,可以遍歷,方法有add, delete,hasMap:
1,本質上是健值對的集合,類似集合
2,可以遍歷,可以跟各種數據格式轉換promise對象的用法,手寫一個promise
promise是一個構造函數,下面是一個簡單實例
var promise = new Promise((resolve,reject) => {if (操作成功) {resolve(value)} else {reject(error)} }) promise.then(function (value) {// success },function (value) {// failure })復制代碼
Ajax
如何創建一個ajax
(1)創建XMLHttpRequest對象,也就是創建一個異步調用對象
(2)創建一個新的HTTP請求,并指定該HTTP請求的方法、URL及驗證信息
(3)設置響應HTTP請求狀態變化的函數
(4)發送HTTP請求
(5)獲取異步調用返回的數據
(6)使用JavaScript和DOM實現局部刷新同步和異步的區別
同步:
瀏覽器訪問服務器請求,用戶看得到頁面刷新,重新發請求,等請求完,頁面刷新,新內容出現,用戶看到新內容,進行下一步操作異步:
瀏覽器訪問服務器請求,用戶正常操作,瀏覽器后端進行請求。等請求完,頁面不刷新,新內容也會出現,用戶看到新內容ajax的優點和缺點
ajax的優點
1、無刷新更新數據(在不刷新整個頁面的情況下維持與服務器通信)
2、異步與服務器通信(使用異步的方式與服務器通信,不打斷用戶的操作)
3、前端和后端負載均衡(將一些后端的工作交給前端,減少服務器與寬度的負擔)
4、界面和應用相分離(ajax將界面和應用分離也就是數據與呈現相分離)ajax的缺點
1、ajax不支持瀏覽器back按鈕
2、安全問題 Aajax暴露了與服務器交互的細節
3、對搜索引擎的支持比較弱
4、破壞了Back與History后退按鈕的正常行為等瀏覽器機制get和post的區別
1、get和post在HTTP中都代表著請求數據,其中get請求相對來說更簡單、快速,效率高些 2、get相對post安全性低
3、get有緩存,post沒有
4、get體積小,post可以無限大
5、get的url參數可見,post不可見
6、get只接受ASCII字符的參數數據類型,post沒有限制
7、get請求參數會保留歷史記錄,post中參數不會保留
8、get會被瀏覽器主動catch,post不會,需要手動設置
9、get在瀏覽器回退時無害,post會再次提交請求什么時候使用post?
post一般用于修改服務器上的資源,對所發送的信息沒有限制。比如
1、無法使用緩存文件(更新服務器上的文件或數據庫)
2、向服務器發送大量數據(POST 沒有數據量限制)
3、發送包含未知字符的用戶輸入時,POST 比 GET 更穩定也更可靠如何解決跨域問題
跨域的概念:協議、域名、端口都相同才同域,否則都是跨域
解決跨域問題:
1、使用JSONP(json+padding)把數據內填充起來
2、CORS方式(跨域資源共享),在后端上配置可跨域
3、服務器代理,通過服務器的文件能訪問第三方資源什么是Ajax和JSON,它們的優點和缺點
Ajax:
Ajax是異步JavaScript和XML,用于在Web頁面中實現異步數據交互
Ajax優點:
異步請求響應快,用戶體驗好;頁面無刷新、數據局部更新;按需取數據,減少了冗余請求和服務器的負擔;
Ajax缺點:
異步回調問題、this指向問題、路由跳轉back問題;對搜索引擎的支持比較弱,對于一些手機還不是很好的支持
JSON:
是一種輕量級的數據交換格式,看著像對象,本質是字符串
JSON優點:
輕量級、易于人的閱讀和編寫,便于js解析,支持復合數據類型
JSON缺點:
沒有XML格式這么推廣的深入人心和使用廣泛, 沒有XML那么通用性
Github
git常用的命令
從遠程庫克隆到本地:git clone 網站上的倉庫地址
新增文件的命令:git add .
提交文件的命令:git commit –m或者git commit –a
查看工作區狀況:git status –s
拉取合并遠程分支的操作:git fetch/git merge或者git pull
查看提交記錄命令:git reflog
webpack
webpack打包原理
webpack只是一個打包模塊的機制,只是把依賴的模塊轉化成可以代表這些包的靜態文件。webpack就是識別你的 入口文件。識別你的模塊依賴,來打包你的代碼。至于你的代碼使用的是commonjs還是amd或者es6的import。webpack都會對其進行分析。來獲取代碼的依賴。webpack做的就是分析代碼。轉換代碼,編譯代碼,輸出代碼。webpack本身是一個node的模塊,所以webpack.config.js是以commonjs形式書寫的(node中的模塊化是commonjs規范的)
模塊熱更新
模塊熱更新是webpack的一個功能,他可以使代碼修改過后不用刷新就可以更新,是高級版的自動刷新瀏覽器
devServer中通過hot屬性可以控制模塊的熱替換
通過配置文件
const webpack = require('webpack'); const path = require('path'); let env = process.env.NODE_ENV == "development" ? "development" : "production"; const config = {mode: env,devServer: {hot:true} }plugins: [new webpack.HotModuleReplacementPlugin(), //熱加載插件], module.exports = config; 復制代碼通過命令行
"scripts": {"test": "echo \"Error: no test specified\" && exit 1","start": "NODE_ENV=development webpack-dev-server --config webpack.develop.config.js --hot",}, 復制代碼如何提高webpack構建速度
1、通過externals配置來提取常用庫
2、利用DllPlugin和DllReferencePlugin預編譯資源模塊 通過DllPlugin來對那些我們引用但是絕對不會修改的npm包來進行預編譯,再通過DllReferencePlugin將預編譯的模塊加載進來
3、使用Happypack 實現多線程加速編譯
要注意的第一點是,它對file-loader和url-loader支持不好,所以這兩個loader就不需要換成happypack了,其他loader可以類似地換一下
4、使用Tree-shaking和Scope Hoisting來剔除多余代碼 5、使用fast-sass-loader代替sass-loader 6、babel-loader開啟緩存
babel-loader在執行的時候,可能會產生一些運行期間重復的公共文件,造成代碼體積大冗余,同時也會減慢編譯效率 可以加上cacheDirectory參數或使用 transform-runtime 插件試試
// webpack.config.js use: [{loader: 'babel-loader',options: {cacheDirectory: true }] // .bablerc {"presets": ["env","react"],"plugins": ["transform-runtime"] } 復制代碼不需要打包編譯的插件庫換成全局"script"標簽引入的方式
比如jQuery插件,react, react-dom等,代碼量是很多的,打包起來可能會很耗時 可以直接用標簽引入,然后在webpack配置里使用 expose-loader 或 externals 或 ProvidePlugin 提供給模塊內部使用相應的變量
// @1 use: [{loader: 'expose-loader',options: '$'}, {loader: 'expose-loader',options: 'jQuery'}] // @2 externals: {jquery: 'jQuery'}, // @3new webpack.ProvidePlugin({$: 'jquery',jQuery: 'jquery','window.jQuery': 'jquery'}), 復制代碼8、優化構建時的搜索路徑
在webpack打包時,會有各種各樣的路徑要去查詢搜索,我們可以加上一些配置,讓它搜索地更快 比如說,方便改成絕對路徑的模塊路徑就改一下,以純模塊名來引入的可以加上一些目錄路徑 還可以善于用下resolve alias別名 這個字段來配置 還有exclude等的配置,避免多余查找的文件,比如使用babel別忘了剔除不需要遍歷的
webpack的優點
專注于處理模塊化的項目,能做到開箱即用,一步到位
可通過plugin擴展,完整好用又不失靈活
使用場景不局限于web開發
社區龐大活躍,經常引入緊跟時代發展的新特性,能為大多數場景找到已有的開源擴展
良好的開發體驗
webpack的缺點
webpack的缺點是只能用于采用模塊化開發的項目
微信小程序
文件主要目錄及文件作用
- 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():頁面卸載時觸發。 復制代碼如何封裝數據請求
1,封裝接口
項目/utils/api.js
// 將請求進行 Promise 封裝 const fetch = ({url, data}) => {// 打印接口請求的信息
console.log(【step 1】API 接口:<span>${url}</span>);
console.log("【step 2】data 傳參:");
console.log(data);// 返回 Promise
// 成功時的處理 <span>if</span> (res.data.code == 0) {console.log(<span>"【step 3】請求成功:"</span>);console.log(res.data);<span>return</span> resolve(res.data);} <span>else</span> {wx.showModal({title: <span>'請求失敗'</span>,content: res.data.message,showCancel: <span>false</span>});}},fail: err => {// 失敗時的處理console.log(err);<span>return</span> reject(err);} })
return new Promise((resolve, reject) => {
wx.request({
url: getApp().globalData.api + url,
data: data,
success: res => {})
}
/**
- code 換取 openId
- @data {
- jsCode - wx.login() 返回的 code
- }
*/
export const wxLogin = data => {
return fetch({
url: “tbcUser/getWechatOpenId”,
data: data
})
}
復制代碼2,調用接口
項目/pages/login/login.js
import {wxLogin, } from '../../utils/api.js' 復制代碼3,使用接口
項目/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);} ) 復制代碼頁面數據傳遞
通過 url 攜帶參數,在 onLoad() 中通過 options 獲取 url 上的參數:
<navigator url="../index/index?userId={{userId}}"></navigator><!-- 這兩段是分別在 HTML 和 JS 中的代碼 -->
onLoad: function(options) {
console.log(options.userId);
}
復制代碼通過 Storage 來傳遞參數:
wx.setStorageSync('userId', 'jsliang'); wx.getStorageSync('userId'); 復制代碼WXML傳遞數據到 JS
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> 復制代碼通過接口調用傳遞參數
加載性能優化方法
1、通過 this.$preload() 預加載用戶可能點擊的第二個頁面
2、組件化頁面,出現兩次以上的部分都進行封裝成組件
3、提取共用的 CSS 樣式
4、優化圖片:TinyPNG
微信小程序與原生APP、Vue、H5差異
微信小程序優勢
1、無需下載
2、打開速度較快
3、開發成本低于原生APP微信小程序劣勢
1、限制多。頁面大小不能超過 1M,不能打開超過 5 個層級的頁面
2、樣式單一。小程序內部組件已經成宿,樣式不可以修改
3、推廣面窄。跑不出微信,還不能跑入朋友圈微信小程序 VS 原生APP
微信小程序有著低開發成本、低獲客成本、無需下載的優勢微信小程序 VS H5
1、依賴環境不同。一個能在多種手機瀏覽器運行。一個只能在微信中的非完整的瀏覽器
2、開發成本不同。一個可能在各種瀏覽器出問題。一個只能在微信中運行微信小程序 VS Vue
微信小程序看似就是閹割版的 Vue微信小程序原理
本質上就是一個單頁面應用,所有的頁面渲染和事件處理,都在一個頁面中進行
架構為數據驅動的模式,UI 和數據分離,所有頁面的更新,都需要通過對數據的更改來實現
微信小程序分為兩個部分:webview 和 appService。其中 webview 主要用來展示 UI,appServer 用來處理業務邏輯、數據及接口調用。它們在兩個進程中進行,通過系統層 JSBridge 實現通信,實現 UI 的渲染、事件的處理
wxml與標準的html的異同
wxml基于xml設計,標簽只能在微信小程序中使用,不能使用html的標簽
網絡協議
網絡分層
目前網絡分層可分為兩種:OSI 模型和 TCP/IP 模型
OSI模型
應用層(Application)
表示層(Presentation)
會話層(Session)
傳輸層(Transport)
網絡層(Network)
數據鏈路層(Data Link)
物理層(Physical)TCP/IP模型
應用層(Application)
傳輸層(Host-to-Host Transport)
互聯網層(Internet)
網絡接口層(Network Interface)HTTP/HTTPS
1、https協議需要到ca申請證書,一般免費證書較少,因而需要一定費用
2、http是超文本傳輸協議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協議
3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443
4、http的連接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。HTTP狀態碼
區分狀態碼
1××開頭 - 信息提示
2××開頭 - 請求成功
3××開頭 - 請求被重定向
4××開頭 - 請求錯誤
5××開頭 - 服務器錯誤常見狀態碼
200 - 請求成功,Ajax 接受到信息了
400 - 服務器不理解請求
403 - 服務器拒絕請求
404 - 請求頁面錯誤
500 - 服務器內部錯誤,無法完成請求性能優化
HTML優化
1、避免 HTML 中書寫 CSS 代碼,因為這樣難以維護。 2、使用 Viewport 加速頁面的渲染。 3、使用語義化標簽,減少 CSS 代碼,增加可讀性和 SEO。 4、減少標簽的使用,DOM 解析是一個大量遍歷的過程,減少不必要的標簽,能降低遍歷的次數。 5、避免 src、href 等的值為空,因為即時它們為空,瀏覽器也會發起 HTTP 請求。 6、減少 DNS 查詢的次數 復制代碼CSS優化
1、優化選擇器路徑:使用 .c {} 而不是 .a .b .c {}。 2、選擇器合并:共同的屬性內容提起出來,壓縮空間和資源開銷。 3、精準樣式:使用 padding-left: 10px 而不是 padding: 0 0 0 10px。 4、雪碧圖:將小的圖標合并到一張圖中,這樣所有的圖片只需要請求一次。 5、避免通配符:.a .b * {} 這樣的選擇器,根據從右到左的解析順序在解析過程中遇到通配符 * {} 6、會遍歷整個 DOM,性能大大損耗。 7、少用 float:float 在渲染時計算量比較大,可以使用 flex 布局。 8、為 0 值去單位:增加兼容性。 9、壓縮文件大小,減少資源下載負擔。 復制代碼JavaScript優化
1、盡可能把 <script> 標簽放在 body 之后,避免 JS 的執行卡住 DOM 的渲染,最大程度保證頁面盡快地展示出來 2、盡可能合并 JS 代碼:提取公共方法,進行面向對象設計等…… 3、CSS 能做的事情,盡量不用 JS 來做,畢竟 JS 的解析執行比較粗暴,而 CSS 效率更高。 4、盡可能逐條操作 DOM,并預定好 CSs 樣式,從而減少 reflow 或者 repaint 的次數。 5、盡可能少地創建 DOM,而是在 HTML 和 CSS 中使用 display: none 來隱藏,按需顯示。 6、壓縮文件大小,減少資源下載負擔。 復制代碼面試常見的其他問題
常問
1、自我介紹
2、你的項目中技術難點是什么?遇到了什么問題?你是怎么解決的?
3、你認為哪個項目做得最好?
4、平時是如何學習前端開發的?
5、你最有成就感的一件事
6、你是怎么學習前端的人事面
1、面試完你還有什么問題要問的嗎
2、你有什么愛好?
3、你最大的優點和缺點是什么?
4、你為什么會選擇這個行業,職位?
5、你覺得你適合從事這個崗位嗎?
6、你有什么職業規劃?
7、你對工資有什么要求?
8、如何看待前端開發?
9、未來三到五年的規劃是怎樣的?其他
談談你對重構的理解?
網絡重構:在不改變外部行為的前提下,簡化結構、添加可讀性,而在網站前端保持一致的行為。也就是說是在不改變UI的情況下,對網站進行優化, 在擴展的同時保持一致的UI
對于傳統的網站來說重構通常是:
- 表格(table)布局改為DIV+CSS
- 使網站前端兼容于現代瀏覽器(針對于不合規范的CSS、如對IE6有效的)
- 對于移動平臺的優化
- 針對于SEO進行優化
什么樣的前端代碼是好的?
高復用低耦合,這樣文件小,好維護,而且好擴展
對前端工程師這個職位是怎么樣理解的?它的前景會怎么樣?
前端是最貼近用戶的程序員,比后端、數據庫、產品經理、運營、安全都近
- 實現界面交互
- 提升用戶體驗
- 有了Node.js,前端可以實現服務端的一些事情
前端是最貼近用戶的程序員,前端的能力就是能讓產品從 90分進化到 100 分,甚至更好,
與團隊成員,UI設計,產品經理的溝通;
做好的頁面結構,頁面重構和用戶體驗;
你覺得前端工程的價值體現在哪?
1、為簡化用戶使用提供技術支持(交互部分)
2、為多個瀏覽器兼容性提供支持
3、為提高用戶瀏覽速度(瀏覽器性能)提供支持
4、為跨平臺或者其他基于webkit或其他渲染引擎的應用提供支持
5、為展示數據提供支持(數據接口)平時如何管理你的項目?
-
先期團隊必須確定好全局樣式(globe.css),編碼模式(utf-8) 等;
-
編寫習慣必須一致(例如都是采用繼承式的寫法,單樣式都寫成一行);
-
標注樣式編寫人,各模塊都及時標注(標注關鍵樣式調用的地方);
-
頁面進行標注(例如 頁面 模塊 開始和結束);
-
CSS跟HTML 分文件夾并行存放,命名都得統一(例如style.css);
-
JS 分文件夾存放 命名以該JS功能為準的英文翻譯。
-
圖片采用整合的 images.png png8 格式文件使用 - 盡量整合在一起使用方便將來的管理
移動端(Android IOS)怎么做好用戶體驗?
清晰的視覺縱線、
信息的分組、極致的減法、
利用選擇代替輸入、
標簽及文字的排布方式、
依靠明文確認密碼、
合理的鍵盤利用
總結
- 上一篇: Halcon机器视觉实战--分水岭分割+
- 下一篇: 文献检索与学术写作笔记(4)