前端面試中讓你困惑的閉包、原型、原型鏈到底是什麼?

       前段時間我朋友從上家公司離職,上週開始了前端面試(如今已經上班了),一天我下班回到出租房時,他問我原型鏈是什麼?一時半會我居然也不知道從何提及可以讓他很清楚的明白,又突然想起以前我一個朋友也問過我閉包的問題,所以在這裏記錄解惑一下,下面我會以面試官和應聘者的口吻進行介紹理解......html

 

一.閉包前端

面試官什麼是閉包?閉包你瞭解嗎?面試

應聘者閉包就是可以讀取其餘函數內部變量的函數。數組

面試官通俗一點呢?閉包

應聘者通俗的講就是函數a內部函數b,被函數a外部的一個變量引用的時候,就建立了一個閉包。函數

面試官是這樣,沒錯,那你知道什麼狀況下會用到閉包嗎?this

應聘者:最多見的是函數封裝的時候,再就是在使用定時器的時候,會常常用到...spa

面試官那你簡單寫一個閉包吧prototype

應聘者code

function a(){
     var i=0;
     function b(){
         alert(++i);
     }
     return b;
}

var c = a();
c();//外部的變量

面試官你這個寫法是正確的,那我衍生一下,你回答一下依次會彈出什麼:

function a(){
     var i=0;
     function b(){
i++; alert(
i); } return b; } var c = a(); c();// c();// c();//

應聘者應該是會依次彈出1,2,3

面試官沒錯,你回答的很對,你知道其中的原理嗎?可否解釋一下

應聘者好的,i函數a中的一個變量,它的值在函數b中被改變,函數b每執行一次,i的值就在原來的基礎上累加 1 。所以,函數a中的i變量會一直保存在內存中。

                當咱們須要在模塊中定義一些變量,並但願這些變量一直保存在內存中但又不會 「污染」 全局的變量時,就能夠用閉包來定義這個模塊。

面試官很是棒,你說的這是它的一個用處,你能說一下閉包的用處有哪些嗎?

應聘者它的最大用處有兩個,一個是它能夠讀取函數內部的變量,另外一個就是讓這些變量的值始終保持在內存中

面試官那我順便再出個問題考考你吧,請看題:

var num = new Array();
for(var i=0; i<4; i++){
    num[i] = f1(i);
}
function f1(n){
     function f2(){
         alert(n);
     }
     return f2;
}
num[2]();
num[1]();
num[0]();
num[3]();

應聘者答案爲2,1,0,3(這個時候你瞭解清楚閉包以後,這個答案應該就是隨口而出),解釋以下:

//建立數組元素
var num = new Array();
for(var i=0; i<4; i++){
    //num[i] = 閉包;//閉包被調用了4次,就會生成4個獨立的函數
    //每一個函數內部有本身能夠訪問的個性化(差別)的信息
    num[i] = f1(i);
}
function f1(n){
     function f2(){
         alert(n);
     }
     return f2;
}
num[2]();  //2
num[1]();  //1
num[0]();  //0
num[3]();  //3

面試官那你知道閉包的優缺點嗎?

應聘者

優勢

        ① 減小全局變量;

        ② 減小傳遞函數的參數量;

        ③ 封裝;

缺點

        ① 使用閉包會佔有內存資源,過多的使用閉包會致使內存溢出等

面試官正好你提到了內存泄漏,說說你的解決方法

應聘者簡單的說就是把那些不須要的變量,可是垃圾回收又收不走的的那些賦值爲null,而後讓垃圾回收走;

面試官看來閉包已經難不倒你了,閉包就到這裏告一段落了,接下來考考你原型和原型鏈。

 

二.原型和原型鏈

面試官你好,接下來考考你原型和原型鏈

應聘者好的,請問

面試官你解釋一下原型的概念吧!

應聘者 每一個對象都會在其內部初始化一個屬性,就是prototype(原型)。

面試官通俗一點呢?

應聘者通俗的說,原型就是一個模板,更準確的說是一個對象模板

面試官那你接着說一下原型鏈是什麼?

應聘者當咱們訪問一個對象的屬性時,若是這個對象內部不存在這個屬性,那麼他就會去prototype裏找這個屬性,這個prototype又會有本身的prototype,因而就這樣一直找下去,也就是咱們平時所說的原型鏈的概念。

面試官你這個說太多了,簡單一點

應聘者就是利用原型讓一個引用類型繼承另外一個引用類型的屬性和方法;

                 舉例說明: Student → Person → Object   ,學生繼承人類,人類繼承對象類

面試官我看你說到了繼承,那你簡單寫一個原型鏈繼承和構造函數繼承的例子

應聘者好,以下

function Animal(name) {
    this.name = name
}

Animal.prototype.getName = function() {
    console.log(this.name)
}

var animal1 = new Animal('Kate')
var animal2 = new Animal('Lucy')

//對象animal1 和 animal2共享方法getName
animal1.getName()
animal2.getName()
//父類:人
function Person () {
   this.head = '腦殼瓜子';
   this.emotion = ['喜', '怒', '哀', '樂']; //人都有喜怒哀樂
}
//子類:學生,繼承了「人」這個類
function Student(studentID) {
    this.studentID = studentID;
    Person.call(this);
}

var stu1 = new Student(1001);
console.log(stu1.emotion); //['喜', '怒', '哀', '樂']

面試官ok,那我出個問題考考你,你告訴我結果,題目以下:

var A=function(){}

A.prototype.n=1

var b=new A()

A.prototype={
     n:2,
     m:3
}

var c=new A()

console.log(b.n,b.m,c.n,c.m)//多少

應聘者答案爲1,undefined,2,3。緣由是b繼承A,因此b.n就爲1,而m在A中找不到,因此爲undefined,以此類推,c繼承的時候A添加了n和m,因此c.n和c.m分別是2和3;

面試官你回答的很棒,你知道null和undefined的區別嗎?

應聘者undefined是一個表示"無"的原始值

     null用來表示還沒有存在的對象,

面試官很正確,再出個問題給你,問題以下:

var F=function(){};

Object.prototype.a=function(){
     console.log('a()')
};

Function.prototype.b=function(){
     console.log('b()')
}

var f=new F();

f.a()//
f.b()//
F.a()//
F.b()//

應聘者答案應該爲a()、報錯找不到b這個函數、a()、b()。(若是你能瞬間回答出這個答案就表明你已經瞭解原型和原型鏈了)

面試官看來原型原型鏈也難不倒你了,那面試就到這裏告一段落了。

 

三.總結

閉包和原型原型鏈的介紹就到這裏介紹了,若是上面有哪些解釋有錯誤麻煩你們指正一下,謝謝了!附加一下我上文提到的朋友http://www.javashuo.com/article/p-xnbqjurb-u.html

相關文章
相關標籤/搜索