首頁 web前端 js教程 JavaScript arguments物件全面介紹

JavaScript arguments物件全面介紹

Oct 13, 2016 am 09:10 AM

1. 什麼是 arguments

MDN 上解釋:

arguments 是一個類別陣列物件。代表傳給一個function的參數清單。

我們先用一個範例直觀了解下 JavaScript 中的 arguments 長什麼樣子。

function printArgs() { 
 
console.log(arguments); 
 
} 
 
printArgs("A", "a", 0, { foo: "Hello, arguments" });
登入後複製

執行結果是:

["A", "a", 0, Object]
登入後複製

乍一看,結果是個數組,但並不是真正的數組,所以說arguments 是一個類數組的對象(想了解真正數組與類數組對象的區別可以一直翻到最後)。

再看看 arguments 表示的內容,其表示了函數執行時傳入函數的所有參數。在上面的例子中,代表了傳入 printArgs 函數中的四個參數,可以分別用 arguments[0]、 arguments[1]... 來取得單一的參數。

2. arguments 操作

2.1 arguments length

arguments 是個類別數組對象,其包含一個 length 屬性,可以用 arguments.length 來獲得傳入函數的參數個數。

function func() { 
 
console.log("The number of parameters is " + arguments.length); 
 
} 
 
func(); 
 
func(1, 2); 
 
func(1, 2, 3);
登入後複製

執行結果如下:

The number of parameters is 0 
 
The number of parameters is 2 
 
The number of parameters is 3
登入後複製

2.2 arguments 轉數組

通常使用下面的方法來將arguments 轉換成數組:

Array.prototype.slice.call(arguments);
登入後複製

還有一個更簡短的寫法:

rr空數組的slice 方法,而沒有從Array 的原型層面呼叫。

為什麼上面兩種方法可以轉換呢?

首先,slice 方法得到的結果是一個數組,參數就是 arguments。事實上,滿足一定條件的物件都能被 slice 方法轉換成陣列。看個例子:

[].slice.call(arguments);
登入後複製

執行結果是:

const obj = { 0: "A", 1: "B", length: 2 }; 
 
const result = [].slice.call(obj); 
 
console.log(Array.isArray(result), result);
登入後複製

從上面例子可以看出,條件就是: 1) 屬性為0,1,2...;2) 具有length 屬性;

另外,有一個需要注意的地方就是,不能將函數的arguments 洩漏或傳遞出去。什麼意思呢?看下面的幾個洩漏 arguments 的例子:

true ["A", "B"]
登入後複製

上面的做法就直接將函數的 arguments 對象洩露出去了,最終的結果就是 V8 引擎將會跳過優化,導致相當大的性能損失。

你可以這麼做:

// Leaking arguments example1: 
 
function getArgs() { 
 
    return arguments; 
 
} 
 
// Leaking arguments example2: 
 
function getArgs() { 
 
    const args = [].slice.call(arguments); 
 
    return args; 
 
} 
 
// Leaking arguments example3: 
 
function getArgs() { 
 
    const args = arguments; 
 
    return function() { 
 
    return args; 
 
    }; 
 
}
登入後複製

那就很好奇了,我們每次使用arguments 時通常第一步都會將其轉換為數組,同時arguments 使用不當還容易導致性能損失,那麼為什麼不將arguments 直接設計成數組物件呢?

這需要從這門語言的一開始說起。 arguments 在語言的早期就引入了,當時的 Array 物件有 4 個方法: toString、 join、 reverse 和 sort。 arguments 繼承於 Object 的很大原因是不需要這四個方法。而現在,Array 增加了許多強大的方法,像是 forEach、map、filter 等等。那為什麼現在不在新的版本裡讓 arguments 重新繼承自 Array呢?其實 ES5 的草案中就包含這一點,但為了向前兼容,最終還是被委員會否決了。

2.3 修改 arguments 值

在嚴格模式與非嚴格模式下,修改函數參數值表現的結果不一樣。看下面的兩個例子:

function getArgs() { 
 
    const args = new Array(arguments.length); 
 
    for(let i = 0; i < args.length; ++i) { 
 
    args[i] = arguments[i]; 
 
    } 
 
    return args; 
 
}
登入後複製

輸出:

function foo(a) { 
 
"use strict"; 
 
console.log(a, arguments[0]); 
 
a = 10; 
 
console.log(a, arguments[0]); 
 
arguments[0] = 20; 
 
console.log(a, arguments[0]); 
 
} 
 
