基礎面試

5、rem 和flex佈局原理javascript

1.rem是根據html的font-size大小來變化,正是基於這個出發,咱們能夠在每個設備下根據設備的寬度設置對應的html字號,從而實現了自適應佈局php

2.採用flex佈局的元素,稱爲flex容器,它的全部子元素自動成爲容器成員,稱爲flex項目。以下圖:
css

容器默認存在2根軸,水平的主軸和垂直的側軸,主軸的開始位置(與邊框的交叉點)叫作main start, 結束位置叫作 main end.
交叉軸的開始位置叫作 cross start,結束位置叫作cross end。項目默認沿主軸排列。單個項目佔據的主軸空間叫作main size,
佔據的交叉軸空間叫作cross size。html

二:容器有以下6個屬性
flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content前端

1. flex-direction該屬性決定主軸的方向(即項目的排列方向)。
它可能有四個值:
row(默認值):主軸爲水平方向,起點在左端。
row-reverse:主軸爲水平方向,起點在右端。
column:主軸爲垂直方向,起點在上沿。
column-reverse:主軸爲垂直方向,起點在下沿。vue

 

6、什麼是原型鏈 閉包js的內存分配機制java

原型鏈:若訪問對象屬性時,先在基本屬性中找,若是自身沒有該屬性,便會沿着_proto_這條鏈往上找這個找的路徑叫原型鏈。node

閉包:就是可以讀取其餘函數內部變量的函數。jquery

因爲在javascript中,只有函數內部的子函數才能讀取局部變量,因此說,閉包能夠簡單理解成「定義在一個函數內部的函數「。因此,在本質上,閉包是將函數內部和函數外部鏈接起來的橋樑。webpack

