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