前端面試題(附答案)

pilotage發表於2019-04-09

1、使用至少兩種方法,實現如下佈局(box垂直居中於父元素,寬高不固定)?

第一種:

<style>
.container {
  display: table;
}
.inner {
  display: table-cell;
  vertical-align:middle;
  text-align:center;
}
</style>
<div class="container">
  <div class="inner">
  you own content
  </div>
</div>
複製程式碼

第二種:

<style>
.container {
  position: relative;
}
.inner {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
</style>
<div class="container">
  <div class="inner">
    your own content
  </div>
</div>
複製程式碼

第三種:

<style>
.container{
    text-align: center;
}
.container:before {
    content: '';
    display: inline-block;
    height: 100%;
    vertical-align: middle;
}
.inner {
    display: inline-block;
}
</style>
<div class="container">
    <div class="inner">
        this is a box fixed in center of screen<br>The second line
    </div>
</div>
複製程式碼

2、px、em、rem有什麼區別?

  • px 表示“絕對尺寸”(並非真正的絕對),實際上就是css中定義的畫素(此畫素與裝置的物理畫素有一定的區別,後續詳細說明見文末說明1),利用 px 設定字型大小及元素寬高等比較穩定和精確。
  • em表示相對尺寸,其相對於當前物件內文字的 font-size(如果當前物件內文字的 font-size 計量單位也是em,則當前物件內文字的 font-size 的參考物件為父元素文字 font-size)。
  • rem 也表示相對尺寸,其參考物件為根元素<html>font-size,因此只需要確定這一個 font-size

3、position有幾種取值,每種取值相對於誰來進行定位?

  • absolute :生成絕對定位的元素, 相對於最近一級的 定位不是 static 的父元素來進行定位。
  • fixed (老IE不支援)生成絕對定位的元素,通常相對於瀏覽器視窗或 frame 進行定位。
  • relative 生成相對定位的元素,相對於其在普通流中的位置進行定位。
  • static 預設值。沒有定位,元素出現在正常的流中
  • sticky 生成粘性定位的元素,容器的位置根據正常文件流計算得出

4、JavaScript的資料型別有哪些?

  • 七種資料型別:UndefinedNullBooleanNumberStringSymbolObject

5、用new運算子建立一個例項時,經歷了哪些步驟?

例子?:

function create() {
    // 建立一個空的物件
    let obj = new Object()
    // 獲得建構函式
    let Con = [].shift.call(arguments)
    // 連結到原型
    obj.__proto__ = Con.prototype
    // 繫結 this,執行建構函式
    let result = Con.apply(obj, arguments)
    // 確保 new 出來的是個物件
    return typeof result === 'object' ? result : obj
}
複製程式碼
  1. 建立一個新物件
  2. 將建構函式的作用域賦給新物件(因此this就指向了這個新物件)
  3. 執行建構函式中的程式碼(為這個新物件新增屬性)
  4. 返回新物件

6、下面這段程式碼返回值是什麼?

var scope = 'global scope';
function checkScope() {
    var scope = 'local scope';
    function f() {
        return scope;
    }
    return f;
}
checkScope()(); // local scope
複製程式碼

7、用什麼方法可以獲得物件的類?寫出程式碼

  1. Object.prototype.toString.call(物件)
  2. typeof: typeof 物件 或者 typeof(物件)

8、call()、apply()、bind()方法的作用是什麼?什麼時候會使用到這些方法?他們之間的區別是什麼?

javaScript權威指南上的解釋是: call() 、apply()可以看作是某個物件的方法,通過呼叫方法的形式來間接呼叫函式。bind() 就是將某個函式繫結到某個物件上。

關於call() 和 apply() 在犀牛書上的解釋可能比較生澀難懂,我的理解就是,它們的作用是: 讓函式在某個指定的物件下執行。

var obj = {x: 1}

function foo() {console.log(this.x)}

foo.call(obj) // 列印結果:1
複製程式碼

call() 和apply()的第一個引數相同,就是指定的物件。這個物件就是該函式的執行上下文。

call()和apply()的區別就在於,兩者之間的引數。

call()在第一個引數之後的 後續所有引數就是傳入該函式的值。apply() 只有兩個引數,第一個是物件,第二個是陣列,這個陣列就是該函式的引數。

var obj = {};
 
function foo(a, b, c) {
  console.log(b);
}
 
foo.call(obj, 1, 2, 3) // 列印結果:2;
複製程式碼
var obj = {};
 
function foo(a, b, c) {
  console.log(b);
}
 
foo.apply(obj, [1, 2, 3]) // 列印結果:2;
複製程式碼

bind() 方法和前兩者不同在於: bind() 方法會返回執行上下文被改變的函式而不會立即執行,而前兩者是直接執行該函式。他的引數和call()相同。

這三個方法的作用都是改變函式的執行上下文!

9、利用正規表示式,寫一個字串轉換成駝峰的方法。

function stringToCamelCase(str){
    var reg=/-(\w)/g; //子項()表示子項
    return str.replace(reg,function($0, $1){ 
        // $0代表正則整體,replace()方法中的第二個引數若是回撥函式,那麼這個回撥函式中的引數就是匹配成功後的結果
        // 若回撥函式中有多個引數時,第一個引數代表整個正則匹配結果,第二個引數代表第一個子項
        alert($0); // -b
        alert($1); // b
        return $1.toUpperCase();
    });
}
複製程式碼

10、如下程式碼,控制檯會輸出什麼內容?

const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('success');
    }, 1000);
})

