前端面試&筆試&錯題指南(三)

JavaScript排坑指南(三)

JavaScript老是給人以驚喜,學習不止,進步不斷,今天繼續補充JS容易搞錯的幾道筆試/面試題,爲了秋招繼續努力,歡迎一塊兒爲秋招努力的小夥伴共勉javascript

--------------------------------------總部傳送門-----------------------------------前端

1.VK的秋招前端奇遇記(一)java

2.VK的秋招前端奇遇記(二)git

3.VK的秋招前端奇遇記(三)github

4.VK的秋招前端奇遇記(四)面試

5.番外篇:前端面試&筆試算法 Algorithm算法

」老生常錯「的this與做用域相關

Q1. 下面程序的輸出結果是?

var length = 10;
function fn() {
	console.log(this.length);
}

var obj = {
  length: 5,
  method: function(fn) {
    fn();
    arguments[0]();
  }
};

obj.method(fn, 1);
複製代碼

output:數組

10
2
複製代碼

這個我作錯在第二個輸出上,其實對this瞭解後就知道,第一個輸出10應該是很顯然的:雖然在程序執行時,使用了obj.method方法,讓this指向了obj,可是真正的函數執行在函數體內部,也即當fn()執行的時候,this是指向window的,因此第一次執行結果是10app

那麼這裏第二次執行arguments[0]爲何結果是2函數

分析下在method(fn,1)執行時,經歷了什麼: 首先兩個參數fn1會被放入arguments中,在arguments中第一個參數就是咱們傳入的函數;接下來fn執行,此時this沒有綁定所以指向window,輸出10。 然而到了arguments[0]()這一句,至關於把arguments[0]中的第一個參數拿來執行, 效果以下:

arguments[0]()  //執行,等同於下面的
arguments.0() //固然這句話是不合法的,可是這樣咱們能夠更清楚知道,this是指向arguments實例自己
複製代碼

arguments.length就是它自己的長度(arguments是一個類數組,具備length屬性),所以輸出2


Q2. try..catch程序的輸出結果

(function () {
    try {
        throw new Error();
    } catch (x) {
        var x = 1, y = 2;
        console.log(x);
    }
    console.log(x);
    console.log(y);
})();
複製代碼

輸出結果:

1
undefined
2
複製代碼

咱們都知道var是在預編譯階段會有一個變量提高,這種類型很容易解決,可是當遇到在catch(x)中與已有變量重名的狀況,必定要區分二者之間的關係。

用變量提高的方法,把程序重寫並分析以下:

(function () {
    var x,y;  // 外部變量提高
    try {
        throw new Error();
    } catch (x/* 內部的x */) {
		x = 1; //內部的x,和上面聲明的x不是一回事!!
         y = 2; //內部沒有聲明,做用域鏈向上找,外面的y
        console.log(x); //固然是1
    }
    console.log(x);  //只聲明,未賦值,undefined
    console.log(y);  //就是2了
})();
複製代碼

這樣子就很清晰,以後注意預編譯的過程,把變量和函數定義進行提高後,進行分析,會清楚不少


Q3. 下面程序的輸出

var x = 21;
var girl = function () {
    console.log(x);
    var x = 20;
};
girl ();
複製代碼

輸出:

undefined
複製代碼

說實話,這個題目我沒作錯,我沒作錯,我沒作錯!

由於和Q2同樣,並且尚未Q2難,一句話解釋就是: 函數內部變量提高。 至關於

var x = 21;
var girl = function() {
    var x;
    console.log(x); // undefined
    x = 20;
}
}
複製代碼

那些詭異的邊角知識

Q1. 運算符考點: 下面程序輸出是什麼?

console.log(1 < 2 < 3);
console.log(3 > 2 > 1);
複製代碼

輸出:

true
flase
複製代碼

第一個輸出結果是好理解的,主要看下第二個爲何是false

核心在於js怎麼去解析<>運算符。 在JS中,這種運算符是從左向右運算的,因此3>2>1就被轉換成了true>1,而true的值是1,接着比較1>1就返回false了。


Q2. typeof,下面輸出結果是什麼

console.log(typeof typeof 1);
複製代碼

答案是string

會輸出string,這個題目不單單是typeof的考察,也是對js運算的一個考察。 在js中通常有兩種操做

  • 賦值操做,例如a = b 2>3之類的,上面的題目提到過,是從左向右的順序
  • 取值操做, js問內存:有沒有見過這個傢伙?,好比console.log(a) typeof a 都屬於這個類型,是從右向左的

所以,這個題就被分解爲typeof 1返回"number",注意是一個字符串。 接下來typeof "number",返回string


Q3. typeof undefined == typeof NULL輸出結果是什麼

首先搞清楚兩點:

  • typeof undefined 輸出是undefined
  • typeof null輸出是object

可是,另外一方面,由於js對大小寫敏感,nullNULL,因此``typeof NULL返回undefined`

結果是: true

Q4. 遞歸設計。 實現一個函數,給該函數一個DOM節點,函數訪問其全部子元素(全部子元素,不單單是直接子元素),每次訪問子元素的時候,併爲其傳一個callback。

訪問一個DOM tree,是一個經典的深度優先搜索的算法

function Traverse(DOM,callback) {
    callback(DOM);
    var list = DOM.children;
    Array.prototype.forEach.apply(list,(item)=>{
        Traverse(item,callback); //遞歸
    })
}
複製代碼
相關文章
相關標籤/搜索