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