自己寫的面試題,自己想的答案

守候i發表於2018-03-28

大家都知道‘不忘初心,方得始終’,但多少人知道‘初心易得,始終難守’。時代在變化,技術在發展,基礎沒變。學習新技術的時候,不應把基礎落下。

1.前言

因為機緣巧合,讓當了無數次面試者的我,當上了面試官,也和幾個面試者交流過。既然要應對面試者,我就當然要準備面試題了,好讓我大概知道面試者是什麼水平。這個時候,也該詳解下,自己的寫的那些題目。因為題目是我自己寫的,並不是網上摘的,所以知識點比較基礎,也不全面。如果大家對面試題有什麼建議,歡迎指點。

2.考點-物件導向

需求:定義‘我吃火鍋

程式導向的思想是:動作(我,吃火鍋)

程式碼實現方面:

//程式導向
let eat=function(who,someThing){
    console.log(`${who}${someThing}`);
}
eat('我','火鍋');//我吃火鍋
複製程式碼

使用物件導向的方式改寫一下這個例項。

這道題,只希望有一個物件導向的意思在這裡就行了,我期待的答案是這樣的。

let person={
    name:'守候',
    eat:function(someThing){
        console.log(`${this.name}${someThing}`);
    }
}
person.eat('火鍋');
複製程式碼

更好的方式看下面這篇文章:JavaScript:面試頻繁出現的幾個易錯點。這裡不展開講。

3.考點-預解析

根據以下程式碼,寫出結果

這道題我印象很深刻,因為是我在一年多以前,在Q群看到有人說直自己各種精通的時候,我就出這道題來提問,一抓一個準,至今那些各種精通的人,沒一個回答出來的。即使是面試題,也有人掉坑。

之前釋出一篇文章的時候,有提及過這個面試題,也被人罵過,大概的意思是:現在都什麼年代了,ES都不知道更新多少版本了,誰還這麼寫程式碼?看到這個我並沒有回應,也沒打算和誰對撕。但是我腦子裡想到的第一件事就是:以前,新聞有條微博說70%網友贊成數學退出高考,有人談定回答:數學就是用來淘汰這70%人的。在這裡我想說,雖然開發上這樣寫程式碼肯定會被批鬥,但是面試題,考的不只是開發上遇到的問題,也有考一些基礎知識。這道題就是其中之一。而且,現在我也覺得還有必要知道這個知識,還沒到全民寫 ES6 的時代,拋棄 ES5 的時代。

alert(a)
a();
var a=3;
function a(){
    alert(10)
}   
alert(a)
a=6;
a();  

//------------分割線------------------

alert(a)
a();
var a=3;
var a=function(){
    alert(10)
}   
alert(a)
a=6;
a(); 複製程式碼

這個之前寫文章有寫過,現在賦值貼上下。
考點其實就兩個,第一變數宣告提前,第二函式宣告優先於變數宣告!
下面我簡單分析一下,
第一部分執行結果:
1.函式宣告優先於變數宣告,所以,剛開始,a就是function a(){alert(10)} ,就會看到這個函式。
2.a(),執行函式,就是出現alert(10)
3.執行了var a=3; 所以alert(a)就是顯示3
4.由於a不是一個函式了,所以往下在執行到a()的時候, 報錯。
第二部分執行結果:
1.underfind
2.報錯
在之前說過,預解析是把帶有varfunction關鍵字的事先宣告,但不會賦值。所以一開始是underfind,然後報錯是因為執行到a()的時候,a並不是一個函式。

//函式表示式,和變數宣告同等
var a=function(){
    alert(10)
} 
//函式宣告,優於變數宣告    
function a(){
    alert(10)
} 複製程式碼

4.考點-事件委託

一個簡單的需求,比如想給ul下面的li加上點選事件,點選哪個li,就顯示那個li的innerHTML。這個貌似很簡單!程式碼如下!

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <ul id="ul-test">
            <li>0</li>
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
            <li>6</li>
            <li>7</li>
            <li>8</li>
            <li>9</li>
        </ul>
    </body>
    <script type="text/javascript">
        var oUl=document.getElementById("ul-test");
        var oLi=oUl.getElementsByTagName("li");
        for(var i=0,len=oLi.length;i<len;i++){
            oLi[i].addEventListener("click",function(){
                alert(this.innerHTML)
            })
        }
    </script>
</html>
複製程式碼

問題在於:
1.for迴圈,迴圈的是li,10個li就迴圈10次,繫結10次事件,100個就迴圈了100次,繫結100次事件!
2.如果li不是本來就在頁面上的,是未來元素,是頁面載入了,再通過js動態載入進來了,上面的寫法是無效的,點選li是沒有反應的!

應該怎麼解決以上問題?

在道題的考點就是事件委託,就是把事件綁在ul上面,之後的li就可以隨便新增。程式碼如下

var oUl=document.getElementById("ul-test");
oUl.addEventListener("click",function(ev){
    var ev=ev||window.event;
    var target=ev.target||ev.srcElement;
    //如果點選的最底層是li元素
    if(target.tagName.toLowerCase()==='li'){
        alert(target.innerHTML)
    }
}) 
複製程式碼

但是有些面試者就是從vue的角度回答這個問題--利用v-for進行繫結。雖然我們公司的專案是使用vue,這樣說也沒錯,但是這道題我沒提及到vue,說vue的,反而就是一個扣分項了。

5.考點-DOM操作

