廢話先說
最近投了數多簡歷,大都了無音訊,昨天有幸收到了新蛋集團的面試電話,在今天上午進行了電話面試,面試的小哥十分和藹,聲音聽起來很舒服,也特別有耐心,可惜自己回答的並不好,結果就順其自然吧。
但是通過這次面試,我對自己的瞭解加深了不少,一是自己除了前端基礎的知識之外,對於網絡協議及算法方面的知識瞭解太少,二是對於自己知道的知識無法準確描述。
在這先整理下自己這次面試的問題,並打算對自己的不足之處進行鞏固加強,不要再錯過本可以抓住的機會了。
正文開始
問題一:簡單介紹一下閉包
1.概念:閉包就是有權訪另一個函數作用域中變量的函數。 如:
function a(){
var m=3 ;
function b(){
console.log(m);
console.log('string');
};
return b;
}
var result=a();
result(); //3 'string'
上面的函數a和b就構成了一個閉包。在全局中執行函數b中可以引用a中的變量m。
2.特性:
- 函數嵌套函數;
- 函數內部可以引用函數外部的參數和變量;
- 函數變量和參數不會被垃圾回收機制回收;
3.優缺點:
優點
- 希望一個變量長期駐紮在內存中
- 避免全局變量的污染
- 私有成員的存在
缺點
- 常駐內存,增大內存使用量,使用不當回造成內存泄漏;
4.自執行函數的好處
- 隔離作用域,避免全局作用域污染
- 模擬塊級作用域
問題二:判斷下面函數是不是閉包,有什麼問題嗎?
function a(){
var m=3;
function b(){
console.log(m);
};
function c(){
console.log('string');
};
return b;
}
var result=a();
result();
它是一個閉包,但是閉包是b而不是c,因爲只是返回了b.
問題三:描述一下原型鏈
1.原型:
每個函數都會默認有一個prototype屬性,它是一個指針,指向此函數的原型對象。而構造函數作爲一個函數,同樣擁有自己的原型對象,而通過構造函數生成的對象實例中,擁有一個_proto_ 屬性,它指向構造函數的原型對象,我們把構造函數的原型對象稱爲對象實例的原型。
如圖:person就是構造函數,而Person prototype原型對象,也是對象實例person1的原型,此實例會繼承所有存在它原型中的所有屬性及方法。
原型鏈
既然每個實例對象都有一個原型,而每個構造函數也都能創建實例,那假如我們將構造函數 f1 的原型屬性指向構造函數f2的實例對象,那麼構造函數f1的實例對象就能訪問f2的原型屬性,依次類推,我們還可以把構造函數f3的原型屬性指向f2的隊實例對象,那麼f3的實例對象同樣可以訪問到f1的原型,這樣,就構成了一條原型鏈。
如圖:從上到下依次講解,首先,原型鏈的頂端是Object prototype
,它的_proto_ 屬性爲 ,接下來看構造函數SuperType
,它的prototype屬性指向的是原型對象SuperType prototype
,這個原型對象其實是Object的一個實例對象,因爲它的_proto_ 屬性指向Object prototype
,因此,SuperType
的實例屬性可以訪問Object prototype
中的屬性與方法。
同理,我們通過SubType.prototype=new SuperType()
,可以將subType的原型對象指向爲SuperType的一個實例對象,這樣SubType 的實例對象instance通過原型鏈可以訪問到上面三個原型中的合法屬性與方法。
問題四:關於setTimeout()
首先關於setTimeout()我的理解爲:
JavaScript引擎是單線程運行的,瀏覽器無論在什麼時候都只且只有一個線程在運行JavaScript程序。
意思就是隻要是setTimeout中的代碼,執行時間總是要等到其他線程結束後才執行。
題目:
setTimeout(console.log('a'),0)
console.log('c');
的輸出順序;
我答的是先輸出c後輸出a,時候在瀏覽器裏運行發現並不是按照我想的那樣,結果是按順序輸出的。後來又試了其他情況才發現自己以前的理解有偏差。
setTimeout(a,0);
console.log('b');
function a(){
console.log('a')
}
//此時輸出順序爲 b, a;
setTimeout(a(),0);
console.log('b');
function a(){
console.log('a')
};
//此時輸出順序爲 a,b;
這樣下來就發現題目中的寫法其實並沒有用到setTiemout()的知識,當程序運行到它時他會立刻給出結果而不需要等待。另外,這樣一來setTimeout也就沒有作用了,在實際開發中這種寫法是不正確的。