摘要:我的意思是大多數稱職的面試官會問你什么是閉包,并且在大多數時候你回答錯誤將失去這份工作。在閉包的范圍內定義的任何公開方法都是特權的。使對象的數據私有化并不是閉包的唯一用途。
文章來源于:https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36
在JavaScript的面試中我通常將這個問題放在第一個或者最后一個問題。坦白地說,如果你沒有深入的學習閉包你的JavaScript不可能有很深的造詣。
你可能JavaScript稍好點兒,但你真的理解如何構建一個好的JavaScript應用嗎?你真的理解什么正在運行,或者應用如何工作的嗎?我對此表示懷疑。不知道這個問題的答案在面試的過程中是一個危險的信號。
你不僅應該知道閉包的工作機制是什么,你還應該知道他為什么發生,并且你應該很輕松的回答幾種常用的閉包用例。
閉包常用在JavaScript對象的數據私有化,事件句柄,回調函數,和在局部應用,柯里化,以及其他功能的變成形式。
我不在乎面試候選人是否知道‘closure’這個詞語或者技術定義。我想要弄明白的是他們是否理解基本的運行機制。如果他們不知道,顯而易見這些面試候選者并沒有大量的實際JavaScript應用開發經驗。
“如果你不能回答這個問題,你就是一個初級開發人員。我不管你工作了幾年。”
這聽起來意味著什么,但實際上并不是。我的意思是大多數稱職的面試官會問你什么是閉包,并且在大多數時候你回答錯誤將失去這份工作。如果你足夠幸運的話,你將得到一個offer,他們將給你一個初級開發人員的工資而不是一個高級的開發人員。
準備好快速跟進:“你能說出兩種常用的閉包嗎?”
什么是閉包?閉包就是一個函數(封閉的)的集合引用的環境(詞法環境)狀態。換句話說,閉包有能力從一個內部函數訪問外部函數的作用域。在JavaScript中,在函數被創建時,每次一個函數被創建閉包也被創建。
用一個閉包,只需在一個函數內部定義一個函數,暴露這個內部的函數,然后返回這個函數,或者把它傳遞給另一個函數。內部的函數將有能力訪問外部函數作用域的變量,即使外部的函數有返回值
使用閉包(實例)刨除其他的,閉包通常用于對象的數據私有化。數據的私有化是幫助我們開發接口的一個重要的屬性,而不是實現(應用的開發的細節實現)。他是一個幫助我們開發一個穩健的軟件的重要概念,因為實現細節往往比接口約定更容易被打破。
“程序之于接口,而不是實現”
設計模式:可重用的面向對象軟件的元素
在javascript中閉包是的主要機制就是被用來實現數據的私有化。當你用筆包進行數據的私有化,所包含的變量僅被包含在在外部的函數作用域內。除了通過對象的特權方法外,你將不能從外部范圍獲取數據。在閉包的范圍內定義的任何公開方法都是特權的。例如:
const getSecret = (secret) => { return { get: () => secret }; }; test("Closure for object privacy.", assert => { const msg = ".get() should have access to the closure."; const expected = 1; const obj = getSecret(1); const actual = obj.get(); try { assert.ok(secret, "This throws an error."); } catch (e) { assert.ok(true, `The secret var is only available to privileged methods.`); } assert.equal(actual, expected, msg); assert.end(); });
在上面的例子中,‘.get()’方法是在‘getsecret()’范圍內定義的,這使得它可以從‘getsecret()’訪問任何變量,并使它 成為一個特權方法。
使對象的數據私有化并不是閉包的唯一用途。它也可以用來創建有狀態的函數,這些函數的返回值可能受他們內部狀態的影響。示例如下:
const secret = msg => () => msg; // Secret - creates closures with secret messages. // https://gist.github.com/ericelliott/f6a87bc41de31562d0f9 // https://jsbin.com/hitusu/edit?html,js,output // secret(msg: String) => getSecret() => msg: String const secret = (msg) => () => msg; test("secret", assert => { const msg = "secret() should return a function that returns the passed secret."; const theSecret = "Closures are easy."; const mySecret = secret(theSecret); const actual = mySecret(); const expected = theSecret; assert.equal(actual, expected, msg); assert.end(); });
在函數式編程中,閉包常常被用在局部應用&柯里化編程,這里需要明白一些定義:
應用程序:應用一個函數的參數已返回一個值得過程
部分應用:函數應用他的部分參數的過程,這個部分被應用的函數稍后被用來獲得返回值。換句話來說,一個函數轉變一個多參數的函數,并利用它的返回一個少參數的函數。
部分應用利用閉包的作用域來處理參數對象,你可以寫一個泛型函數部分的將參數應用于目標函數,下面有一個示例:
partialApply(targetFunction: Function, ...fixedArgs: Any[]) => functionWithFewerParams(...remainingArgs: Any[])
它將接受一個帶有任意數量參數的函數,接下來我們想要部分的應用函數的參數然后返回一個帶有剩余參數的函數。
下面一個例子,一個求兩個數字和的函數:
const add = (a, b) => a + b;
現在你想要一個實現對任意數字都加10的函數,我們命名它為‘add10()’。‘add10(5)’的結果應該是‘15’,我們頂一個‘partialAply()’的函數,如下:
const add10 = partialApply(add, 10); add10(5);
在這個例子中,參數‘10’變成了一個固定的參數被保存在‘add10()’的閉包作用域中。
下面是‘partialApply()’的實現代碼:
// Generic Partial Application Function // https://jsbin.com/biyupu/edit?html,js,output // https://gist.github.com/ericelliott/f0a8fd662111ea2f569e // partialApply(targetFunction: Function, ...fixedArgs: Any[]) => // functionWithFewerParams(...remainingArgs: Any[]) const partialApply = (fn, ...fixedArgs) => { return function (...remainingArgs) { return fn.apply(this, fixedArgs.concat(remainingArgs)); }; }; test("add10", assert => { const msg = "partialApply() should partially apply functions" const add = (a, b) => a + b; const add10 = partialApply(add, 10); const actual = add10(5); const expected = 15; assert.equal(actual, expected, msg); });
正如我們從上面的示例中看到的,這個簡單的返回函數可以訪問‘fixArgs’參數,這個參數是從‘partialApply()’中傳入的。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90388.html
摘要:一言以蔽之,閉包,你就得掌握。當函數記住并訪問所在的詞法作用域,閉包就產生了。所以閉包才會得以實現。從技術上講,這就是閉包。執行后,他的內部作用域并不會消失,函數依然保持有作用域的閉包。 網上總結閉包的文章已經爛大街了,不敢說筆者這篇文章多么多么xxx,只是個人理解總結。各位看官瞅瞅就好,大神還希望多多指正。此篇文章總結與《JavaScript忍者秘籍》 《你不知道的JavaScri...
摘要:第一部分請點擊快速掌握面試基礎知識一閉包閉包由一個函數以及該函數定義是所在的環境組成。當匿名函數執行的時候,的值為。這個問題可以改用后面會介紹方法來解決,通過對每一個匿名函數構建獨立的外部作用域來實現。 譯者按: 總結了大量JavaScript基本知識點,很有用! 原文: The Definitive JavaScript Handbook for your next develope...
摘要:當面試中讓我解釋一下閉包時我懵逼了。這個解釋開始可能有點晦澀,讓我們抽絲剝繭摘下閉包的真面目。此文不詳述作用域有專門的主題闡述,不過作用域是理解閉包原理的基礎。這才是閉包的真正便利之處。閉包使用不當就會很坑。 原文鏈接 為什么深度學習JavaScript? JavaScript如今是最流行的編程語言之一。它運行在瀏覽器、服務器、移動設備、桌面應用,也可能包括冰箱。無需我舉其他再多不相干...
摘要:閉包能用來實現私有化和創建工廠函數等作用。關于閉包的常見面試題是這樣的寫一個函數,循環一個整數數組,延遲秒打印這個數組中每個元素的索引。 文章來源:http://mp.weixin.qq.com/s/vs0... 前言 在公眾號上看到了這篇文章,覺得很有用,有助于理解JS學習中的一些重點難點。決定把它整理下發布出來。該文章主要介紹了JS中的三個問題。在以后的幾篇文章里,我會詳細介紹這三...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。異步編程入門的全稱是前端經典面試題從輸入到頁面加載發生了什么這是一篇開發的科普類文章,涉及到優化等多個方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結思考,循序漸進的理解 TypeScript。 網絡基礎知識之 HTTP 協議 詳細介紹 HTT...
閱讀 3197·2021-11-25 09:43
閱讀 3407·2021-11-11 16:54
閱讀 823·2021-11-02 14:42
閱讀 3741·2021-09-30 09:58
閱讀 3664·2021-09-29 09:44
閱讀 1279·2019-08-30 15:56
閱讀 2097·2019-08-30 15:54
閱讀 2985·2019-08-30 15:43