foo(1);
登入後複製

另一個非嚴格模式的例子:

1 1 
 
10 1 
 
10 20
登入後複製

輸出結果為:

function foo(a) { 
 
console.log(a, arguments[0]); 
 
a = 10; 
 
console.log(a, arguments[0]); 
 
arguments[0] = 20; 
 
console.log(a, arguments[0]); 
 
} 
 
foo(1);
登入後複製

從上面的兩個例子中可以看出,在嚴格模式下,函數中的參數與arguments 物件沒有聯繫,修改一個值不會改變另一個值。而在非嚴格模式下,兩個會互相影響。

2.4 將參數從一個函數傳遞到另一個函數

下面是將參數從一個函數傳遞到另一個函數的建議做法。

1 1 
 
10 10 
 
20 20
登入後複製

2.5 arguments 與重載

很多語言中都有重載,但 JavaScript 中沒有。先看個例子:

function foo() { 
 
bar.apply(this, arguments); 
 
} 
 
function bar(a, b, c) { 
 
// logic 
 
}
登入後複製

執行結果為:

function add(num1, num2) { 
 
console.log("Method one"); 
 
return num1 + num2; 
 
} 
 
function add(num1, num2, num3) { 
 
console.log("Method two"); 
 
return num1 + num2 + num3; 
 
} 
 
add(1, 2); 
 
add(1, 2, 3);
登入後複製

所以,JavaScript 中,函數並沒有根據參數的不同而產生不同的呼叫。

是不是 JavaScript 中就沒有重載了呢?並不是,我們可以利用 arguments 模擬重載。還是上面的例子。

Method two 
 
Method two
登入後複製

執行結果如下:

function add(num1, num2, num3) { 
 
    if (arguments.length === 2) { 
 
    console.log("Result is " + (num1 + num2)); 
 
    } 
 
    else if (arguments.length === 3) { 
 
    console.log("Result is " + (num1 + num2 + num3)); 
 
    } 
 
} 
 
add(1, 2); 
 
add(1, 2, 3)
登入後複製

3. ES6 中的arguments

3.1 擴充運算子

直接上栗子:

Result is 3 
 
Result is 6
登入後複製

執行結果是:

直接上栗子:

function func() { 
 
console.log(...arguments); 
 
} 
 
func(1, 2, 3);
登入後複製

執行結果是:

直接上栗子:

1 2 3
登入後複製

執行結果是:獨立的參數。

3.2 Rest 參數

還是上栗子:

function func(firstArg, ...restArgs) { 
 
console.log(Array.isArray(restArgs)); 
 
console.log(firstArg, restArgs); 
 
} 
 
func(1, 2, 3);
登入後複製

執行結果是:

true 
 
1 [2, 3]
登入後複製

從上面的結果可以看出,Rest 參數表示除了明確指定剩餘的參數集合,類型是 Array。

3.3 預設參數

栗子:

function func(firstArg = 0, secondArg = 1) { 
 
console.log(arguments[0], arguments[1]); 
 
console.log(firstArg, secondArg); 
 
} 
 
func(99);
登入後複製

執行結果是:

99 undefined 
 
99 1
登入後複製

可見,預設參數對 arguments 沒有影響,arguments 還是僅表示調用函數時所傳入的所有參數。

3.4 arguments 轉數組

Array.from() 是個非常推薦的方法,其可以將所有類別數組物件轉換成陣列。

4. 陣列與類別數組物件

數組具有一個基本特徵:索引。這是一般對象所沒有的。

const obj = { 0: "a", 1: "b" }; 
 
const arr = [ "a", "b" ];
登入後複製

我們利用 obj[0]、arr[0] 都能取得自己想要的數據,但取得數據的方式確實不同的。 obj[0] 是利用物件的鍵值對存取數據,而arr[0] 卻是利用陣列的索引。事實上,Object 與 Array 的唯一區別就是 Object 的屬性是 string,而 Array 的索引是 number。 🎜🎜下面看看類別數組物件。 🎜

伪数组的特性就是长得像数组,包含一组数据以及拥有一个 length 属性,但是没有任何 Array 的方法。再具体的说,length 属性是个非负整数,上限是 JavaScript 中能精确表达的最大数字;另外,类数组对象的 length 值无法自动改变。

如何自己创建一个类数组对象?

function Foo() {} 
 
Foo.prototype = Object.create(Array.prototype); 
 
const foo = new Foo(); 
 
