因?yàn)樽罱胁┯逊答佄业牟┪氖侵苯臃g的參考鏈接內(nèi)的內(nèi)容,所以我在這里要說(shuō)明一下,以免引起不必要的誤會(huì)。
首先,我很喜歡 segmentfault 的交流和學(xué)習(xí)的氛圍,所以我很愿意在這里跟各位 SFer 交流學(xué)習(xí)心得,相互學(xué)習(xí),共同進(jìn)步。
第二,我做技術(shù)方面的工作不久,所以學(xué)習(xí)經(jīng)歷也不是很長(zhǎng),但是我發(fā)現(xiàn)寫(xiě)博客,總結(jié)自己的學(xué)習(xí)心得是個(gè)很好的學(xué)習(xí)習(xí)慣,至少對(duì)于我個(gè)人而言,我于此收益頗豐,所以我決定堅(jiān)持一天至少寫(xiě)一篇博客,以督促自己天天學(xué)習(xí),吸取知識(shí)。
第三,由于我個(gè)人能力有限,除了有幾篇知識(shí)性的總結(jié)博文外,其余的博文都是直接翻譯的國(guó)外教程,在中間間接性地插入自己的一些想法和筆記,其主要目的是為了方便自己回顧記憶。之所以把博文的名字命名為《細(xì)說(shuō) Javascript xxx 篇》這種格式,是鑒于 segmentfault 暫時(shí)還沒(méi)有個(gè)人標(biāo)簽的功能,這樣比較適合我個(gè)人進(jìn)行歸納分類(lèi)。
第四,我每篇博文后面都附有參考鏈接,由于我個(gè)人能力有限,所以有些地方可能自己理解或翻譯的不恰當(dāng),那么博友們可以點(diǎn)擊參考鏈接直接看原文的內(nèi)容。
最后,我想說(shuō)的是,我之所以在 segmentfault 寫(xiě)博客,主要目的就是為了能與大家多多交流,彼此相互學(xué)習(xí),我相信大家來(lái) segmentfault 的目的大體都是這樣的,所以我希望在 segmentfault 這個(gè)優(yōu)秀的平臺(tái)獲得知識(shí)取得進(jìn)步的同時(shí),也能為 segmentfault 貢獻(xiàn)自己的一份力量。
言歸真正,接下來(lái)我們討論 Javascript 的 arguments 對(duì)象。
每一個(gè) Javascript 函數(shù)都能在自己作用域內(nèi)訪問(wèn)一個(gè)特殊的變量 - arguments。這個(gè)變量含有一個(gè)傳遞給函數(shù)的所有參數(shù)的列表。
arguments 對(duì)象不是一個(gè)數(shù)組。盡管在語(yǔ)法上它跟數(shù)組有相同的地方,例如它擁有 length 屬性。但它并不是從 Array.prototype 繼承而來(lái),實(shí)際上,它就是一個(gè)對(duì)象。
因此,我們不能直接對(duì) arguments 使用一些數(shù)組的方法,例如 push, pop 或 slice 等。 所以為了使用這些方法,我們就需要將其轉(zhuǎn)換為一個(gè)真正的數(shù)組。
下面的代碼將會(huì)返回一個(gè)包含 arguments 對(duì)象所有元素的數(shù)組。
Array.prototype.slice.call(arguments);
由于轉(zhuǎn)化的速度很慢,所以在性能要求嚴(yán)格的程序中不建議這樣做。
傳遞參數(shù)下面是一種比較推薦的方法,將 arguments 對(duì)象從一個(gè)函數(shù)傳遞到另一個(gè)函數(shù)。
function foo() { bar.apply(null, arguments); } function bar(a, b, c) { // do stuff here }
另外還有一個(gè)比較巧妙的方法,就是同時(shí)使用 call 和 apply 快速創(chuàng)建一個(gè)解綁的外層方法。
function Foo() {} Foo.prototype.method = function(a, b, c) { console.log(this, a, b, c); }; // Create an unbound version of "method" // It takes the parameters: this, arg1, arg2...argN Foo.method = function() { // Result: Foo.prototype.method.call(this, arg1, arg2... argN) Function.call.apply(Foo.prototype.method, arguments); };函數(shù)形參和 arguments 屬性的關(guān)系
arguments 對(duì)象為它自身屬性和函數(shù)的形參都創(chuàng)建了 getter 和 setter 方法。
因此,修改函數(shù)的形參會(huì)影響對(duì)應(yīng)的 arguments 對(duì)象的屬性值,反之亦然。
function foo(a, b, c) { arguments[0] = 2; a; // 2 b = 4; arguments[1]; // 4 var d = c; d = 9; c; // 3 } foo(1, 2, 3);性能問(wèn)題
arguments 只在兩種情況下不會(huì)被創(chuàng)建,一是在函數(shù)內(nèi)部被聲明為局部變量,二是當(dāng)做函數(shù)的形參。其他情況,arguments 對(duì)象總是會(huì)被創(chuàng)建。
由于 getter 和 setter 方法總是會(huì)隨著 arguments 對(duì)象的創(chuàng)建而創(chuàng)建,因此使用 arguments 對(duì)性能本身幾乎沒(méi)有影響。
然而,有一種情形會(huì)嚴(yán)重影響 Javascript 的性能,那就是使用 arguments.callee。
function foo() { arguments.callee; // do something with this function object arguments.callee.caller; // and the calling function object } function bigLoop() { for(var i = 0; i < 100000; i++) { foo(); // Would normally be inlined... } }
在上述代碼中,foo 函數(shù)不再是一個(gè)簡(jiǎn)單的內(nèi)聯(lián)擴(kuò)展,因?yàn)樗枰浪陨硪约八恼{(diào)用者(caller)。這不僅抵消了內(nèi)聯(lián)擴(kuò)展所帶來(lái)的性能提升,同時(shí)也破壞了函數(shù)的封裝性,因?yàn)楹瘮?shù)本身可能需要依賴于一個(gè)特定的調(diào)用背景。
因此,建議大家盡量不要使用 arguments.callee。
http://bonsaiden.github.io/JavaScript-Garden/#function.arguments
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/87514.html
摘要:操作符還有可能是設(shè)計(jì)中最大缺陷,因?yàn)樗鼛缀跏峭耆茡p的。由于用法與調(diào)用函數(shù)的語(yǔ)法相似,因此常被誤以為是函數(shù)調(diào)用,實(shí)際上并不存在名為的函數(shù),只是一個(gè)操作符而已。而列則表示對(duì)象內(nèi)部的屬性。屬性文檔中明確地給出了獲得屬性的途徑,就是使用。 typeof 操作符(還有 instanceof)可能是 Javascript 設(shè)計(jì)中最大缺陷,因?yàn)樗鼛缀跏峭耆茡p的。由于 typeof 用法與調(diào)用函數(shù)...
摘要:因?yàn)槭侨躅?lèi)型語(yǔ)言,所以它會(huì)在任何可能的情形下對(duì)變量進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)換。內(nèi)置類(lèi)型的構(gòu)造函數(shù)調(diào)用內(nèi)置類(lèi)型的構(gòu)造函數(shù)時(shí),是否使用關(guān)鍵字將表現(xiàn)得大不相同。傳遞字面值或非對(duì)象值也會(huì)造成強(qiáng)制類(lèi)型轉(zhuǎn)換的現(xiàn)象。最好的方法就是顯示地將值轉(zhuǎn)換為,或三種類(lèi)型之一。 因?yàn)?Javascript 是弱類(lèi)型語(yǔ)言,所以它會(huì)在任何可能的情形下對(duì)變量進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)換。 // These are true new Num...
摘要:什么是函數(shù)引用的原話函數(shù)是一組可以隨時(shí)隨地運(yùn)行的語(yǔ)句。函數(shù)是由這樣的方式進(jìn)行聲明的關(guān)鍵字函數(shù)名一組參數(shù),以及置于括號(hào)中的待執(zhí)行代碼。 什么是函數(shù)? 引用 W3School 的原話: 函數(shù)是一組可以隨時(shí)隨地運(yùn)行的語(yǔ)句。 函數(shù)是 ECMAScript 的核心。 函數(shù)是由這樣的方式進(jìn)行聲明的:關(guān)鍵字 function、函數(shù)名、一組參數(shù),以及置于括號(hào)中的待執(zhí)行代碼。 函數(shù)的基本語(yǔ)法是這樣的:...
摘要:第二是,由于會(huì)遍歷整個(gè)原型鏈,所以當(dāng)原型鏈過(guò)長(zhǎng)時(shí),會(huì)對(duì)性能造成影響。總結(jié)建議養(yǎng)成過(guò)濾屬性的好習(xí)慣,不要對(duì)運(yùn)行環(huán)境做任何假設(shè),也無(wú)論原生的原型對(duì)象是否被擴(kuò)展。 如同 in 運(yùn)算符一樣,使用 for in 循環(huán)遍歷對(duì)象屬性時(shí),也將往上遍歷整個(gè)原型鏈。 // Poisoning Object.prototype Object.prototype.bar = 1; var foo = {m...
摘要:并沒(méi)有類(lèi)繼承模型,而是使用原型對(duì)象進(jìn)行原型式繼承。我們舉例說(shuō)明原型鏈查找機(jī)制當(dāng)訪問(wèn)一個(gè)對(duì)象的屬性時(shí),會(huì)從對(duì)象本身開(kāi)始往上遍歷整個(gè)原型鏈,直到找到對(duì)應(yīng)屬性為止。原始類(lèi)型有以下五種型。此外,試圖查找一個(gè)不存在屬性時(shí)將會(huì)遍歷整個(gè)原型鏈。 Javascript 并沒(méi)有類(lèi)繼承模型,而是使用原型對(duì)象 prototype 進(jìn)行原型式繼承。 盡管人們經(jīng)常將此看做是 Javascript 的一個(gè)缺點(diǎn),然...
閱讀 2650·2021-10-12 10:12
閱讀 791·2019-08-29 17:25
閱讀 2794·2019-08-29 17:24
閱讀 3228·2019-08-29 17:19
閱讀 1810·2019-08-29 15:39
閱讀 3057·2019-08-26 16:50
閱讀 2003·2019-08-26 12:17
閱讀 2708·2019-08-26 12:16