前段時(shí)間總結(jié)的部分面試題,有需要的可以看下哈~~??
什么是構(gòu)造函數(shù)
用 new 關(guān)鍵字來調(diào)用的函數(shù),稱為構(gòu)造函數(shù)。構(gòu)造函數(shù)首字母一般大寫
function Person4() {
this.gender = '男';
// return { gender: '中性' };
}
var p4 = new Person4();
console.log(p4.gender); // '中性'
什么是繼承
繼承指的是一個(gè)對(duì)象可以共享父級(jí)對(duì)象的一些屬性。
什么是原型鏈
對(duì)于對(duì)象而言,每個(gè) JS 對(duì)象一定對(duì)應(yīng)一個(gè)原型對(duì)象,并從原型對(duì)象繼承屬性和方法。對(duì)象proto屬性的值就是它所對(duì)應(yīng)的原型對(duì)象。對(duì)象的proto指向自己構(gòu)造函數(shù)的 prototype。所以對(duì)象的原型鏈就是obj.proto.proto__....。
function Person() {
return { };
}
var p = new Person();
console.log(p)
// {}
[[Prototype]]: Object
constructor: ? Object()
hasOwnProperty: ? hasOwnProperty()
isPrototypeOf: ? isPrototypeOf()
propertyIsEnumerable: ? propertyIsEnumerable()
toLocaleString: ? toLocaleString()
toString: ? toString()
valueOf: ? valueOf()
__defineGetter__: ? __defineGetter__()
__defineSetter__: ? __defineSetter__()
__lookupGetter__: ? __lookupGetter__()
__lookupSetter__: ? __lookupSetter__()
__proto__: (...)
get __proto__: ? __proto__()
set __proto__: ? __proto__()
對(duì)于函數(shù)而言,只有函數(shù)才有 prototype 屬性,Person.prototype 是一個(gè)對(duì)象,并且有兩個(gè)屬性, 一個(gè)是 constructor 指向其構(gòu)造函數(shù) Person, 一個(gè)是 proto 屬性:是一個(gè)對(duì)象,指向上一層的原型。
console.log(Person.prototype)
// {constructor: ?}
// constructor: ? Person()
// [[Prototype]]: Object
所有的對(duì)象會(huì)一層層往上找原型,最終點(diǎn)是 Object,而 Object 的上一層原型就是 null 了。
this的指向
- 箭頭函數(shù)的 this 是在創(chuàng)建它時(shí)外層 this 的指向
- 當(dāng)使用 new 關(guān)鍵字調(diào)用函數(shù)時(shí),函數(shù)中的 this 一定是 JS 創(chuàng)建的新對(duì)象(箭頭函數(shù)不能當(dāng)做構(gòu)造函數(shù))
cookie、localStorage和sessionStorage 三者之間的區(qū)別
- cookie 可設(shè)置失效時(shí)間/4KB左右/每次都會(huì)攜帶在HTTP頭中/只能保存字符串類型/同域名不同頁(yè)面的數(shù)據(jù)共享
- localStorage 除非被手動(dòng)清除,否則將會(huì)永久保存/可以保存5MB的信息。/可以用來夸頁(yè)面?zhèn)鬟f參數(shù)
- sessionStorage 僅在當(dāng)前網(wǎng)頁(yè)會(huì)話下有效,關(guān)閉頁(yè)面或?yàn)g覽器后就會(huì)被清除/可以保存5MB的信息。
ES6常用語(yǔ)法
- 解構(gòu)賦值
let [a,b] = [1,2]
let {a,b} = {a:1,b:2}
- 模板字符串
let str = `${name}的女朋友`;
- 去除空格 .trim()
let str = ' 10 10 ';
console.log(str); // ' 10 10 '
console.log(str.trim()); // '10 10'
// 如果要去除所有空格
let str = ' 10 10 ';
console.log(str.replace(/ /g, '')); // 1010
- 箭頭函數(shù)
(1)箭頭函數(shù)沒有自己的`this`對(duì)象,內(nèi)部的`this`就是定義時(shí)上層作用域中的`this`。。
(2)不可以當(dāng)作構(gòu)造函數(shù),也就是說,不可以對(duì)箭頭函數(shù)使用`new`命令,否則會(huì)拋出一個(gè)錯(cuò)誤。
(3)不可以使用`arguments`對(duì)象,該對(duì)象在函數(shù)體內(nèi)不存在。如果要用,可以用 rest 參數(shù)代替。
(4)不可以使用`yield`命令,因此箭頭函數(shù)不能用作 Generator 函數(shù)。
- 擴(kuò)展運(yùn)算符 ...
let obj = {...obj1}
let arr = [...arr1,...arr2] //合并數(shù)組 對(duì)象類似
[...'hello']
// [ "h", "e", "l", "l", "o" ]
find() ,findIndex() 查找數(shù)據(jù)/返回下標(biāo)
includes() 方法返回一個(gè)布爾值,表示某個(gè)數(shù)組是否包含給定的值,返回布爾值。
.flat() 一維數(shù)組轉(zhuǎn)換
let arr = [1,2,[3,4],[5,6,[7,8]]]
console.log(arr.flat(1)); //[1, 2, 3, 4, 5, 6, Array(2)]
console.log(arr.flat(2)); //[1, 2, 3, 4, 5, 6, 7, 8]
數(shù)組去重方法
- 利用ES6 Set去重(ES6中最常用)
Array.from(new Set(arr))
- 利用for嵌套for,然后splice去重(ES5中最常用)
var arr = [1, 1, 8, 8, 12, 12, 15, 15, 16, 16];
function unlink(arr) {
for (var i = 0; i < arr.length; i++) { // 首次遍歷數(shù)組
for (var j = i + 1; j < arr.length; j++) { // 再次遍歷數(shù)組
if (arr[i] == arr[j]) { // 判斷連個(gè)值是否相等
arr.splice(j, 1); // 相等刪除后者
j--;
}
}
}
return arr
}
console.log(unlink(arr));
- 利用includes
var arr = [1, 1, 8, 8, 12, 12, 15, 15, 16, 16];
function unique(arr) {
if (!Array.isArray(arr)) {
console.log('type error!')
return
}
var array =[];
for(var i = 0; i < arr.length; i++) {
if( !array.includes( arr[i]) ) {//includes 檢測(cè)數(shù)組是否有某個(gè)值
array.push(arr[i]);
}
}
return array
}
console.log(unique(arr))
數(shù)組排序
- sort()
var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return a - b});
// 1,5,10,25,40,100 升序 反之 b-a 降序
類型判斷
基本數(shù)據(jù)類型:Undefined、Null、Boolean、Number、String,Symbol
引用數(shù)據(jù)類型 :Object
let bool = true;
let num = 1;
let str = 'abc';
let und= undefined;
let nul = null;
let arr = [1,2,3,4];
let obj = {name:'xiaoming',age:22};
let fun = function(){console.log('hello')};
let s1 = Symbol();
- typeof判斷
console.log(typeof bool); //boolean
console.log(typeof num);//number
console.log(typeof str);//string
console.log(typeof und);//undefined
console.log(typeof nul);//object
console.log(typeof arr);//object
console.log(typeof obj);//object
console.log(typeof fun);//function
console.log(typeof s1); //symbol
- instanceof判斷
console.log(bool instanceof Boolean);// false
console.log(num instanceof Number);// false
console.log(str instanceof String);// false
console.log(und instanceof Object);// false
console.log(nul instanceof Object);// false
console.log(arr instanceof Array);// true
console.log(obj instanceof Object);// true
console.log(fun instanceof Function);// true
console.log(s1 instanceof Symbol);// false
- constructor判斷
null、undefined沒有construstor方法,因此constructor不能判斷undefined和null。 但是他是不安全的,因?yàn)閏ontructor的指向是可以被改變。
console.log(bool.constructor === Boolean);// true
console.log(num.constructor === Number);// true
console.log(str.constructor === String);// true
console.log(arr.constructor === Array);// true
console.log(obj.constructor === Object);// true
console.log(fun.constructor === Function);// true
console.log(s1.constructor === Symbol);//true
- Object.prototype.toString.call 判斷
console.log(Object.prototype.toString.call(bool));//[object Boolean]
console.log(Object.prototype.toString.call(num));//[object Number]
console.log(Object.prototype.toString.call(str));//[object String]
console.log(Object.prototype.toString.call(und));//[object Undefined]
console.log(Object.prototype.toString.call(nul));//[object Null]
console.log(Object.prototype.toString.call(arr));//[object Array]
console.log(Object.prototype.toString.call(obj));//[object Object]
console.log(Object.prototype.toString.call(fun));//[object Function]
console.log(Object.prototype.toString.call(s1)); //[object Symbol]
vue v-on綁定多個(gè)事件
<div v-on="{mousedown:onInput,mouseup:onFocus,click:onBlur}"></div>
防抖和節(jié)流
-
防抖(debounce)
所謂防抖,就是指觸發(fā)事件后 n 秒后才執(zhí)行函數(shù),如果在 n 秒內(nèi)又觸發(fā)了事件,則會(huì)重新計(jì)算函數(shù)執(zhí)行時(shí)間。
防抖函數(shù)分為非立即執(zhí)行版和立即執(zhí)行版,此處為 非立即執(zhí)行版
function debounce(func, wait) {
let timeout;
return function () {
const context = this;
const args = [...arguments];
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args)
}, wait);
}
}
-
節(jié)流(throttle)
所謂節(jié)流,就是指連續(xù)觸發(fā)事件但是在 n 秒中只執(zhí)行一次函數(shù)。 節(jié)流會(huì)稀釋函數(shù)的執(zhí)行頻率。
一般有兩種方式可以實(shí)現(xiàn),分別是時(shí)間戳版和定時(shí)器版,此處為 定時(shí)器版
function throttle(func, wait) {
let timeout;
return function() {
let context = this;
let args = arguments;
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
前端性能優(yōu)化
- 使用服務(wù)端渲染
- 靜態(tài)資源使用 CDN(前端只需要引入,靜態(tài)資源放在這url下面 然后以CDN 廠商哪里指定這個(gè)URL)
- 使用字體圖標(biāo) iconfont 代替圖片圖標(biāo)
- 善用緩存,不重復(fù)加載相同的資源
- 降低圖片質(zhì)量( webpack打包配置)
- 盡可能利用 CSS3 效果代替圖片
- 使用 webp 格式的圖片
WebP 的優(yōu)勢(shì)體現(xiàn)在它具有更優(yōu)的圖像數(shù)據(jù)壓縮算法,能帶來更小的圖片體積,而且擁有肉眼識(shí)別無差異的圖像質(zhì)量;同時(shí)具備了無損和有損的壓縮模式、Alpha 透明以及動(dòng)畫的特性,在 JPEG 和 PNG 上的轉(zhuǎn)化效果都相當(dāng)優(yōu)秀、穩(wěn)定和統(tǒng)一。
- 使用 requestAnimationFrame 來實(shí)現(xiàn)視覺變化
如果采取 setTimeout 或 setInterval 來實(shí)現(xiàn)動(dòng)畫的話,回調(diào)函數(shù)將在幀中的某個(gè)時(shí)點(diǎn)運(yùn)行,可能剛好在末尾,而這可能經(jīng)常會(huì)使我們丟失幀,導(dǎo)致卡頓。
- 降低 CSS 選擇器的復(fù)雜性
怎樣理解 Vue 的單向數(shù)據(jù)流?
所有的 prop 都使得其父子 prop 之間形成了一個(gè)單向下行綁定:父級(jí) prop 的更新會(huì)向下流動(dòng)到子組件中,但是反過來則不行。
額外的,每次父級(jí)組件發(fā)生更新時(shí),子組件中所有的 prop 都將會(huì)刷新為最新的值。這意味著你不應(yīng)該在一個(gè)子組件內(nèi)部改變 prop。如果你這樣做了,Vue 會(huì)在瀏覽器的控制臺(tái)中發(fā)出警告。子組件想修改時(shí),只能通過 $emit 派發(fā)一個(gè)自定義事件,父組件接收到后,由父組件修改。
或者通過 .sync 去實(shí)現(xiàn)雙向通信
// 子組件
props:{
msg:String
}
...
computed:{
msgData:{
get(){
return this.msg
},
set(val){
this.$emit('update:msg',val)
}
}
}
//父組件
<children :msg.sync="data" />
父組件可以監(jiān)聽到子組件的生命周期嗎?
可以
// Parent.vue
<Child @mounted="doSomething"/>
// Child.vue
mounted() {
this.$emit("mounted");
}
組件中 data 為什么是一個(gè)函數(shù)?
因?yàn)榻M件是用來復(fù)用的,且 JS 里對(duì)象是引用關(guān)系,如果組件中 data 是一個(gè)對(duì)象,那么這樣作用域沒有隔離,子組件中的 data 屬性值會(huì)相互影響,如果組件中 data 選項(xiàng)是一個(gè)函數(shù),那么每個(gè)實(shí)例可以維護(hù)一份被返回對(duì)象的獨(dú)立的拷貝,組件實(shí)例之間的 data 屬性值不會(huì)互相影響;而 new Vue 的實(shí)例,是不會(huì)被復(fù)用的,因此不存在引用對(duì)象的問題。
Vue 組件間通信有哪幾種方式?
props / $emit 適用 父子組件通信
ref 與 $parent / $children 適用 父子組件通信
EventBus ($emit / $on) 適用于 父子、隔代、兄弟組件通信
Vue 是如何實(shí)現(xiàn)數(shù)據(jù)雙向綁定的?
1.實(shí)現(xiàn)一個(gè)監(jiān)聽器 Observer:對(duì)數(shù)據(jù)對(duì)象進(jìn)行遍歷,包括子屬性對(duì)象的屬性,利用 Object.defineProperty() 對(duì)屬性都加上 setter 和 getter。這樣的話,給這個(gè)對(duì)象的某個(gè)值賦值,就會(huì)觸發(fā) setter,那么就能監(jiān)聽到了數(shù)據(jù)變化。
2.實(shí)現(xiàn)一個(gè)解析器 Compile:解析 Vue 模板指令,將模板中的變量都替換成數(shù)據(jù),然后初始化渲染頁(yè)面視圖,并將每個(gè)指令對(duì)應(yīng)的節(jié)點(diǎn)綁定更新函數(shù),添加監(jiān)聽數(shù)據(jù)的訂閱者,一旦數(shù)據(jù)有變動(dòng),收到通知,調(diào)用更新函數(shù)進(jìn)行數(shù)據(jù)更新。
3.實(shí)現(xiàn)一個(gè)訂閱者 Watcher:Watcher 訂閱者是 Observer 和 Compile 之間通信的橋梁 ,主要的任務(wù)是訂閱 Observer 中的屬性值變化的消息,當(dāng)收到屬性值變化的消息時(shí),觸發(fā)解析器 Compile 中對(duì)應(yīng)的更新函數(shù)。
4.實(shí)現(xiàn)一個(gè)訂閱器 Dep:訂閱器采用 發(fā)布-訂閱 設(shè)計(jì)模式,用來收集訂閱者 Watcher,對(duì)監(jiān)聽器 Observer 和 訂閱者 Watcher 進(jìn)行統(tǒng)一管理。

虛擬 DOM 實(shí)現(xiàn)原理?
虛擬dom的比較,就是找出新節(jié)點(diǎn)(vnode)和舊節(jié)點(diǎn)(oldVnode)之間的差異,然后對(duì)差異進(jìn)行打補(bǔ)丁(patch)
虛擬 DOM 的實(shí)現(xiàn)原理主要包括以下 3 部分:
- 用 JavaScript 對(duì)象模擬真實(shí) DOM 樹,對(duì)真實(shí) DOM 進(jìn)行抽象;
- diff 算法 — 比較兩棵虛擬 DOM 樹的差異;
- pach 算法 — 將兩個(gè)虛擬 DOM 對(duì)象的差異應(yīng)用到真正的 DOM 樹。
Vue 中的 key 有什么作用?
key 是為 Vue 中 vnode 的唯一標(biāo)記,通過這個(gè) key,我們的 diff 操作可以更準(zhǔn)確、更快速。
你有對(duì) Vue 項(xiàng)目進(jìn)行哪些優(yōu)化?
- 代碼層面的優(yōu)化
v-if 和 v-show 區(qū)分使用場(chǎng)景
computed 和 watch 區(qū)分使用場(chǎng)景
v-for 遍歷必須為 item 添加 key,且避免同時(shí)使用 v-if
長(zhǎng)列表性能優(yōu)化
事件的銷毀
圖片資源懶加載
路由懶加載
第三方插件的按需引入
優(yōu)化無限列表性能
服務(wù)端渲染 SSR or 預(yù)渲染
- Webpack 層面的優(yōu)化
Webpack 對(duì)圖片進(jìn)行壓縮
減少 ES6 轉(zhuǎn)為 ES5 的冗余代碼
提取公共代碼
模板預(yù)編譯
提取組件的 CSS
優(yōu)化 SourceMap
構(gòu)建結(jié)果輸出分析
Vue 項(xiàng)目的編譯優(yōu)化
vue有哪些優(yōu)勢(shì)
- 輕量級(jí)框架
- 簡(jiǎn)單易學(xué)
- 雙向數(shù)據(jù)綁定
- 組件化開發(fā)
- 視圖,數(shù)據(jù),結(jié)構(gòu)分離
- 虛擬DOM
- 提供了豐富的
api供開發(fā)者使用(computed,watch,$set,#parent,生命周期鉤子,mixin等)
為什么要用vuex而不直接定義全局變量
- 方便集中管理
- 不會(huì)造成命名污染
- 提供統(tǒng)一的方法修改數(shù)據(jù)