十道前端面試題第【06】篇

1、Webpack 和 Gulp 的區別

  • grunt、gulp 是基於任務運行的工具:它們會自動執行指定的任務,就像流水線,把資源放上去然後通過不同插件進行加工,它們包含活躍的社區,豐富的插件,能方便的打造各種工作流。

  • webpack 是基於模塊化打包的工具:webpack 把一切都當做模塊,當 webpack 處理程序時,會遞歸地構建一個依賴關係圖,其中包含應用程序需要的每個模塊,然後將所有的模塊打包成一個或者多個 bundle。


2、Webpack中常用的loaders和plugins有哪些

常用 loaders

  • file-loader 把文件輸出到一個文件夾中,在代碼中通過相對 URL 引用輸入的文件
  • url_loader 和 file-loader 類似,能在文件很小的情況下以 base64 的方式將文件內容注入到代碼中
  • source-map-loader 加載額外的 Source Map 文件,方便斷點調試
  • image-loader 加載並壓縮圖片文件
  • babel-loader 將 ES6 轉換爲 ES5
  • css-loader 加載 css,支持模塊化、壓縮、文件導入等特性
  • style-loader 把 css 代碼注入到 JavaScript 中,通過 DOM 操作去加載 css
  • eslint-loader 通過 ESLint 檢查 JavaScript 代碼
  • html-minify-loader 壓縮HTML

常用的 plugins

  • define-plugin 定義環境變量
  • html-webpack-plugin 簡化 html 文件創建
  • uglifyjs-webpack-plugin 通過 UglifyES 壓縮 ES6 代碼
  • webpack-parallel-uglify-plugin 多核壓縮,提高壓縮速度
  • webpack-bundle-analyzer 可視化 webpack 輸出文件的體積
  • mini-css-extract-plugin CSS 提取到單獨的文件中,支持按需加載
  • clean-webpack-plugin 在每次構建前清理 /dist 文件夾


3、手寫 reduce() 方法

Array.prototype._reduce = function(fn, initialValue) {
  var arr = Array.prototype.slice.call(this);
  var res, startIndex;
  res = initialValue ? initialValue : arr[0];
  startIndex = initialValue ? 0 : 1;
  for(var i = startIndex; i < arr.length; i++) {
    res = fn.call(null, res, arr[i], i, this); 
  }
  return res;
}


4、Vue-Loader 的工作原理


5、手動實現 instanceof 和 new

// 實例.__ptoto__ === 類.prototype
function _instanceof(example, classFunc) {
    let proto = Object.getPrototypeOf(example);
    while(true) {
        if(proto == null) return false;
        // 在當前實例對象的原型鏈上,找到了當前類
        if(proto == classFunc.prototype) return true;
        // 沿着原型鏈__ptoto__一層一層向上查
        proto = Object.getPrototypeof(proto); // 等於proto.__ptoto__
    }
}

new 操作符做了這些事:

  • 創建一個全新的對象
  • 這個對象的 __proto__ 要指向構造函數的原型 prototype
  • 執行構造函數,使用 call/apply 改變 this 的指向
  • 返回值爲object類型則作爲new方法的返回值返回,否則返回上述全新對象。
function _new(fn, ...args) {
    let instance = Object.create(fn.prototype);
    let res = fn.apply(instance, args); // 改變this指向

    // 確保返回的是一個對象(萬一fn不是構造函數)
    return typeof res === 'object' ? res: instance;
}


6、Webpack熱更新的工作原理


7、手寫 Promise

class MyPromise {
  constructor(fn) {
    this.resolvedCallbacks = [];
    this.rejectedCallbacks = [];    
    this.state = 'PENDING';
    this.value = '';    
    fn(this.resolve.bind(this), this.reject.bind(this));    
  }
  
  resolve(value) {
    if (this.state === 'PENDING') {
      this.state = 'RESOLVED';
      this.value = value;      
      this.resolvedCallbacks.map(cb => cb(value));   
    }
  }
  
  reject(value) {
    if (this.state === 'PENDING') {
      this.state = 'REJECTED';
      this.value = value;      
      this.rejectedCallbacks.map(cb => cb(value));
    }
  }
  
  then(onFulfilled, onRejected) {
    if (this.state === 'PENDING') {
      this.resolvedCallbacks.push(onFulfilled);
      this.rejectedCallbacks.push(onRejected);      
    }    
    if (this.state === 'RESOLVED') onFulfilled(this.value);    
    if (this.state === 'REJECTED') onRejected(this.value);
  }
}


8、解釋下述代碼的運行機理

function bar() {
    console.log(a)
}

function foo() {
    var a = 100
    var b = 1000
    bar()
    function fn() {
        console.log(a)
        console.log(b)
    }
    fn()
}
var a = 200
var b = 2000

foo()

答案:依次打印2001001000


9、手寫瀏覽器嗅探方法

// Browser environment sniffing
var inBrowser = typeof window !== 'undefined';
var inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform;
var weexPlatform = inWeex && WXEnvironment.platform.toLowerCase();
var UA = inBrowser && window.navigator.userAgent.toLowerCase();
var isIE = UA && /msie|trident/.test(UA);
var isIE9 = UA && UA.indexOf('msie 9.0') > 0;
var isEdge = UA && UA.indexOf('edge/') > 0;
var isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android');
var isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios');
var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;
var isPhantomJS = UA && /phantomjs/.test(UA);
var isFF = UA && UA.match(/firefox\/(\d+)/);


10、給一個無序的數組,這個數組中包含 N 連續數字中的 N-1,已知上下邊界,要求找到這個數組缺失的數字。

function findMissingNumber(arr) {
  var sum_of_integers = 0;
  var min = arr[0]
  var max = arr[0]
  for (var i = 0; i < arr.length; i++) {
    sum_of_integers += arr[i];
    min = Math.min(min, arr[i])
    max = Math.max(max, arr[i])
  }
  upper_limit_sum = (max * (max + 1)) / 2;
  lower_limit_sum = (min * (min - 1)) / 2;
  theoretical_sum = upper_limit_sum - lower_limit_sum;
  return (theoretical_sum - sum_of_integers)
}

// 測試
var integers = [23,26,24,22,28,25];
var miss = findMissingNumber(integers);
console.log('miss', miss)  // 27


本週結束,下週繼續!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章