比如有一個需求,往ul裡面新增10個li,如下程式碼

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <ul id="ul-test">
            
        </ul>
    </body>
    <script type="text/javascript">
        var oUl=document.getElementById("ul-test");
        for(var i=0;i<10;i++){
            var oLi=document.createElement('li');
            oLi.innerHTML=i;
            oUl.appendChild(oLi);
        }       
    </script>
</html>
複製程式碼

問題:這裡相當於操作了10次DOM,有什麼方案,減少DOM的操作次數?可寫程式碼簡單說明。

這道題,有幾個人還是從vue的角度來解決問題(v-for,data),雖然這樣不能說錯,但是我題目沒提及vue的任何東西。考點就是利用innerHTML或者文件碎片的形式。

程式碼如下

innerHTML

var oUl=document.getElementById("ul-test");
//定義臨時變數
var _html='';
for(var i=0;i<10;i++){
    //儲存臨時變數
    _html+='<li>'+i+'</li>'
}
//新增元素
oUl.innerHTML=_html;
複製程式碼

文件碎片-createDocumentFragment

var oUl=document.getElementById("ul-test"),_frag = document.createDocumentFragment();
for(var i=0;i<10;i++){
    var oLi=document.createElement('li');
    oLi.innerHTML=i;
    //把元素新增進文件碎片
    _frag.appendChild(oLi);
}
//把文件碎片新增進元素
oUl.appendChild(_frag);
複製程式碼

6.考點-物件深拷貝

寫出一個函式,實現對,物件的深拷貝

要求實現一個函式clone。

let obj={
    name:'小明',
    age:24
}
let obj1=clone(obj);
複製程式碼

修改obj1,不會影響到obj的值。

這道題,在obj上面,我故意只寫一層,物件裡面沒有巢狀陣列或物件,就是想看下面試者能不能往深處想一下。結果面試者都踩坑了。但是可以理解,畢竟大家都是針對題目而論。

基本上回答都是類似下面這樣

function clone(object){
    let _obj={}
    for(let key in object){
        _obj[key]=object[key];
    }
    return _obj;
}
let obj1=clone(obj);

//-------------------或者-------------
function clone(obj){
    let _obj=Object.assign({},object);
    return _obj;
}
let obj1=clone(obj);
複製程式碼

這個方案,目的是達到了,但是如果obj裡面的屬性,巢狀著物件或者陣列,這個就有問題了。所以理想的解決方案應該是這個。

function clone(object){
    let _obj=JSON.parse(JSON.stringify(obj))
}  複製程式碼

這種方案,如果需要屬性值是函式或者是undefined,就會被過濾掉。保險的做法是下面這樣。原理也很簡單,就是逐個遍歷,如果檢測到屬性值是時引用型別就用當前屬性進行遍歷。

function clone(obj){    
  if(!obj&& typeof obj!== 'object'){      
    return;    
  }
  var newObj=obj.constructor===Object?{}:[];    
  for(var key in obj){              
    newObj[key] =(obj[key]&&typeof obj[key]==='object')?clone(obj[key]):obj[key];       
  }    
  return newObj; 
}
複製程式碼

7.其它考點

其餘幾道題都是比較籠統的題目,沒有唯一的解決方案,這裡就不統一回答了!

1.如果設計中使用了非標準的字型,你該如何去實現?

圖片,字型圖示代替,如果是比較小的英文字型可以使用css3的@font-face。

2.在開發專案上,知道那些優化的方式,提升效能,減少頁面載入時間,程式碼質量,程式碼可讀性等方面

效能優化-壓縮程式碼,懶載入,預載入,合併請求,小圖片轉換base64編碼,資源按需載入等。
程式碼質量優化-命名有意義,適當的註釋,避免巨大函式,避免物件強耦合,程式碼邏輯清晰等。

3.列舉Es6,常用的一些新特性。

參考資料如下:
ECMAScript 6 入門
30分鐘掌握ES6/ES2015核心內容(上)
30分鐘掌握ES6/ES2015核心內容(下)
例項感受-es6的常用語法和優越性
ES6 Promise 用法講解

4.Div+css排版的時候,從頁面渲染和程式碼可讀性的角度,應該注意些什麼?

標籤語義化,class和id命名有意義並且命名統一規範,css避免深巢狀(3級就得注意),避免@import,!important,和*萬用字元,避免行內樣式,在head引入css等。

參考:
21條CSS高階技巧
css寫作建議和效能優化小結

5.說下自己對模組化開發的理解,以及模組化開發的好處。

提高開發效率,有利團隊協同開發,
避免全域性變數汙染,命名衝突,
方便程式碼的複用維護等。

8.小結

面試題就是這10道,我自己的解決方案也說完了。雖熱我們公司的技術棧用的主要是vue,webpack這一些,我面試交流的時候,也會問相關的問題,但是我在面試題裡面我不出關於vue,webpack這些題目,就問文章這些題目,就是想知道面試者的基礎如何(因為現在的行情,很多人都是注重學習熱門的框架,庫,工具等,卻把基礎落下了)。基礎好的話,框架不難上手,但是基礎不牢,就熟悉兩三的框架和一些構建工具,以後技術轉型可能會有阻力。現在前端的發展很快,技術很雜,但是基礎一直沒變。建議大家在學習新技術的同時,不要忘記鞏固基礎。

最後,如果大家對面試題有什麼解法建議或者建議出什麼題型,歡迎指點。

-------------------------華麗的分割線--------------------
想了解更多,關注關注我的微信公眾號:守候書閣

clipboard.png


相關文章