摘要:引子獨家解析原型繼承已經(jīng)比較全面的分析了自定義函數(shù)類型,內(nèi)置基本類和內(nèi)置對象類型的的以及的原型鏈。鑒于函數(shù)是的一等公民,另辟新篇介紹函數(shù)的原型及其應(yīng)用。函數(shù)本身也是對象,它遵循獨家解析原型繼承所描述的自定義函數(shù)類型對象的原型法則。
引子
獨家解析Javascript原型繼承已經(jīng)比較全面的分析了自定義函數(shù)類型,JS內(nèi)置基本類(undefined, null, bool, number, string, symbol)和JS內(nèi)置對象類型(Error, Date, Function)的design-time的prototype, 以及run-time的__proto__原型鏈。鑒于函數(shù)是JS的一等公民,另辟新篇介紹函數(shù)的原型及其應(yīng)用。
JS函數(shù)類型的構(gòu)造通常情況下定義一個函數(shù):
function add1(a, b) { return a + b; } console.log(add1(1,2)) //3
通過new Function也能構(gòu)造:
var add2 = new Function("a", "b", "return a + b"); console.log(add2(1,2)) //3
兩種方式達到的目的是一致的。而add1和add2的run-time __proto__都是Function.prototype, 可以看作add1和add2都是透過new Function構(gòu)造出來的,而function關(guān)鍵子就是調(diào)用new Function構(gòu)造的便利途徑。
add1.__proto__ = Function.prototype //true add2.__proto__ = Function.prototype //true
函數(shù)本身也是對象,它遵循獨家解析Javascript原型繼承所描述的自定義函數(shù)類型對象的原型法則。
//add1 創(chuàng)自于Function類型,是Function的實例 add1.__proto__ //[Function] add instanceof Function //true // add1 也繼承了object類型的原型 add1.__proto__.__proto__ //{} add1 instanceof Object //true // 所以add1 run-time __proto__原型鏈的頂端同樣是null add1.__proto__.__proto__.__proto__ // nullAOP編程實現(xiàn)
至此我們了解到,透過funtion關(guān)鍵字定義的函數(shù),實質(zhì)是Fuction類型的實例,和通過new Function方式構(gòu)造本身是一樣的。所以我們通過修改Function的design-time的prototype,來實現(xiàn)面向切面編程(AOP)
值得一提的是:我們(程序員)一般情況下只推薦修改design-time的prototype,而不去更改run-time的__proto__, 否則修改run-time的__proto__會造成程序難以維護和閱讀,增加不確定的運行錯誤。Object.setPrototypeOf可以更改對象實例run-time的__proto__
面向切面編程(AOP,Aspect-Oritented Programming), 簡而言之,可理解為函數(shù)調(diào)用時,在該函數(shù)執(zhí)行前或/和執(zhí)行后做一些通用的工作,比如做log,記錄執(zhí)行時間等。這需要一個代理函數(shù),把原始函數(shù)打扮成具有做log等功能的新函數(shù)。實際中調(diào)用該代理函數(shù)
function foo() { console.log("foo runs"); } foo(); // foo runs
現(xiàn)在我們想在foo函數(shù)執(zhí)行前后分別打印log,而不修改foo函數(shù)本身。
Function.prototype.before = function() { var _self = this; return function() { console.log("before foo calls"); return _self.apply(this, arguments); } } Function.prototype.after = function() { var _self = this; return function() { var ret = _self.apply(this, arguments); console.log("after foo calls"); return ret; } } //這里foo就具有了執(zhí)行前后打印log的功能 foo = foo.before().after(); foo(); // before foo calls // foo runs // after foo calls
把打印log的功能提出來,做成更通用的邏輯。
Function.prototype.before = function(beforeFn) { var _self = this; return function() { beforeFn.apply(this, arguments); return _self.apply(this, arguments); } } Function.prototype.after = function(afterFn) { var _self = this; return function() { var ret = _self.apply(this, arguments); afterFn.apply(this, arguments); return ret; } } //包裝成具有l(wèi)og功能的新的foo函數(shù) foo = foo.before(function() { console.log("foo enters") }).after(function(){ console.log("foo exits") }); foo(); // foo enters // foo runs // foo exits
由此,可把函數(shù)調(diào)用和通用的log能功能掛接(hook)起來了。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/84030.html
摘要:支持的類型的內(nèi)置數(shù)據(jù)類型羅列如下自定義自定義這三種類型的賦值是同類似的。這根不同,這因為是沒有包裝類新增的基本類型,只支持函數(shù)式賦值,不支持字面量和函數(shù)構(gòu)造。 JavaScript支持的類型 JS的內(nèi)置數(shù)據(jù)類型羅列如下: undefined null bool number string function object Function Date ...
摘要:面向?qū)ο髮崿F(xiàn)代碼動物發(fā)聲汪汪喵喵調(diào)用代碼動物發(fā)聲喵喵動物發(fā)聲汪汪當要增加一種動物時,只需增加一個繼承,不會影響其他已有的動物邏輯。所以的繼承和的原型繼承,可謂殊途同歸。 傳統(tǒng)面向?qū)ο蟮睦^承和多態(tài) 我們知道C++/Java/C#等面向?qū)ο笳Z言,都原生地支持類的繼承。繼承的核心作用大抵是創(chuàng)建一個派生類,并使其復(fù)用基本類(即父類)的字段和/或方法。并且派生類可以重寫基本類的方法。這樣基本類和...
摘要:每一個由構(gòu)造函數(shù)創(chuàng)建的對象都會默認的連接到該神秘對象上。在構(gòu)造方法中也具有類似的功能,因此也稱其為類實例與對象實例一般是指某一個構(gòu)造函數(shù)創(chuàng)建出來的對象,我們稱為構(gòu)造函數(shù)的實例實例就是對象。表示該原型是與什么構(gòu)造函數(shù)聯(lián)系起來的。 本文您將看到以下內(nèi)容: 傳統(tǒng)構(gòu)造函數(shù)的問題 一些相關(guān)概念 認識原型 構(gòu)造、原型、實例三角結(jié)構(gòu)圖 對象的原型鏈 函數(shù)的構(gòu)造函數(shù)Function 一句話說明什么...
摘要:設(shè)計模式是以面向?qū)ο缶幊虨榛A(chǔ)的,的面向?qū)ο缶幊毯蛡鹘y(tǒng)的的面向?qū)ο缶幊逃行┎顒e,這讓我一開始接觸的時候感到十分痛苦,但是這只能靠自己慢慢積累慢慢思考。想繼續(xù)了解設(shè)計模式必須要先搞懂面向?qū)ο缶幊蹋駝t只會讓你自己更痛苦。 JavaScript 中的構(gòu)造函數(shù) 學(xué)習(xí)總結(jié)。知識只有分享才有存在的意義。 是時候替換你的 for 循環(huán)大法了~ 《小分享》JavaScript中數(shù)組的那些迭代方法~ ...
摘要:使用新的易用的類定義,歸根結(jié)底也是要創(chuàng)建構(gòu)造函數(shù)和修改原型。首先,它把構(gòu)造函數(shù)當成單獨的函數(shù)且包含類屬性集。該節(jié)點還儲存了指向父類的指針引用,該父類也并儲存了構(gòu)造函數(shù),屬性集和及父類引用,依次類推。 原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第...
閱讀 2265·2021-09-27 13:35
閱讀 561·2019-08-30 15:55
閱讀 810·2019-08-30 15:53
閱讀 555·2019-08-30 15:52
閱讀 2146·2019-08-30 12:59
閱讀 2269·2019-08-29 16:42
閱讀 1385·2019-08-26 18:26
閱讀 2467·2019-08-26 13:48