原型鏈用於實現JS中的實現繼承。(許多語言都支持兩種方式的繼承:接口繼承和實現繼承。接口繼承只繼承方法簽名,而實現繼承則繼承實際的方法。因爲函數沒有簽名,在ECMAScript中只能實現實現繼承。
原型鏈做爲實現繼承的主要方法,其基本思想是利用原型讓一個引用類型繼承另外一個引用繼承的屬性和方法。瞭解一下構造函數、原型和實例的關係:每一個構造函數都是一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。假如咱們讓原型對象等於另外一個類型的實例,那麼此時的原型對象將包含一個指向另外一個原型的指針,相應的另外一個原型中包含着一個指向另外一個構造函數的指針。如此層層遞進,就構成了實例與原型的鏈條。這就是原型鏈的概念。
當函數調用時,需查找和獲取的變量和元素都會經過原型鏈機制一層層的往上搜索在原型對象或繼承來的對象中得到。

當函數被建立,就有了做用域,當被調用時,就有了做用域鏈,當被繼承時就有了原型鏈,當須要獲取做用域鏈或原型鏈上的變量或值時,就有了閉包

JS的內存分配:

javascript中的變量分爲兩種,原始值和引用值。

原始值:指的是原始數據類型的值,好比undefined,null,number,string,boolean類型所表示的值。

引用值:指的是複合數據類型的值,即Object,Function,Array等。

 

原始值和引用值存儲在內存中的位置分別爲棧和堆。

原始值是存儲在棧中的簡單數據段,他們的值直接存儲在變量訪問的位置。

引用值是存儲在堆中的對象。

存儲在棧中的值是一個指針,指向存儲在堆中的實際對象。     

8、前端性能優化思路經驗    

網頁內容

減小http請求次數

減小DNS查詢次數

避免頁面跳轉

緩存Ajax

延遲加載

提早加載

減小DOM元素數量

根據域名劃份內容

減小iframe數量

避免404

 

服務器

使用CDN

添加Expires 或Cache-Control報文頭

Gzip壓縮傳輸文件

配置ETags

儘早flush輸出

使用GET Ajax請求

避免空的圖片src

 

Cookie

減小Cookie大小

頁面內容使用無cookie域名

CSS

將樣式表置頂

避免CSS表達式

用<link>代替@import

避免使用Filters

Javascript

將腳本置底

使用外部Javascirpt和CSS文件

精簡Javascript和CSS

去除重複腳本

減小DOM訪問

使用智能事件處理

 

圖片

優化圖像

優化CSS Sprite

不要在HTML中縮放圖片

使用小且可緩存的favicon.ico

 

9、給一個已知數組去重

第一種是比較常規的方法

思路:

1.構建一個新的數組存放結果

2.for循環中每次從原數組中取出一個元素,用這個元素循環與結果數組對比

3.若結果數組中沒有該元素,則存到結果數組中


Array.prototype.unique1 = function(){
 var res = [this[0]];
 for(var i = 1; i < this.length; i++){
  var repeat = false;
  for(var j = 0; j < res.length; j++){
   if(this[i] == res[j]){
    repeat = true;
       break;
   }
  }
  if(!repeat){
   res.push(this[i]);
  }
 }
 return res;
}
var arr = [1, 'a', 'a', 'b', 'd', 'e', 'e', 1, 0]
alert(arr.unique1());


第二種方法比上面的方法效率要高

思路:

1.先將原數組進行排序

2.檢查原數組中的第i個元素 與 結果數組中的最後一個元素是否相同,由於已經排序,因此重複元素會在相鄰位置

3.若是不相同,則將該元素存入結果數組中

複製代碼代碼以下:


Array.prototype.unique2 = function(){
 this.sort(); //先排序
 var res = [this[0]];
 for(var i = 1; i < this.length; i++){
  if(this[i] !== res[res.length - 1]){
   res.push(this[i]);
  }
 }
 return res;
}
var arr = [1, 'a', 'a', 'b', 'd', 'e', 'e', 1, 0]
alert(arr.unique2());


第二種方法也會有必定的侷限性,由於在去重前進行了排序,因此最後返回的去重結果也是排序後的。若是要求不改變數組的順序去重,那這種方法便不可取了。

第三種方法(推薦使用)

思路:

1.建立一個新的數組存放結果

2.建立一個空對象

3.for循環時,每次取出一個元素與對象進行對比,若是這個元素不重複,則把它存放到結果數組中,同時把這個元素的內容做爲對象的一個屬性,並賦值爲1,存入到第2步創建的對象中。

說明:至於如何對比,就是每次從原數組中取出一個元素,而後到對象中去訪問這個屬性,若是能訪問到值,則說明重複。

複製代碼代碼以下:


Array.prototype.unique3 = function(){
 var res = [];
 var json = {};
 for(var i = 0; i < this.length; i++){
  if(!json[this[i]]){
   res.push(this[i]);
   json[this[i]] = 1;
  }
 }
 return res;
}

var arr = [112,112,34,'你好',112,112,34,'你好','str','str1'];
alert(arr.unique3());

 

let、var、const區別:

  1. const定義的變量能夠修改,不可重複定義,並且必須初始化

2. var定義的變量能夠修改,若是不初始化會輸出undefined,不會報錯。

3. let是塊級做用域,函數內部使用let定義後,對函數外部無影響。

Promise:

Promise是異步編程的一種解決方案,比傳統的解決方案(回調函數和事件)更合理更強大。

所謂Promise,簡單說就是一個容器,裏面保存着某個將來纔會結束的事件 (一般是一個異步操做)的結果。從語法上說,Promise是一個對象,從它能夠獲取異步操做的消息。

Promise對象有如下2個特色: 
    1.對象的狀態不受外界影響。Promise對象表明一個異步操做,有三種狀態:Pending(進行中)Resolved(已完成)Rejected(已失敗)。只有異步操做的結果,能夠決定當前是哪種狀態,任何其餘操做都沒法改變這個狀態。這也是Promise這個名字的由來,它的英語意思就是「承諾」,表示其餘手段沒法改變。 
    2.一旦狀態改變,就不會再變,任什麼時候候均可以獲得這個結果。Promise對象的狀態改變,只有兩種可能:從Pending變爲Resolved;從Pending變爲Rejected。只要這兩種狀況發生,狀態就凝固了,不會再變了,會一直保持這個結果。就算改變已經發生了,你再對Promise對象田靜回調函數,也會當即獲得這個結果。這與事件(Event)徹底不一樣,事件的特色是,若是你錯過了它,再去監聽,是得不到結果的。

有了Promise對象,就能夠把異步操做以同步操做的流程表達出來,避免了層層嵌套的回調函數。此外,Promise對象提供了統一的接口,使得控制異步操做更加容易。

 

跨域:

什麼是跨域?

跨域,指的是瀏覽器不能執行其餘網站的腳本。它是由瀏覽器的同源策略形成的,是瀏覽器施加的安全限制。

所謂同源是指,域名,協議,端口均相同,

瀏覽器執行javascript腳本時,會檢查這個腳本屬於哪一個頁面,若是不是同源頁面,就不會被執行。

解決辦法:

1、JSONP:

使用方式就不贅述了,可是要注意JSONP只支持GET請求,不支持POST請求。

2、代理:

例如www.123.com/index.html須要調用www.456.com/server.php,能夠寫一個接口www.123.com/server.php,由這個接口在後端去調用www.456.com/server.php並拿到返回值,而後再返回給index.html,這就是一個代理的模式。至關於繞過了瀏覽器端,天然就不存在跨域問題。

 

jquery插件無縫滾動實現原理:

1.不少時候使用方法Ul列表去展現。固然這也有一些好處,好比float對齊之類的。固然直接用p或者div也行。

2.瞭解overflow屬性。在溢出狀況下的處理。其實輪播就是在不斷的處理li溢出的狀況。

3 jQuery animate的動畫效果。固然若是不用這個也行。一個setInterval就能搞定它。不過jQuery仍是作了一些封裝。

4 可能還須要一些基礎的理解就是對定位的熟悉。margin和postion的瞭解。

5 以後就是循環輪播了,循環輪播須要對節點進行從新的修改。

   具體而言就是在輪播到最後一張圖片的時候,修改節點,將第一個節點,添加到列表的最後一個位置。以下:

  1. $(this).css({'margin-left':0}).children('li').last().after($(this).children('li').first());  



看一下核心代碼:

html:

  1. <div class="list" id = "sidle">  
  2.     <ul>  
  3.         <li><img src="1.jpg" width="538" height="198" /></li>  
  4.         <li><img src="2.jpg" width="538" height="198" /></li>  
  5.         <li><img src="3.jpg" width="538" height="198" /></li>  
  6.         <li><img src="4.jpg" width="538" height="198" /></li>  
  7.     </ul>  
  8. </div>  


css:

  1. .list{  
  2.     width:538px;  
  3.     height:198px;  
  4.     overflow:hidden;  
  5.     margin:50px auto;  
  6. }  
  7. .list ul{  
  8.     width:2152px;  
  9.     height:198px;  
  10. 10.     margin:0;  
  11. 11.     padding:0;  

12. }  

13. .list ul li{  

  1. 14.     float:left;  
  2. 15.     width:538px;  

16. }  



  1.  (function($){  
  2.     var silde = {  
  3.         init:function(){  
  4.             this.auto();  
  5.         },  
  6.         auto:function(){  
  7.             var _root = this,  
  8.                 $ul = $("#sidle").find("ul"),  
  9.                 $lis = $ul.children("li"),  
  10. 10.                 width = $lis.eq(0).width();  
  11. 11.             setInterval(function(){  
  12. 12.                 $ul.animate({  
  13. 13.                         'margin-left':'-'+ width +'px'  
  14. 14.                     },  
  15. 15.                     'slow',  
  16. 16.                     function(){  
  17. 17.                         //此處保證能循環輪播  
  18. 18.                         //將已經輪播過的節點的第一張圖片添加到末尾的位置  
  19. 19.                         //再將margin-left重置爲0px;  
  20. 20.                         //這樣就能一直的循環下去.  
  21. 21.                         $ul.css({'margin-left':0}).  
  22. 22.                             children('li').  
  23. 23.                             last().  
  24. 24.                             after(  
  25. 25.                                 $ul.children('li').first()  
  26. 26.                             );  
  27. 27.                     });  
  28. 28.                 },2000  
  29. 29.             );  
  30. 30.         }  
  31. 31.     };  
  32. 32.     $(function(){silde.init();})  

33. })(jQuery);  

 

Vuex:

Vuex 是什麼?

Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。Vuex 也集成到 Vue 的官方調試工具 devtools extension,提供了諸如零配置的 time-travel 調試、狀態快照導入導出等高級調試功能。

什麼是「狀態管理模式」?

讓咱們從一個簡單的 Vue 計數應用開始:

 

這個狀態自管理應用包含如下幾個部分:

  • state,驅動應用的數據源;
  • view,以聲明方式將 state 映射到視圖;
  • actions,響應在 view 上的用戶輸入致使的狀態變化。

如下是一個表示「單向數據流」理念的極簡示意:

 

可是,當咱們的應用遇到多個組件共享狀態時,單向數據流的簡潔性很容易被破壞:

  • 多個視圖依賴於同一狀態。
  • 來自不一樣視圖的行爲須要變動同一狀態。

對於問題一,傳參的方法對於多層嵌套的組件將會很是繁瑣,而且對於兄弟組件間的狀態傳遞無能爲力。對於問題二,咱們常常會採用父子組件直接引用或者經過事件來變動和同步狀態的多份拷貝。以上的這些模式很是脆弱,一般會致使沒法維護的代碼。

所以,咱們爲何不把組件的共享狀態抽取出來,以一個全局單例模式管理呢?在這種模式下,咱們的組件樹構成了一個巨大的「視圖」,無論在樹的哪一個位置,任何組件都能獲取狀態或者觸發行爲!

另外,經過定義和隔離狀態管理中的各類概念並強制遵照必定的規則,咱們的代碼將會變得更結構化且易維護。

這就是 Vuex 背後的基本思想,借鑑了 FluxRedux、和 The Elm Architecture。與其餘模式不一樣的是,Vuex 是專門爲 Vue.js 設計的狀態管理庫,以利用 Vue.js 的細粒度數據響應機制來進行高效的狀態更新。

 

什麼狀況下我應該使用 Vuex?

在組件外部管理狀態, 能夠幫助咱們管理共享狀態

中小型單頁應用,一個簡單的 global event bus 就足夠您所需了。

Axios:

axios 是一個基於 Promise 的,爲瀏覽器和 Node.js 設計的 HTTP 客戶端。它儘量簡化封裝了 HTTP 相關的各類操做,在 Web App 中使用很是方便,官方建議使用 axios 進行 HTTP 操做

v-modle實現原理:

 

咱們看上圖中的代碼,有行 $emit的代碼,這行代碼實際上會觸發一個 input事件, 'input'後的參數就是傳遞給v-model綁定的屬性的值,

也就是自定義的組件內部通常包含原生的表單組件(固然非表單的組件也能夠)

而後,給原生控件綁定事件,捕捉到原生組件的值,利用 $emit方法,觸發input方法,組件監聽到 input事件而後把值傳入到myattr中.

這裏有個疑問,爲何是 'input'呢??? 三個字,看文檔!

這個就是 vue對 v-model實現的一個規則: 使用了v-model的組件會

自動監聽 input 事件,並把這個input事件所攜帶的值 傳遞給v-model所綁定的屬性!這樣組件內部的值就給到了父組件了

經過以上講解,咱們總結一下如何利用v-model實現自定義的表單組件:

監聽原生組件的事件,當獲取到原生組件的值後把值經過調用 $emit('input' ,data) 方法去觸發 input事件

 

組件之間怎麼通訊:

1.父組件傳遞數據給子組件

父組件數據如何傳遞給子組件呢?能夠經過props屬性來實現

這樣呢,就實現了父組件向子組件傳遞數據.

2.子組件與父組件通訊

那麼,若是子組件想要改變數據呢?這在vue中是不容許的,由於vue只容許單向數據傳遞,這時候咱們能夠經過觸發事件來通知父組件改變數據,從而達到改變子組件數據的目的.

3.非父子組件通訊

若是2個組件不是父子組件那麼如何通訊呢?這時能夠經過eventHub來實現通訊. 
所謂eventHub就是建立一個事件中心,至關於中轉站,能夠用它來傳遞事件和接收事件.

 

這樣就實現了非父子組件之間的通訊了.原理就是把Hub看成一箇中轉站!

 

你是如何搭建腳手架的:

1、環境搭建
  1. 安裝node.js,從node.js官網下載並安裝node,安裝過程很簡單,一路「下一步」就能夠了(傻瓜式安裝)。安裝完成以後,打開命令行工具(win+r,而後輸入cmd),輸入 node -v,以下圖,若是出現相應的版本號,則說明安裝成功。
    1. 在硬盤上找一個文件夾放工程用的。這裏有兩種方式指定到相關目錄:①cd 目錄路徑 ②若是以安裝git的,在相關目錄右鍵選擇Git Bash Here
    2. 安裝vue腳手架輸入:vue init webpack exprice ,注意這裏的「exprice」 是項目的名稱能夠說是隨便的起名,可是須要主要的是「不能用中文」
2.  安裝淘寶鏡像,打開命令行工具,把這個(npm install -g cnpm --registry= https://registry.npm.taobao.org)安裝完成以後輸入 cnpm -v,以下圖,若是出現相應的版本號,則說明安裝成功。
3.  安裝webpack,打開命令行工具輸入:npm install webpack -g,安裝完成以後輸入 webpack -v,以下圖,若是出現相應的版本號,則說明安裝成功。

4.  安裝vue-cli腳手架構建工具,打開命令行工具輸入:npm install vue-cli -g,安裝完成以後輸入 vue -V(注意這裏是大寫的「V」),以下圖,若是出現相應的版本號,則說明安裝成功。

一.    用vue-cli來構建項目
  1. cd 命令進入建立的工程目錄,首先cd exprice(這裏是本身建工程的名字);
  2. 安裝項目依賴:npm install,由於自動構建過程當中已存在package.json文件,因此這裏直接安裝依賴就行。不要從國內鏡像cnpm安裝(會致使後面缺了不少依賴庫),可是可是若是真的安裝「個把」小時也沒成功那就用:cnpm install 吧
  3. 安裝 vue 路由模塊 vue-router 和網絡請求模塊 vue-resource,輸入:cnpm install vue-router vue-resource –save

建立完成的「exprice」目錄以下:

數面試

 

css部分

  1. position有哪些屬性?
  1. 盒模型中的content如何固定100px?

設置 box-sizing: content-box;

  1. transition/translate/transform 如何實現2s使一個with100px的盒子變成200px?

transition過渡屬性

transition-property  

transition-duration

transition-timing-function: linear/ease

transition-delay

  1. 容器中的不定長寬div如何上下左右居中對齊?

js部分

  1. 原生js如何獲取時間戳?

Date.parse(new Date())

(new Date()).valueOf()

new Date().getTime()

  1. JSON兩個轉換方法記得嗎?

JSON.parse()

JSON.stringify()

  1. 如何用jquery實現列表奇偶行設置自定義顏色?

//偶數行:even

$(「ul li:even」).css(‘backgroundColor’: ‘blue’)

//偶數行:odd

$(「ul li:odd」).css(‘backgroundColor’: ‘green’)

  1. 普通數組與對象數組如何快速排序?數組遍歷方法有哪些?map方法參數有哪些,有什麼做用?

普通數組:經常使用方法sort()爲數組排序,默認會調用toString()方法比較ASCII值升序排序。

對象數組:編寫一個函數參數爲(arr, prop, desc)

  1. 要利用數組sort方法就先初始化一個空數組
  2. 數組長度作全局緩存
  3. 比較屬性prop的鍵值數據類型都須要作判斷
  4. 最後調用數組的sort方法
  5. 最後是數組拷貝到目標數組
  6. 返回該目標數組
  1. 對象排序怎麼作?
    1. 獲取對象屬性集合Object.keys()
    2. Object.keys = Object.keys || function(obj){

var a = [];

//簡潔巧妙,遍歷同時賦值

for(a[a.length] in obj){

       return a;

}

}

注意舊版本的IE,不支持for in遍歷名爲valueOf和toString的屬性名

  1. 遍歷數組和對象分別有哪些方法?效率高的是什麼方法?
    1. 原生for循環、for-in及forEach

1.1   for-in遍歷數組或者對象,i值表明數組每一項的下標值,或者表明對象的每一項的key值。(特別爲遍歷對象設計)

1.2   forEach遍歷數組,三個參數依次是數組元素、索引、數組自己(只能遍歷數組) arr.forEach(value, index, arr)

1.3   能遍歷對象和數組—通用的forEach方法

function forEach(obj){

             var key;

             If( obj instantceof Array ){

                       obj.forEach(function(item){

                                console.log(item);

})

}else{

         for(var key in obj){

         console.log(key, obj[key]);

}

}

}

  1. ES6 for-of方法遍歷類數組集合

//for-of遍歷Map對象, 遍歷字符串」china中國」

let iterable = new Map([[「a」: 1],[「b」: 2],[「c」: 3]]);

for(let [key, value] in iterable){

            console.log(value);

}

  1. Object.key()返回鍵名的集合
  1. jQuery的$.each()

$.each(function(index, value){})遍歷對象和數組

  1. underscore的_.each()

_.each(arrTmp,function(value,index,array){}遍歷對象和數組

  1. javascript原生遍歷方法的建議用法:

用for循環遍歷數組

用for-in遍歷對象

用for-of遍歷類數組對象(ES6)

用Object.keys()獲取對象屬性名的集合

  1. 數組對象嵌套的狀況怎麼排序?
  1. 如何複製一個數組或者一個對象?有更快速便捷的方式嗎?

複製有淺拷貝與深拷貝之分:

1.1 淺拷貝是賦值操做,只是建立了一份原內容的引用

1.2 深拷貝有三種方法

1.2.1 遍歷複製

1.2.2 (最快的複製方法1是concat一個空數組)

arrayObject.concat(arrayX, arrayX…)

(最快的複製方法2是slice(start, end)從頭截到尾)

arr.slice(0)

都不改變原數組且返回被鏈接數組的一份拷貝

1.3   實例:

var objDeepCopy  = function(source){

        var sourceCopy = source instanceof Array ? [] : {};

        for(var item in source){

sourceCopy[item] = typeof source[item] === 'object' ? objDeepCopy(source[item]) : source[item];

        }

        return sourceCopy;

        }

  1. (5,10)之間的隨機數怎麼獲取?

Math.random() * (max - min) + min

Math.floor(Math.random()*(max-min)+min)

Math.round((Math.random()*(max-min)+min)*10)/10

  1. typeof [] 輸出值是什麼?

typeof 有哪些返回值類型:

10.1 boolean (true false)

10.1  number (NaN Infinity)

10.2  string ("123")

10.3  function (Date eval)

10.4  object (window document null [] {})

10.5  undefined (undefined sass)

  1. Js如何判斷值是否爲數字?

1.1    使用isNaN()函數處理,會把」」/[]/null看成0處理,視爲數字

···   11.2 function isNaN(val){

If(val === 「」 || val == null || val == []){
       return false;

} else if(!isNaN(val)){

       return true;

}else{

       return false;

}

}   

  1. 兩個數組如何鏈接在一塊兒?數組與字符串直接轉換方法是什麼?

concat()方法和slice(start,end)截取返回都不改變原數組:快速深拷貝一個數組

數組轉字符串: join(「」)

字符串轉數組:split(「,」)

項目部分

  1. 你在項目中用過哪些技術?
  2. 負責哪些模塊的實現?
  3. 項目中碰到過什麼問題?
  4. 你是怎麼解決的?

電話面試:

flex 應用

柵格佈局

前端緩存技術有用過哪些

什麼是原型鏈?有哪幾種方法實現繼承,多態,封裝?

閉包是什麼?用閉包實現過什麼功能?

Js事件都有哪些?

vue的mvvm實現原理

vue路由實現原理

vue的鉤子函數有哪些?

vue的:和 @分別表明什麼含義?

vue項目的開發目錄還記得嗎?有公司公用的組件怎麼放置的?

先後端分離 打包發佈怎麼作的

 

面試筆試題:

解析url:http://www.qq.com?tag=12 p 5ih&g=&u=50爲json對象

(Window.foo||(window.foo=」bar」)) window.foo的值是什麼?

描述下position的relative和absolute的原理和關係?

Css如何清除浮動?

編寫一個高效的數組去重方法

請簡述Onload和DomContentLoad的區別?

一個類的方法寫在構造函數裏邊與寫在原型中的區別?

簡述下建立Ajax|請求的過程,描述下什麼是跨域?

Vue中v-bind 和 v-on的分別是什麼?

Js的基本數據類型有哪些?

Get和Post有什麼區別?

描述Expires和 Cache-control的功能細節?

簡述xss的原理,如何預防?

Repaint和reflow是什麼?

相關文章
相關標籤/搜索