前端面試的難題和怪題
前端面試特輯包含前端面試概念收集器,前端面試的經典題,前端面試的難題和怪題。
函數
var f = function g(){n return 23;n}ntypeof g()n
答案 Error, 函數表達式中後方的函數聲明g並不會被定義。
作用域
var a,b;n(function(){n alert(a);n alert(b);n var a = b = 3;n alert(a);n alert(b);n})();n alert(a);n alert(b);n
答案 undefined,undefined,3,3,undefined, 3。var a = b = 3;可以被分為var a =3; b=3; b會尋找全局變數進行賦值。
var out = 25,n inner = {n out: 20,n func: function () {n var out = 30;n return this.out;n }n };nconsole.log((inner.func, inner.func)());nconsole.log(inner.func());nconsole.log((inner.func)());nconsole.log((inner.func = inner.func)());n
答案 25,20,20,25,因為(inner.func, inner.func)是進行逗號運算符,逗號運算符就是運算前一段表達式,且返回後一段表達式結果,唯一個函數指向windows。第二和第三個console.log的作用域都是inner,也就是他們執行的其實是inner.func()。考查的是一個等號運算inner.func = inner.func其實返回的是運算的結果,即函數inner.func,與第一問相同。
至於箭頭函數,給你們做為思考題吧。
var out = 25,n inner = {n out: 20,n func: () => {n var out = 30;n return this.out;n }n };nconsole.log((inner.func, inner.func)());nconsole.log(inner.func());nconsole.log((inner.func)());nconsole.log((inner.func = inner.func)());n
javascript的delete
(function(x){n delete(x);n alert(x);n})(1+5);n
答案 6,變數卻不能刪除,函數也不能刪除。形式參數不能被刪除。詳情參考《Javascript高級編程》
IIFE
var a = 10;nfunction f1(){n console.log(a);n}nf1();nn(function(){n var a = 20;n f1();n}());nn(function(f2){n var a = 30;n f2();n}(f1));n
答案 10 10 10,調用的方法在指向的是全局變數。本題迷惑性極強。
var test = (function(a){n this.a = a;n return function(b){n return this.a + b;n }n}(function(a,b){n return a;n}(3,2)));nconsole.log(test(1));n
答案 4,首先立即執行函數把function(a,b){return a;}(3,2)返回值3傳到a的位置。立即執行函數又被賦予到test中。test調用的參數傳到b的位置。所以結果為3+1。
下面題目來自Excuse me?這個前端面試在搞事!
for (var i = 0; i < 5; i++) {n setTimeout((function(i) {n console.log(i);n })(i), i * 1000);n}n
答案 0 1 2 3 4,立即執行函數在內部。無返回值,所以函數變成了setTimeout(undefined,i*1000),即沒有東西是延時執行。立即執行了函數內部的console.log(i),所以立即返回0 1 2 3 4。
引用類型
function a(array){n var result = [];n for(var i=0;i < array.length;i++){n result[i] = function(){n return array[I];n }n }n return result;n}nnvar b = a([10,20,30,40,50]);nconsole.log(b[0]());n
答案 undefined,var變數提升,i為5,方法為對象。每個i都是5。array[5]超出範圍,所以答案為undefined。
setTimeout
(function(){n console.log(1);n setTimeout(function(){console.log(2)},1000);n setTimeout(function(){console.log(3)},0);n console.log(4);n })();n
答案 1 4 3 2,setTimeout即使為0ms,也會延時至最後。
下面題目來自Excuse me?這個前端面試在搞事!
setTimeout(function() {n console.log(1)n}, 0);nnew Promise(function executor(resolve) {n console.log(2);n for( var i=0 ; i<10000 ; i++ ) {n i == 9999 && resolve();n }n console.log(3);n}).then(function() {n console.log(4);n});nconsole.log(5);n
答案 2 3 5 4 1,如上面所說,setTimeout延時即使為0,也會在最後執行。先執行Promise內的2和3,then延時執行。先輸出5。下一個tick執行4,最後是setTimeout。
add(2)(3)(4)的執行結果為9,寫出函數體。
利用柯里化,函數體可以這麼寫。
function add(a){n return function(b){n return function(c){n return a+b+c;n }n }n}n
當然,面試官會問你,如果不僅僅只有3個參數的情況。
function add(x) {n var sum = x;n var tmp = function (y) {n sum = sum + y;n return tmp;n };n tmp.toString = function () {n return sum;n };n return tmp;n}n
轉載,請表明出處。總目錄前端經驗收集器
歡迎關注我的微信公眾號:brandonxiang
推薦閱讀:
※前端 ,後端 關於數據交互的問題?
※v-on 綁定事件時,函數名加括弧和不加括弧有什麼區別?
※React新引擎React Fiber究竟要解決什麼問題?