foo.push(&#39;A&#39;); 
 
console.log(foo, foo.length); 
 
console.log("foo is an array? " + Array.isArray(foo));
登入後複製

执行结果是:

["A"] 1 
 
foo is an array? false
登入後複製

也就是说 Foo 的示例拥有 Array 的所有方法,但类型不是 Array。

如果不需要 Array 的所有方法,只需要部分怎么办呢?

function Bar() {} 
 
Bar.prototype.push = Array.prototype.push; 
 
const bar = new Bar(); 
 
bar.push(&#39;A&#39;); 
 
bar.push(&#39;B&#39;); 
 
console.log(bar);
登入後複製

执行结果是:

Bar {0: "A", 1: "B", length: 2}
登入後複製

参考:

JavaScript中的数组与伪数组的区别

MDN arguments

Avoid modifying or passing arguments into other functions — it kills optimization

Optimization killers

Why isn't a function's arguments object an array in Javascript?

arguments 对象

Advanced Javascript: Objects, Arrays, and Array-Like objects

JavaScript 特殊对象 Array-Like Objects 详解

What is a good way create a Javascript array-like object?


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何創建和發布自己的JavaScript庫? 如何創建和發布自己的JavaScript庫? Mar 18, 2025 pm 03:12 PM

文章討論了創建,發布和維護JavaScript庫,專注於計劃,開發,測試,文檔和促銷策略。

如何在瀏覽器中優化JavaScript代碼以進行性能? 如何在瀏覽器中優化JavaScript代碼以進行性能? Mar 18, 2025 pm 03:14 PM

本文討論了在瀏覽器中優化JavaScript性能的策略,重點是減少執行時間並最大程度地減少對頁面負載速度的影響。

前端熱敏紙小票打印遇到亂碼問題怎麼辦? 前端熱敏紙小票打印遇到亂碼問題怎麼辦? Apr 04, 2025 pm 02:42 PM

前端熱敏紙小票打印的常見問題與解決方案在前端開發中,小票打印是一個常見的需求。然而,很多開發者在實...

如何使用瀏覽器開發人員工具有效調試JavaScript代碼? 如何使用瀏覽器開發人員工具有效調試JavaScript代碼? Mar 18, 2025 pm 03:16 PM

本文討論了使用瀏覽器開發人員工具的有效JavaScript調試,專注於設置斷點,使用控制台和分析性能。

如何有效地使用Java的收藏框架? 如何有效地使用Java的收藏框架? Mar 13, 2025 pm 12:28 PM

本文探討了Java收藏框架的有效使用。 它強調根據數據結構,性能需求和線程安全選擇適當的收集(列表,設置,地圖,隊列)。 通過高效優化收集用法

如何使用源地圖調試縮小JavaScript代碼? 如何使用源地圖調試縮小JavaScript代碼? Mar 18, 2025 pm 03:17 PM

本文說明瞭如何使用源地圖通過將其映射回原始代碼來調試JAVASCRIPT。它討論了啟用源地圖,設置斷點以及使用Chrome DevTools和WebPack之類的工具。

開始使用Chart.js:PIE,DONUT和BUBBLE圖表 開始使用Chart.js:PIE,DONUT和BUBBLE圖表 Mar 15, 2025 am 09:19 AM

本教程將介紹如何使用 Chart.js 創建餅圖、環形圖和氣泡圖。此前,我們已學習了 Chart.js 的四種圖表類型:折線圖和條形圖(教程二),以及雷達圖和極地區域圖(教程三)。 創建餅圖和環形圖 餅圖和環形圖非常適合展示某個整體被劃分為不同部分的比例。例如,可以使用餅圖展示野生動物園中雄獅、雌獅和幼獅的百分比,或不同候選人在選舉中獲得的投票百分比。 餅圖僅適用於比較單個參數或數據集。需要注意的是,餅圖無法繪製值為零的實體,因為餅圖中扇形的角度取決於數據點的數值大小。這意味著任何占比為零的實體

誰得到更多的Python或JavaScript? 誰得到更多的Python或JavaScript? Apr 04, 2025 am 12:09 AM

Python和JavaScript開發者的薪資沒有絕對的高低,具體取決於技能和行業需求。 1.Python在數據科學和機器學習領域可能薪資更高。 2.JavaScript在前端和全棧開發中需求大,薪資也可觀。 3.影響因素包括經驗、地理位置、公司規模和特定技能。

See all articles