1、Webpack 和 Gulp 的區別
grunt、gulp 是基於任務運行的工具:它們會自動執行指定的任務,就像流水線,把資源放上去然後通過不同插件進行加工,它們包含活躍的社區,豐富的插件,能方便的打造各種工作流。
webpack 是基於模塊化打包的工具:webpack 把一切都當做模塊,當 webpack 處理程序時,會遞歸地構建一個依賴關係圖,其中包含應用程序需要的每個模塊,然後將所有的模塊打包成一個或者多個 bundle。
2、Webpack中常用的loaders和plugins有哪些
- 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
- 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()
答案:依次打印200
、100
、1000
。
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
本週結束,下週繼續!!!