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