記我的第一次面試總結——閉包和原型鏈

廢話先說

最近投了數多簡歷,大都了無音訊,昨天有幸收到了新蛋集團的面試電話,在今天上午進行了電話面試,面試的小哥十分和藹,聲音聽起來很舒服,也特別有耐心,可惜自己回答的並不好,結果就順其自然吧。

但是通過這次面試,我對自己的瞭解加深了不少,一是自己除了前端基礎的知識之外,對於網絡協議及算法方面的知識瞭解太少,二是對於自己知道的知識無法準確描述。

在這先整理下自己這次面試的問題,並打算對自己的不足之處進行鞏固加強,不要再錯過本可以抓住的機會了。

正文開始

問題一:簡單介紹一下閉包

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也就沒有作用了,在實際開發中這種寫法是不正確的。

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