面試知識點突擊

摘錄各大語錄,合集,非原創,連接較多後續添加。javascript

js 題庫

原型鏈

原理

  • 原型prototype:對象,函數都有。css

  • 原型指針_proto_:屬性,對象都有。html

  • 對象的_proto_指向構造函數的原型前端

obj._proto_ = Object.prototype
複製代碼
  • A.prototype.constructer = A

new過程

var a = new B()
等同於
var a ={}
a._prototype_= B.prototype
B.call(a)
複製代碼

類型

  • number,boolean,null,undefined,string,object(es6 symbol)
  • typeof =>輸出類型:object,string,number,boolean,function,undefined
  • instanceof =>輸出true or false 。
    • a instanceof b // a對象的原型鏈上是否存在b.prototype.constructor,一個對象在其原型鏈中是否存在一個構造函數的 prototype 屬性
var arr = []
arr instanceof Array //true
typeof arr //object
null instanceof Object //false
typeof null //object
undefined instanceof Object //false
typeof undefined //undefined
function a (){}
a instanceof Object // true
typeof a //function
typeof NaN //number
複製代碼

繼承

原型

// 定義一個動物類
function Animal (name) {
  // 屬性
  this.name = name || 'Animal';
  // 實例方法
  this.sleep = function(){
    console.log(this.name + '正在睡覺!');
  }
}
// 原型方法
Animal.prototype.eat = function(food) {
  console.log(this.name + '正在吃:' + food);
};
複製代碼

原型鏈繼承

function Cat(){ 
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.eat('fish'));
console.log(cat.sleep());
console.log(cat instanceof Animal); //true 
console.log(cat instanceof Cat); //true
複製代碼

特色:vue

很是純粹的繼承關係,實例是子類的實例,也是父類的實例 父類新增原型方法/原型屬性,子類都能訪問到 簡單,易於實現java

缺點:node

若是要新增原型屬性和方法,則必須放在new Animal()這樣的語句以後執行;react

沒法實現多繼承,來自原型對象的全部屬性被全部實例共享;ios

建立子類實例時,沒法向父類構造函數傳參es6

構造繼承

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
複製代碼

特色:

子類實例共享父類引用屬性的問題 建立子類實例時,能夠向父類傳遞參數 能夠實現多繼承(call多個父類對象)

缺點:

實例並非父類的實例,只是子類的實例 只能繼承父類的實例屬性和方法,不能繼承原型屬性/方法 沒法實現函數複用,每一個子類都有父類實例函數的副本,影響性能

組合繼承

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true

複製代碼

特色:

能夠繼承實例屬性/方法,也能夠繼承原型屬性/方法 既是子類的實例,也是父類的實例 不存在引用屬性共享問題 可傳參 函數可複用

缺點:

調用了兩次父類構造函數,生成了兩份實例(子類實例將子類原型上的那份屏蔽了)

寄生組合繼承

function Cat(name){
    Animal.call(this);
    this.name = name||'Tom';
}
(function(){
  // 建立一個沒有實例方法的類
  var Super = function(){};
  Super.prototype = Animal.prototype;
  //將實例做爲子類的原型
  Cat.prototype = new Super();
})();
Cat.prototype.constructor = Cat;
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true
複製代碼

方法

  • push():向數組尾部添加一個或多個元素,並返回添加新元素後的數組長度。注意,該方法會改變原數組
  • pop(): 刪除數組的最後一個元素,並返回該元素。注意,該方法會改變原數組
  • unshift():在數組的第一個位置添加元素,並返回添加新元素後的數組長度。注意,該方法會改變原數組
  • shift():刪除數組的第一個元素,並返回該元素。注意,該方法會改變原數組
  • valueOf():返回數組的自己。
  • indexOf():返回指定元素在數組中出現的位置,若是沒有出現則返回-1。接受第二個參數,表示搜索的開始位置
    • str.indexOf(searchString,startIndex); 返回子字符串第一次出現的位置,從startIndex開始查找,找不到時返回-1
  • toString():返回數組的字符串形式
  • join():以參數做爲分隔符,將全部數組成員組成一個字符串返回。若是不提供參數,默認用逗號分隔。
  • concat():用於多個數組的合併。它將新數組的成員,添加到原數組的尾部,而後返回一個新數組,原數組不變
  • reverse():用於顛倒數組中元素的順序,返回改變後的數組。注意, 該方法將改變原數組
  • slice():用於截取原數組的一部分,返回一個新數組,原數組不變。 slice(start,end)它的第一個參數爲起始位置(從0開始),第二個參數爲終止位置(但該位置的元素自己不包括在內)。若是省略第二個參數,則一直返回到原數組的最後一個成員。
    • str.slice(start,end); 返回值:[start,end)
  • splice():刪除原數組的一部分紅員,並能夠在被刪除的位置添加入新的數組成員,返回值是被刪除的元素。注意,該方法會改變原數組。 splice(start,delNum,addElement1,addElement2,...)第一個參數是刪除的起始位置,第二個參數是被刪除的元素個數。若是後面還有更多的參數,則表示這些就是要被插入數組的新元素。
  • sort():對數組成員進行排序,默認是按照字典順序排序。排序後,原數組將被改變
  • map():對數組的全部成員依次調用一個函數,根據函數結果返回一個新數組。
  • filter():參數是一個函數,全部數組成員依次執行該函數,返回結果爲true的成員組成一個新數組返回。該方法不會改變原數組
  • str.charAt(index); 返回子字符串,index爲字符串下標,index取值範圍[0,str.length-1]
  • str.split(separator,limit); 參數1指定字符串或正則,參照2指定數組的最大長度