const promise2 = promise1.then(() => {
    throw new Error('error~~~');
});

console.log('promise1', promise1);
console.log('promise2', promise2);

setTimeout(() => {
    console.log('promise1', promise1);
    console.log('promise2', promise2);
}, 2000);
複製程式碼

promise1 Promise {} promise2 Promise {} promise1 Promise {: "success"} Promise {: Error: error~~~at promise1.then (:8:11)}

11、CommonJS、AMD、CMD的區別?

CommonJS

CommonJS 是以在瀏覽器環境之外構建 JavaScript 生態系統為目標而產生的專案,比如在伺服器和桌面環境中,Node.JS遵循CommonJS的規範 CommonJS 規範是為了解決 JavaScript 的作用域問題而定義的模組形式,可以使每個模組它自身的名稱空間中執行。該規範的主要內容是,模組必須通過 module.exports 匯出對外的變數或介面,通過 require() 來匯入其他模組的輸出到當前模組作用域中。

var clock = require('clock');
clock.start();
複製程式碼

CommonJS 是同步載入模組

AMD

基於CommonJS規範的nodeJS出來以後,服務端的模組概念已經形成,很自然地,大家就想要客戶端模組。而且最好兩者能夠相容,一個模組不用修改,在伺服器和瀏覽器都可以執行。但是,由於一個重大的侷限,使得CommonJS規範不適用於瀏覽器環境。如果將上面的程式碼執行在客戶端瀏覽器,就會報錯。

上面的require方法是同步的。這對伺服器端不是一個問題,因為所有的模組都存放在本地硬碟,可以同步載入完成,等待時間就是硬碟的讀取時間。但是,對於瀏覽器,這卻是一個大問題,因為模組都放在伺服器端,等待時間取決於網速的快慢,可能要等很長時間,瀏覽器處於"假死"狀態。

因此,瀏覽器端的模組,不能採用"同步載入",只能採用"非同步載入"。這就是AMD規範誕生的背景。

CommonJS是主要為了JS在後端的表現制定的,他是不適合前端的,AMD出現了,它就主要為前端JS的表現制定規範。

AMDAsynchronous Module Definition的縮寫,意思就是"非同步模組定義"。它採用非同步方式載入模組,模組的載入不影響它後面語句的執行。所有依賴這個模組的語句,都定義在一個回撥函式中,等到載入完成之後,這個回撥函式才會執行。 AMD也採用require()語句載入模組,但是不同於CommonJS,它要求兩個引數:

require([module], callback);

require(['clock'],function(clock){
  clock.start();
});
複製程式碼

requireJs就是AMD規範的實現

CMD

CMD (Common Module Definition), 是seajs推崇的規範,CMD則是依賴就近,用的時候再require。它寫起來是這樣的:

define(function(require, exports, module) {
   var clock = require('clock');
   clock.start();
});
複製程式碼

AMDCMD最大的區別是對依賴模組的執行時機處理不同,而不是載入的時機或者方式不同,二者皆為非同步載入模組。

AMD依賴前置,js可以方便知道依賴模組是誰,立即載入;而CMD就近依賴,需要使用把模組變為字串解析一遍才知道依賴了那些模組

12、MVC、MVP、MVVM的區別?

MVC:

  1. View接受使用者的互動請求
  2. View將請求轉交給Controller
  3. Controller操作Model進行資料更新
  4. 資料更新之後,Model通知View資料變化
  5. View顯示更新之後的資料

MVP:

  1. 各部分之間的通訊, 都是雙向的。
  2. View 與 Model 不發生聯絡, 都通過 Presenter 傳遞。
  3. View 非常薄, 不部署任何業務邏輯, 稱為 被動檢視,Presenter 非常厚, 所有邏輯都部署在那裡。

MVVM:

  1. 各部分之間的通訊, 都是雙向的。
  2. View 與 Model 不發生聯絡, 都通過 ViewModel 傳遞。
  3. View 非常薄, 不部署任何業務邏輯, 稱為 ViewModel 非常厚, 所有邏輯都部署在那裡。

唯一的區別是, 它採用雙向資料繫結,(data-binding) : View 的變動。自動反映在 ViewModel, 反之亦然。 Angular 和 Ember 都採用這種模式

13、簡述v-if和v-show的區別?

v-if 是銷燬刪除節點、並且渲染時不會渲染 v-show是顯示隱藏節點、相當於display:none

相關文章