摘要:英文原文中本來是,而翻譯成第一類公民其實就是一種比喻。所以,通過上述的結果,我們發現在中不管我們是用構造函數創建的對象還是用本身提供的數據類型創建的對象都源自于。使用可以解除函數體內代碼和函數名的耦合狀態。
作為一個Jser,不光要會用js,還要明白它的運行原理,不然就會一直停留在表面。
函數在JavaScript中被稱作第一等公民,這個第一等公民是什么鬼?看看知乎上是怎么回答的。就像我的引路人剛開始跟我說的要想學好一門語言,就要先掌握好一門外語(英語)一樣,因為這些計算機編程語言或解釋器語言基本都是源于老外開發,所以要想學到原汁原味的東西,查看英文文檔是必不可少的。
英文原文中本來是 first-class object ,而翻譯成 第一類公民 其實就是一種比喻。從這里可以知道兩點:
函數本質上也是對象,
可以用函數實現其它的任何對象
函數的用法可以動態的創建函數 (new Function())
這種方式不常用,也不推薦。具體原因是(來自于JavaScript高級程序設計):這種語法會導致解析兩次代碼,從而影響性能。
可以將函數賦值給變量(函數表達式)
可以將函數最為一個參數傳遞給另一個函數(回調函數)
函數可以包含自己的屬性和方法(構造函數)
將一個函數作為另一個函數的返回值
對象數組的排序,代碼如下:
function compare(prop) { return fucntion(obj1, obj2) { var v1 = obj1[prop], v2 = obj2[prop] return v1 > v2 ? 1 : v1 < v2 ? -1 : 0 } } var arr = [{ name: "li", age: 18 }, { name: "an", age: 19 }, { name: "tian", age: 18 }] arr.sort(compare("name"))函數與對象之間的關系
通過上面的描述,不管之前知道不知道,但是現在應該知道,我們可以通過函數來創建對象。
代碼說明:
function Robot(name) { this.name = name } var robert = new Robot("robert") robert.__proto__.constructor // ? Robot(name) {this.name = name} roboert.__proto__.constructor.__proto__.constructor // ? Function() { [native code] } robert.__proto__.__proto__.constructor // ? Object() { [native code] } robert.__proto__.__proto__.constructor.__proto__.constructor // ? Function() { [native code] } robert.__proto__.__proto__.__proto__ // null
通過原型鏈,我們可以知道我們的實例對象源于誰。如上面的例子,我們創建了構造函數 Robot,用它實例化了一個robert對象,所以robert對象源自于構造函數Robot,而構造函數Robot的原型通過打印值,我們知道它源自于對象Function;接著看,通過原型鏈繼承我們可以知道,Robot繼承自對象Object,而Object的構造函數則源自于Function;而順著原型鏈我們查找Object的原型的對象,會得到一個空值。所以,通過上述的結果,我們發現在js中不管我們是用構造函數創建的對象還是用js本身提供的數據類型創建的對象都源自于Function。
在js中創建對象的基本方式大致分為四類:
構造函數 (如:一般構造函數,寄生構造函數,穩妥構造函數等)
包裝器(如:new Number()/new Object()等等)
對象字面量 (如:var obj = {name: "robert", age: 18})
原型
然后,就是根據需要使用上面的基本方式的隨機組合。
Function對象的屬性Function既然是個對象,那么它就可以擁有自己的屬性。這個我們可以在瀏覽器控制臺輸入 函數名. 后,瀏覽器就可以自動提示函數的屬性。而我們常用的式函數的內部屬性,我們常見的就是 arguments 和 this。前者是一個包含函數傳入的參數偽數組,后者指向函數對象本身。同時我們也注意到了arguments對象包含一個屬性 callee ,它是一個指針,指向包含 arguments 屬性的函數。它和 this 的區別就是arguments.callee()可以代表函數本身,而 this 就是函數執行環境的對象。
使用arguments.callee()可以解除函數體內代碼和函數名的耦合狀態。
參考代碼如下:
function fic(n) { return n <=1 ? 1 : n * arguments.callee(n-1) } function fic2(n) { return n <= 1 ? 1 : n * fic(n-1) } function fic3() { return 0 } fic(5) // 120 fic2(5) // 120 var fic4 = fic var fic5 = fic2 fic = fic3 fic2 = fic3 fic(5) // 0 fic2(5) // 0 fic4(5) // 120 fic5(5) // 0
通過函數fic4和fic5的比較我們可以的出上面的結論。
name: 函數的名字
length: 函數傳入參數的個數
Function對象的方法我們常見的是 apply/call , apply方法接收兩個參數,第一個都是在其中運行的函數作用域,第二個參數為一個參數數組。
在ES5中還有一個方法bind也可以改變函數運行時內部的作用域,它有一個參數,該參數就是函數內部this要綁定的對象。
后續可能還會繼續修改,也歡迎各位批評指正。有問題或者有其他想法的可以在我的GitHub上pr。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94607.html
摘要:今天同學去面試,做了兩道面試題全部做錯了,發過來給道典型的面試題前端掘金在界中,開發人員的需求量一直居高不下。 排序算法 -- JavaScript 標準參考教程(alpha) - 前端 - 掘金來自《JavaScript 標準參考教程(alpha)》,by 阮一峰 目錄 冒泡排序 簡介 算法實現 選擇排序 簡介 算法實現 ... 圖例詳解那道 setTimeout 與循環閉包的經典面...
摘要:函數表達式的分類匿名函數表達式具名函數表達式自調用函數表達式函數表達式的用法使用來接偶函數名和函數體的耦合狀態。修改函數表達式代碼如下閉包我們知道,函數表達式是將匿名函數賦值給一個變量,作為變量的值,所以,匿名函數也可以作為的返回值。 這篇文章要介紹的內容是函數表達,因為我個人比較喜歡使用函數表達式定義函數,所以就對它做了一些研究和整理。其實,說到函數表達式,就不得不說到定義函數的另一...
摘要:責編現代化的方式開發一個圖片上傳工具前端掘金對于圖片上傳,大家一定不陌生。之深入事件機制前端掘金事件綁定的方式原生的事件綁定方式有幾種想必有很多朋友說種目前,在本人目前的研究中,只有兩種半兩種半還有半種的且聽我道來。 Ajax 與數據傳輸 - 前端 - 掘金背景 在沒有ajax之前,前端與后臺傳數據都是靠表單傳輸,使用表單的方法傳輸數據有一個比較大的問題就是每次提交數據都會刷新頁面,用...
摘要:因為用戶不用在第一次進入應用時下載所有代碼,用戶能更快的看到頁面并與之交互。譯高階函數利用和來編寫更易維護的代碼高階函數可以幫助你增強你的,讓你的代碼更具有聲明性。知道什么時候和怎樣使用高階函數是至關重要的。 Vue 折騰記 - (10) 給axios做個挺靠譜的封裝(報錯,鑒權,跳轉,攔截,提示) 稍微改改都能直接拿來用~~~喲吼吼,喲吼吼..... 如何無痛降低 if else 面...
摘要:插件開發前端掘金作者原文地址譯者插件是為應用添加全局功能的一種強大而且簡單的方式。提供了與使用掌控異步前端掘金教你使用在行代碼內優雅的實現文件分片斷點續傳。 Vue.js 插件開發 - 前端 - 掘金作者:Joshua Bemenderfer原文地址: creating-custom-plugins譯者:jeneser Vue.js插件是為應用添加全局功能的一種強大而且簡單的方式。插....
閱讀 2932·2023-04-26 01:49
閱讀 2066·2021-10-13 09:39
閱讀 2278·2021-10-11 11:09
閱讀 923·2019-08-30 15:53
閱讀 2816·2019-08-30 15:44
閱讀 916·2019-08-30 11:12
閱讀 2966·2019-08-29 17:17
閱讀 2371·2019-08-29 16:57