promise原理

Promise 對象用於延遲(deferred) 計算和異步(asynchronous )計算.一個Promise對象表明着一個還未完成,但預期未來會完成的操做。Promise 對象是一個返回值的代理,這個返回值在promise對象建立時未必已知。它容許你爲異步操做的成功或失敗指定處理方法。 這使得異步方法能夠像同步方法那樣返回值:異步方法會返回一個包含了原返回值的 promise 對象來替代原返回值。

axios

  • 從瀏覽器生成XMLHttpRequests
  • 從node.js發出http請求
  • 支持Promise API
  • 攔截請求和響應
  • 轉換請求和響應數據
  • 取消請求
  • 自動轉換JSON數據
  • 客戶端支持防範XSRF

安全

談談對前端安全的理解,有什麼,怎麼防範前端安全問題主要有XSS、CSRF攻擊 XSS:跨站腳本攻擊 它容許用戶將惡意代碼植入到提供給其餘用戶使用的頁面中,能夠簡單的理解爲一種javascript代碼注入。

XSS的防護措施: 過濾轉義輸入輸出 避免使用eval、new Function等執行字符串的方法,除非肯定字符串和用戶輸入無關 使用cookie的httpOnly屬性,加上了這個屬性的cookie字段,js是沒法進行讀寫的 使用innerHTML、document.write的時候,若是數據是用戶輸入的,那麼須要對象關鍵字符進行過濾與轉義

CSRF:跨站請求僞造 其實就是網站中的一些提交行爲,被黑客利用,在你訪問黑客的網站的時候進行操做,會被操做到其餘網站上

CSRF防護措施: 檢測http referer是不是同域名 避免登陸的session長時間存儲在客戶端中 關鍵請求使用驗證碼或者token機制 其餘的一些攻擊方法還有HTTP劫持、界面操做劫持

webscoket

垃圾回收

vue

vuex

在main.js引入store,注入,新建一個目錄store,….. export 等,經常使用的場景有:單頁應用中,組件之間的狀態,音樂播放、登陸狀態、加入購物車等等。

Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態。這裏的關鍵在於集中式存儲管理

  • 學院派:Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式;集中存儲和管理應用的全部組件狀態。

  • 理解:以上這4個詞是咱們理解的關鍵。狀態:什麼是狀態,咱們能夠通俗的理解爲數據。Vue只關心視圖層,那麼視圖的狀態如何來肯定?咱們知道是經過數據驅動,這裏的狀態管理能夠簡單理解爲管理數據。集中存儲:Vue只關心視圖,那麼咱們須要一個倉庫(Store)來存儲數據,並且是全部的數據集中存儲,視圖和數據就能夠分析。管理:除了存儲,還能夠管理數據,也就是計算、處理數據。全部組件狀態:所用的組件共用一個倉庫(Store),也就是一個項目只有一個數據源(區分模塊modules)。

  • 總結:Vuex就是在一個項目中,提供惟一的管理數據源的倉庫。

  • 場景一:處理多組件依賴於同一個數據,例若有柱狀圖和條形圖兩個組件都是展現的同一數據;

  • 場景二: 一個組件的行爲——改變數據——影響另外一個組件的視圖,其實也就是公用依賴的數據;

  • Vuex將組件公用數據抽離,在一個公共倉庫管理,使得各個組件容易獲取(getter)數據,也容易設置數據(setter)

生命週期

vue生命週期總共分爲8個階段建立前/後,載入前/後,更新前/後,銷燬前/後。

建立前/後: 在beforeCreated階段,vue實例的掛載元素el尚未。

載入前/後:在beforeMount階段,vue實例的$el和data都初始化了,但仍是掛載以前爲虛擬的dom節點,data.message還未替換。在mounted階段,vue實例掛載完成,data.message成功渲染。

