Vue中computed和watch、method的區別
computed:計算屬性只有在相關的數據發生變化時才會改變要計算的屬性,當相關數據沒有變化是,它會讀取緩存。
一個數據受多個數據影響
a.支持緩存,只有依賴數據發生改變,才會重新進行計算
b.不支持異步,當computed內有異步操作時無效,無法監聽數據的變化
watch:當需要在數據變化時執行異步或開銷較大的操作時,一個數據影響多個數據
a. 不支持緩存,數據變,直接會觸發相應的操作;
b.watch支持異步;
methods:每次都會重新計算,computed只有依賴的數據變化時,才重新計算
vue是否可以監聽數組與對象的變化
Vue是可以監聽數組改變的,只是受JavaScript的限制,以下兩種情況除外:
a.當你利用索引直接設置一個數組項時,例如:vm.items[indexofItem]=newValue
b.當你修改數組的長度時,例如:vm.items.length=newLength
vue 無法監聽數組變化的解決方案:
1).this.set(arr, index, newVal);
2).使用數組 splice 方法可以監聽,例子上面有
3).使用臨時變量直接賦值的方式
vue 可以監聽直接賦值的對象this.watchObj = {name: 'popo'};
vue 不能監聽對象屬性的添加、修改、刪除
vue 監聽對象的解決方法使用 this.$set(object, key, value)
v-show與v-if的區別
v-show 本質就是通過設置 css 中的 display 設置為 none,控制隱藏
v-if 是動態的向 DOM 樹內添加或者刪除 DOM 元素
v-show 只編譯一次,后面其實就是控制 css,而 v-if 不停的銷毀和創建,
如果要頻繁切換某節點時,使用 v-show
this.$nextTick()
this.$nextTick()將回調延遲到下次 DOM 更新循環之后執行。在修改數據之后立即使用它,然后等待 DOM 更新
keep-alive
原理:就是將需要緩存的VNode節點保存在this.cache中/在render時,如果VNode的name符合在緩存條件
(可以用include以及exclude控制),則會從this.cache中取出之前緩存的VNode實例進行渲染。
Vue 的響應式原理:
Vue是采用數據劫持配合發布者-訂閱者模式,通過Object.defineProperty來()
來劫持各個屬性的getter和setter在數據發生變化的時候,發布消息給依賴收集器,
去通知觀察者,做出對應的回調函數去更新視圖。
本地實現vue的雙向綁定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>測試</title>
</head>
<body>
<!-- 本地實現雙向綁定 -->
<input type="text" id="input">
<div id="show"></div>
</body>
<script>
// 本地實現雙向綁定
var obj={}
function defineProperty(obj,attr){
var val;
Object.defineProperty(obj,attr,{
get:function(){
return val
},
set:function(newVal){
if(newVal === val){
return
}
val = newVal
document.getElementById('input').value = newVal
document.getElementById('show').innerText = newVal
}
})
}
document.getElementById("input").addEventListener('keyup',function(e){
obj.txt = e.target.value
})
defineProperty(obj,'txt')
</script>
</html>
vuex的原理
vuex是利用vue的mixin混入機制,在beforeCreate鉤子前混入vuexInit方法
vuexInit方法實現了store注入vue組件實例,并注冊了vuex store的引用屬性$store
Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態,
并以相應的規則保證狀態以一種可預測的方式發生變化。
Vue中key的作用
key的特殊attribute主要用在Vue的虛擬DOM算法,在新舊Nodes對比時辨識VNodes。
vue的生命周期
(開始創建、初始化數據、編譯模板、掛載Dom、渲染、更新、渲染、卸載)主要分為八個階段:
1.beforeCreate data 和 $el 都沒有初始化 全部為 undefined
2.created data 初始化完成,但 $el 沒有初始化
3.beforeMount data 和 $el 均已存在,但 DOM 為虛擬DOM 仍未完全加載 eg:{{message}}
4.mounted data 和 $el 均已存在,并且 DOM 加載完成 ,完成掛載
當data中數據發生改變時觸發update相關函數
5.beforeUpdate 渲染完成,并監測到data發生變化,在變化的數據重新渲染視圖之前會觸發,
這也是重新渲染之前最后修改數據的機會
6.updated 監測到data發生變化,并完成渲染更新視圖之后觸發
6.beforeDestory 實例銷毀之前調用 , 實例仍然完全可用。
7.destroyed 實例銷毀后調用。
調用后,實例指示的所有東西都會解綁定,所有的事件監聽器會被移除,所有的子實例也會被銷毀。
vue的組件通信有哪些,具體用哪些方法?什么時候用vuex
父子props
兄弟 $emit
子父 $emit事件
祖父/子/孫子 provide/inject
vuex
Vuex與localStorage
vuex 是 vue 的狀態管理器,存儲的數據是響應式的。但是并不會保存起來,刷新之后就回到了初始狀態,
具體做法應該在vuex里數據改變的時候把數據拷貝一份保存到localStorage里面,
刷新之后,如果localStorage里有保存的數據,取出來再替換store里的state
hash與history的區別,在使用中遇到了哪些問題
即地址欄 URL 中的 # 符號hash 雖然出現在 URL 中,但不會被包括在 HTTP 請求中,對后端完全沒有影響,
因此改變 hash 不會重新加載頁面。
hash模式背后的原理是onhashchange事件,可以在window對象上監聽這個事件,
因為hash發生變化的url都會被瀏覽器記錄下來,從而你會發現瀏覽器的前進后退都可以用了
history利用H5的 history中新增的兩個API pushState() 和 replaceState() 和一個
事件onpopstate監聽URL變化
相對定位與絕對定位;相對定位?flex布局垂直居中?絕對定位與用translate定位有什么區別
1.position 的四個值:static、relative、absolute、fixed。
絕對定位:absolute 和 fixed 統稱為絕對定位
相對定位:relative
默認值:static
relative:相對于原來位置移動,元素設置此屬性之后仍然處在文檔流中,不影響
其他元素的布局
absolute:元素會脫離文檔流,如果設置偏移量,會影響其他元素的位置定位
absolute定位原理剖析:
(1.在父元素沒有設置相對定位或絕對定位的情況下,元素相對于根元素定位(即html元素)(是父元素沒有)。
(2.父元素設置了相對定位或絕對定位,元素會相對于離自己最近的設置了相對或
絕對定位的父元素進行定位(或者說離自己最近的不是static的父元素進行定位,因為元素默認是static)
flex布局垂直居中:
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
事件委托:
事件委托利用了事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件
transition、transform、animate的區別?
transition需要事件觸發,比如:hover、:focus、:checked或者js
操作css樣式的變更,所以沒法在網頁加載時自動發生。
transition是一次性的,不能重復發生,除非一再觸發。
transition只能定義開始狀態和結束狀態,不能定義中間狀態,也就是說只有兩個狀態。
animation不需要觸發
可以定義初始中間結束狀態
可重復發生
transform: 應用于元素的2D或3D轉換。這個屬性允許你將元素旋轉,縮放,移動,傾斜等。
旋轉:rotate()、縮放:scale()、移動:translate()、傾斜:skew()
在瀏覽器輸入url后發生了什么
1.DNS域名解析;
2.建立TCP連接;
3.發送HTTP請求;
4.服務器處理請求;
5.返回響應結果;
6.關閉TCP連接;
7.瀏覽器解析HTML;
8.瀏覽器布局渲染;
get、post的區別
1.get傳參方式是通過地址欄URL傳遞,是可以直接看到get傳遞的參數,post傳參方式參數URL不可見,
get把請求的數據在URL后通過?連接,通過&進行參數分割。post將參數存放在HTTP的包體內
2.get傳遞數據是通過URL進行傳遞,對傳遞的數據長度是受到URL大小的限制,
URL最大長度是2048個字符。post沒有長度限制
3.get后退不會有影響,post后退會重新進行提交
4.get請求可以被緩存,post不可以被緩存
談談你對 TCP 三次握手和四次揮手的理解
http狀態碼
200請求成功
301永久重定向
302臨時重定向
401需要用戶身份驗證
404資源未找到
500服務器內部錯誤,無法完成請求
502作為網關或代理服務器請求時,從遠程服務器獲取到一個無效響應
504充當網關或帶理服務器,未及時從遠端服務器獲取請求
說一下CORS?CORS與JSONP的比較
跨域資源共享它允許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。
JSONP只支持GET請求,CORS支持所有類型的HTTP請求。JSONP的優勢在于支持老式瀏覽器,以及可以向不支持CORS
的網站請求數據。
JSONP 由兩部分組成:回調函數和數據。回調函數是當響應到來時應該在頁面
中調用的函數。回調函數的名字一般是在請求中指定的。而數據就是傳入回調函
數中的JSON數據
說一下宏任務和微任務?
image.png
image.png
說一下繼承的幾種方式及優缺點?
1)原型鏈繼承:
問題:引用類型的屬性被所有實例共享,一個被修改了,就都修改了
2)借用構造函數繼承call或apply
問題:但是只能繼承父類的實例屬性和方法,不能繼承原型屬性或者方法
優點:解決了數據共享問題
3)組合繼承
問題:子類原型上多了一份父類的實例屬性
優點:解決了 原型繼承和構造函數繼承的缺點
其背后的思路是使用原型鏈實現對原型屬性和方法的繼承,而通過借用構造函數來實現對實例屬性的繼承。
深拷貝和淺拷貝
深拷貝和淺拷貝最根本的區別在于是否真正獲取一個對象的復制實體,而不是引用。
假設B復制了A,修改A的時候,看B是否發生變化:
如果B跟著也變了,說明是淺拷貝,拿人手短!(修改堆內存中的同一個值)
如果B沒有改變,說明是深拷貝,自食其力!(修改堆內存中的不同的值)
淺拷貝(shallowCopy)只是增加了一個指針指向已存在的內存地址,
深拷貝(deepCopy)是增加了一個指針并且申請了一個新的內存,使這個增加的指針指向這個新的內存
數組去重 的方法
1)利用ES6 Set去重(ES6中最常用)
2)利用for嵌套for,然后splice去重(ES5中最常用)
3)利用indexOf去重
4)利用sort()然后判斷相鄰元素
5)利用hasOwnProperty
6)利用filter
7)利用Map數據結構去重
js中判斷是否是對象typeof、instanceof和constructor的區別
(1)typeof運算符,通常會返回:"undefined"、"object"、"boolean"、"number" 、"function" 和 "string"的字符串。數組和對象都返回"object"。
image.png
(2)instanceof運算符用來判斷一個對象是否為一個類的實例;判斷一個構造函數的prototype屬性所指向的對象是否存在另外一個要檢測對象的原型鏈上。可以區分數組和對象。
image.png
(3)constructor返回變量的構造函數;返回對創建此對象的數組函數的引用。可以區分數組和對象。
image.png
JS中的for循環
for
forEach
filter
map
some
every
原型與原型鏈prototype與proto
原型:
①所有引用類型都有一個__proto__(隱式原型)屬性,屬性值是一個普通的對象
②所有函數都有一個prototype(原型)屬性,屬性值是一個普通的對象
③所有引用類型的__proto__屬性指向它構造函數的prototype
原型鏈:
當訪問一個對象的某個屬性時,會先在這個對象本身屬性上查找,如果沒有找到,則會去它的__proto__
隱式原型上查找,即它的構造函數的prototype,
如果還沒有找到就會再在構造函數的prototype的__proto__中查找,這樣一層一層向上查找就會形成一個
鏈式結構,我們稱為原型鏈。
改變this指向的方法bind,call,apply
function.bind(o,args….)bind返回一個作為方法調用的函數,一個新函數,
該函數會作為o的方法來調用,并向他傳入args參數
apply傳的參數,第一個是要將this指向誰,第二個是數組參數
call傳的參數是多個,第一個是要將this指向誰,其他是參數
call和apply返回的是調用函數function的返回值
閉包,閉包的作用域
閉包就是能夠讀取其他函數內部變量的函數。
它的最大用處有兩個,一個是前面提到的可以讀取函數內部的變量,
另一個就是讓這些變量的值始終保持在內存中,不會在f1調用后被自動清除。
遞歸:什么是遞歸?項目中什么位置用到了遞歸
['']==''返回什么?為什么?運算符==進行了什么操作?
1.[''].valueof轉為原始值''
2.''轉為數字0
3.0==''再將''轉為數字0,再比較
請求多個接口時,要保證同時拿到數據,渲染到同一個頁面上的方法。一個頁面渲染需要3個接口返回的數據,怎么判斷這3個接口都返回成功
Promise.all可以將多個Promise實例包裝成一個新的Promise實例。同時,成功和失敗的返回值是不同的,成功的時候返回的是一個結果數組,而失敗的時候則返回最先被reject失敗狀態的值。
Promise.all([methods1, methods2]).then(res => {
//在方法1 和方法2 都請求成功時再進行操作。
})
es6的新特性
1.let/const的變量聲明
2.模板字符串
3.箭頭函數
4.參數的默認值賦值
5.對象與數組的解構賦值
6.for of遍歷迭代器如數組,for/in遍歷對象
es6遍歷對象的方法
for … in
Object.keys()
Object.getOwnPropertyNames(obj),
Reflect.ownKeys(obj)
let var const 聲明變量的區別
① var聲明的變量屬于函數作用域;let 和 const 聲明的變量屬于塊級作用域,不能跨函數訪問;
② var存在變量提升現象,而 let 和 const 沒有;
③ var變量可以重復聲明,值可改變;在同一個塊級作用域下:let變量不能重新聲明;
const定義的變量是常量,聲明時必須賦值,但不允許重復賦值,如果定義的是引用類型,可以修改數據內部結構。
柯里化函數:一道經典面試題
// 實現一個add方法,使計算結果能夠滿足如下預期:
add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;
function add() {
// 第一次執行時,定義一個數組專門用來存儲所有的參數
var _args = Array.prototype.slice.call(arguments);
// 在內部聲明一個函數,利用閉包的特性保存_args并收集所有的參數值
var _adder = function() {
_args.push(...arguments);
return _adder;
};
// 利用toString隱式轉換的特性,當最后執行時隱式轉換,并計算最終的值返回
_adder.toString = function () {
return _args.reduce(function (a, b) {
return a + b;
});
}
return _adder;
}
add(1)(2)(3) // 6
add(1, 2, 3)(4) // 10
add(1)(2)(3)(4)(5) // 15
add(2, 6)(1) // 9
普通函數與箭頭函數的區別
① 外形不同:箭頭函數使用箭頭定義,普通函數中沒有
②箭頭函數都是匿名函數普通函數可以有匿名函數,也可以有具體名函數,但是箭頭函數都是匿名函數
③箭頭函數不能用于構造函數,不能使用new
③箭頭函數中this的指向不同
在普通函數中,this總是指向調用它的對象,如果用作構造函數,this指向創建的對象實例。
延長作用域鏈
? try-catch 語句的 catch 塊;
? with 語句
前端性能優化
1.減少請求數量:
合并:公共庫合并
圖片處理:雪碧圖,base64,字體圖標如阿里圖標庫
減少重定向
使用緩存
不使用CSS @import
避免使用空的src和href
2.減少資源大小
【1.壓縮】:
html壓縮:不顯示 空格,制表符,換行符
css壓縮:刪除無效代碼,語義合并
JS壓縮與混亂包括無效字符及注釋的刪除、代碼語義的縮減和優化、降低代
碼可讀性,實現代碼保護
圖片壓縮
【2.使用webp】:在安卓下可以使用webp格式的圖片,它具有更優的圖像數據
壓縮算法,能帶來更小的圖片體積
【3.開啟Gzip:】HTTP協議上的GZIP編碼是一種用來改進WEB應用程序性能的技術
3.優化網絡連接:dns預解析
<link rel="dns-prefecth" >
4.優化資源加載:
【加載位置】,css在head,js在body最后,
【資源加載時機】:
1、異步script標簽:defer、async
2、模塊按需加載:需要根據路由來加載當前頁面需要的業務模塊
3、使用資源預加載preload和資源預讀取prefetch
4、資源懶加載與資源預加載
5.減少重繪回流:
【樣式設置】:
1、避免使用層級較深的選擇器
2、避免使用CSS表達式
3、不要使用table布局
4、能夠使用CSS實現的效果,盡量使用CSS而不使用JS實現
【DOM優化】:
1、緩存DOM
2、減少DOM深度及DOM數量
3、事件代理
4、防抖和節流
5、及時清理環境:垃圾收集(標記清除,引用計數)
6.webpack優化
【打包公共代碼】
【動態導入和按需加載】
【剔除無用代碼】
【長緩存優化】
【公用代碼內聯】:使用html-webpack-inline-chunk-plugin插件將mainfest.js內聯到html文件中
promise的三種狀態
pending/reslove/reject 。pending就是未完成,resolve可以理解為成功,reject可以理解為拒絕
函數與變量的提升
變量提升:在函數域里定義一個和外部變量一樣名稱的變量時,變量的聲明會提升至第一句,賦值則不會變。
函數提升:在寫JS代碼的時候,有兩種寫法,一種是函數表達式,
另外一種是函數聲明方式。我們需要重點注意的是,只有函數聲明形式才能被提升。
防抖節流
作用域與作用域鏈
異步控制(promise,es6 generate,Async)
模塊化開發模式(AMD,CMD,KMD)
javascript解釋器(異步I/O實現,垃圾回收,事件隊列)
自身的優點
以后的打算
離職的原因
技術面試問到你還有什么要問的嗎
未來一年,部門的工作任務是什么
入職后的3個月,會參加哪些培訓,
團隊有多少人,工作年限是多少
可以大概講一下公司的企業文化嗎