更新前/後:當data變化時,會觸發beforeUpdate和updated方法。

銷燬前/後:在執行destroy方法後,對data的改變不會再觸發周期函數,說明此時vue實例已經解除了事件監聽以及和dom的綁定,可是dom結構依然存在。

雙向數據綁定原理

vue.js 是採用數據劫持結合發佈者-訂閱者模式的方式,經過Object.defineProperty()來劫持各個屬性的setter,getter,在數據變更時發佈消息給訂閱者,觸發相應的監聽回調。 具體步驟:

第一步:須要observe的數據對象進行遞歸遍歷,包括子屬性對象的屬性,都加上 setter和getter。這樣的話,給這個對象的某個值賦值,就會觸發setter,那麼就能監聽到了數據變化

第二步:compile解析模板指令,將模板中的變量替換成數據,而後初始化渲染頁面視圖,並將每一個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變更,收到通知,更新視圖

第三步:Watcher訂閱者是Observer和Compile之間通訊的橋樑,主要作的事情是:

一、在自身實例化時往屬性訂閱器(dep)裏面添加本身

二、自身必須有一個update()方法

三、待屬性變更dep.notice()通知時,能調用自身的update()方法,並觸發Compile中綁定的回調,則功成身退。

第四步:MVVM做爲數據綁定的入口,整合Observer、Compile和Watcher三者,經過Observer來監聽本身的model數據變化,經過Compile來解析編譯模板指令,最終利用Watcher搭起Observer和Compile之間的通訊橋樑,達到數據變化 -> 視圖更新;視圖交互變化(input) -> 數據model變動的雙向綁定效果。

template編譯

簡而言之,就是先轉化成AST樹,再獲得的render函數返回VNode(Vue的虛擬DOM節點) 詳情步驟:

首先,經過compile編譯器把template編譯成AST語法樹(abstract syntax tree 即 源代碼的抽象語法結構的樹狀表現形式),compile是createCompiler的返回值,createCompiler是用以建立編譯器的。另外compile還負責合併option。

而後,AST會通過generate(將AST語法樹轉化成render funtion字符串的過程)獲得render函數,render的返回值是VNode,VNode是Vue的虛擬DOM節點,裏面有(標籤名、子節點、文本等等)

1.獲取el元素。

2.判斷el是否爲body或者html。

3.爲$options編譯render函數。

4.執行以前的mount函數。

關鍵在於第三步,編譯 render 函數上。先獲取 template,即獲取HTML內容,而後執行 compileToFunctions 來編譯,最後將 render 和 staticRenderFns 傳給 vm.$options 對象。

  1. 經過 baseCompile 方法進行編譯;
  2. 經過 createCompilerCreator 中的 compile 方法合併配置參數並返回 baseCompile 方法執行結果;
  3. createCompilerCreator 返回 compile 方法和 compileToFunctions 方法;
  4. compileToFunctions 方法用於將方法字符串生成真實方法。

baseCompile:

  1. parse 將HTML解析爲 AST 元素。
  2. optimize該方法只是作了些標記靜態節點的行爲,目的是爲了在從新渲染時不重複渲染靜態節點,以達到性能優化的目的。
  3. generate 解析成基本的 render 函數

vue-router

單頁面應用(SPA)的核心之一是: 更新視圖而不從新請求頁面。

一、Hash模式: hash(#)是URL 的錨點,表明的是網頁中的一個位置,單單改變#後的部分,瀏覽器只會滾動到相應位置,不會從新加載網頁,也就是說 #是用來指導瀏覽器動做的,對服務器端徹底無用,HTTP請求中也不會不包括#;同時每一次改變#後的部分,都會在瀏覽器的訪問歷史中增長一個記錄,使用」後退」按鈕,就能夠回到上一個位置;

二、History模式: HTML5 History API提供了一種功能,能讓開發人員在不刷新整個頁面的狀況下修改站點的URL,就是利用 history.pushState API 來完成 URL 跳轉而無須從新加載頁面;

  • Vue-Router的兩種模式主要依賴什麼實現的

hash主要依賴location.hash來改動 URL,達到不刷新跳轉的效果.每次 hash 改變都會觸發hashchange事件(來響應路由的變化,好比頁面的更換) history主要利用了 HTML5的 historyAPI 來實現,用pushState和replaceState來操做瀏覽歷史記錄棧

  • 鉤子函數

    • 全局的鉤子

      beforeEach(to,from,next)

      afterEach(to,from,next)

    • 單個路由裏面的鉤子

      beforeEnter(to,from,next)

      beforeLeave (to, from, next)

    • 組件內的鉤子

      beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave

    vue和react

  • 相同點:都支持 ssr,都有 vdom,組件化開發,實現 webComponents 規範,數據驅動等

  • 不一樣點:vue 是雙向數據流(固然爲了實現單數據流方便管理組件狀態,vuex 便出現了),react 是單向數據流。vue 的 vdom 是追蹤每一個組件的依賴關係,不會渲染整個組件樹,react 每當應該狀態被改變時,所有子組件都會 re-render。

VDOM 的必要性?

  • 建立真實DOM的代價高:真實的 DOM 節點 node 實現的屬性不少,而 vnode 僅僅實現一些必要的屬性,相比起來,建立一個 vnode 的成本比較低。 觸發屢次瀏覽器重繪及迴流:使用 vnode ,至關於加了一個緩衝,讓一次數據變更所帶來的全部 node 變化,先在 vnode 中進行修改,而後 diff 以後對全部產生差別的節點集中一次對 DOM tree 進行修改,以減小瀏覽器的重繪及迴流。

vue 爲何採用 vdom?

  • 性能受場景的影響是很是大的,不一樣的場景可能形成不一樣實現方案之間成倍的性能差距,因此依賴細粒度綁定及 Virtual DOM 哪一個的性能更好還真不是一個容易下定論的問題。 Vue 之因此引入了 Virtual DOM,更重要的緣由是爲了解耦 HTML 依賴,這帶來兩個很是重要的好處是:

  • 再也不依賴 HTML 解析器進行模版解析,能夠進行更多的 AOT 工做提升運行時效率:經過模版 AOT 編譯,Vue 的運行時體積能夠進一步壓縮,運行時效率能夠進一步提高; 能夠渲染到 DOM 之外的平臺,實現 SSR、同構渲染這些高級特性,Weex 等框架應用的就是這一特性。

  • 綜上,Virtual DOM 在性能上的收益並非最主要的,更重要的是它使得 Vue 具有了現代框架應有的高級特性。

vue SSR ...

axios

css

未知寬高的元素實現水平垂直居中

.parent{
            width:100%;
            height:400px;
            position:relative;
        }
        .children{
            position:absolute;
            top:50%;
            left:50%;
            transform:translate(-50%,-50%);
        }
複製代碼
.parent{
            width:100%;
            height:400px;
            display:flex;
            align-items:center;
            justify-content:center;
        }
        .children{
            background:red;
        }

複製代碼
.parent{
            display:table;
            width:100%;
            height:400px;
        }
        .children{
            display:table-cell;
            vertical-align:middle;
            text-align:center;
        }

複製代碼

深複製

var json1 = {
    name: 'aaa',
    age: 25,
    data: {
        a: 1,
        b: 2
    }
};

function deepCopy(parent, child) {
    var child = child || {};// 並非直接聲明一個新child爲空{},傳過來的就用傳過來的
    for(var i in parent) {
        if(typeof parent[i] === 'object') {
            child[i] = (parent[i].constructor === Array) ? [] : {};// child.data = {};
            deepCopy(parent[i], child[i]);// {a: 1,b: 2},傳過去的是child.data的空json
        }
        else {
            child[i] = parent[i];// child.data.a ...
        }
    }
    return child;
}

var json2 = deepCopy(json1);
json2.data.a = 3;
console.log(json1.data.a);// json1.data.a不受影響,仍舊是1
console.log(json2.data.a);

複製代碼

算法

都是從小到大

//冒泡
function a (arr){
    for(var i;arr<length;i++){
        for(var j;arr<=length-1;i++){
        if(arr[j]>arr[j+1]){
            var b ;
            b = arr[j];
            arr[j] = arr[j+1];
            arr[j+1] = b;
        }
    }
    }
    return arr;
}
複製代碼
function b (arr){
    if(arr.length<=1){return arr;}
    var left =[];
    var right = [];
    var a = Math.floor(arr.length/2);
    var indexs = arr.splice(a,1)[0];
    for(var i=0;i<length;i++){
        if(indexs > arr[i]){
            left.push(arr[i]);
        }else{
            right.push(arr[i]);
        }
    }
    return b(left).concat([indexs],b(right));
}

複製代碼

優化

  1. 減小http請求(雪碧)
  2. 將樣式表放在頭部
  3. 將腳本放在底部
  4. 針對第三方庫文件使用cdn方式
  5. 慎用deep watch
  6. v-if v-show
  7. keep-alive

打包庫忽略externals

1、加載渲染過程

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

2、子組件更新過程

父beforeUpdate->子beforeUpdate->子updated->父updated

3、父組件更新過程

父beforeUpdate->父updated

4、銷燬過程

父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

相關文章
相關標籤/搜索