目次
1. 引数とは何ですか
2. arguments 操作
2.1 arguments length
3.4 arguments 转数组
2.3 修改 arguments 值
2.4 将参数从一个函数传递到另一个函数
2.5 arguments 与重载
3. ES6 中的 arguments
3.1 扩展操作符
3.2 Rest 参数
3.3 默认参数

2.1 引数の長さ

2.2 引数を配列に変換
2.3 引数の値を変更する
2.4 ある関数から別の関数にパラメーターを渡す
2.5 引数とオーバーロード
3.1 拡張演算子
3.2 Rest パラメータ
3.3 デフォルトのパラメータ
配列への 3.4 つの引数
ホームページ ウェブフロントエンド jsチュートリアル JavaScriptの引数オブ​​ジェクトの詳しい説明

JavaScriptの引数オブ​​ジェクトの詳しい説明

Mar 03, 2017 pm 03:13 PM
javascript

1. 引数とは何ですか

は MDN で説明されています:

arguments は配列のようなオブジェクトです。関数に渡されるパラメータのリストを表します。

まず、JavaScript の引数がどのようなものかを直感的に理解するために例を使用してみましょう。

function printArgs() {
    console.log(arguments);
}
printArgs("A", "a", 0, { foo: "Hello, arguments" });
ログイン後にコピー

実行結果は次のとおりです:

["A", "a", 0, Object]
ログイン後にコピー

一見、結果は配列ですが、実際の配列ではないため、引数は配列のようなオブジェクトです(実際の配列との違いを知りたい場合)配列のようなオブジェクト、最後までスクロールできます)。

引数で表される内容をもう一度見てください。これは、関数の実行時に関数に渡されるすべてのパラメーターを表します。上の例では、printArgs 関数に渡される 4 つのパラメーターを表しており、それぞれ arguments[0]arguments[1]</ として使用できます。コード >… を使用して単一のパラメータを取得します。 <code>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);
ログイン後にコピー

还有一个更简短的写法:

[].slice.call(arguments);
ログイン後にコピー

在这里,只是简单地调用了空数组的 slice 方法,而没有从 Array 的原型层面调用。

为什么上面两种方法可以转换呢?

首先,slice 方法得到的结果是一个数组,参数便是 arguments。事实上,满足一定条件的对象都能被 slice 方法转换成数组。看个例子:

const obj = { 0: "A", 1: "B", length: 2 };
const result = [].slice.call(obj);
console.log(Array.isArray(result), result);
ログイン後にコピー

执行结果是:

true ["A", "B"]
ログイン後にコピー

从上面例子可以看出,条件就是: 1) 属性为 0,1,2…;2) 具有 length 属性;

另外,有一个需要注意的地方就是,不能将函数的 arguments 泄露或者传递出去。什么意思呢?看下面的几个泄露 arguments 的例子:

// 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 对象泄露出去了,最终的结果就是 V8 引擎将会跳过优化,导致相当大的性能损失。

你可以这么做:

function getArgs() {
    const args = new Array(arguments.length);
    for(let i = 0; i < args.length; ++i) {
        args[i] = arguments[i];
    }
    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 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);
ログイン後にコピー

输出结果为:

1 1
10 10
20 20
ログイン後にコピー

从上面的两个例子中可以看出,在严格模式下,函数中的参数与 arguments 对象没有联系,修改一个值不会改变另一个值。而在非严格模式下,两个会互相影响。

2.4 将参数从一个函数传递到另一个函数

下面是将参数从一个函数传递到另一个函数的推荐做法。

function foo() {
    bar.apply(this, arguments);
}
function bar(a, b, c) {
    // logic
}
ログイン後にコピー

2.5 arguments 与重载

很多语言中都有重载,但 JavaScript 中没有。先看个例子:

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);
ログイン後にコピー

执行结果为:

Method two
Method two
ログイン後にコピー

所以,JavaScript 中,函数并没有根据参数的不同而产生不同的调用。

是不是 JavaScript 中就没有重载了呢?并不是,我们可以利用 arguments 模拟重载。还是上面的例子。

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)
ログイン後にコピー

执行结果如下:

Result is 3
Result is 6
ログイン後にコピー

3. ES6 中的 arguments

3.1 扩展操作符

直接上栗子:

function func() {
    console.log(...arguments);
}

func(1, 2, 3);
ログイン後にコピー

执行结果是:

1 2 3
ログイン後にコピー

简洁地讲,扩展操作符可以将 arguments 展开成独立的参数。

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()

2. 引数の操作

2.1 引数の長さ

arguments は length 属性を含む配列のようなオブジェクトで、arguments.length< として使用できます。 /code> 関数に渡されるパラメータの数を取得します。 <p><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>const obj = { 0: &quot;a&quot;, 1: &quot;b&quot; }; const arr = [ &quot;a&quot;, &quot;b&quot; ];</pre><div class="contentsignin">ログイン後にコピー</div></div><div class="contentsignin">ログイン後にコピー</div></div></p>実行結果は以下の通りです: 🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>function Foo() {} Foo.prototype = Object.create(Array.prototype); const foo = new Foo(); foo.push(&amp;#39;A&amp;#39;); console.log(foo, foo.length); console.log(&quot;foo is an array? &quot; + Array.isArray(foo));</pre><div class="contentsignin">ログイン後にコピー</div></div><div class="contentsignin">ログイン後にコピー</div></div><h3 id="引数を配列に変換">2.2 引数を配列に変換</h3>🎜 引数を配列に変換するには、通常次の方法が使用されます: 🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>[&quot;A&quot;] 1 foo is an array? false</pre><div class="contentsignin">ログイン後にコピー</div></div><div class="contentsignin">ログイン後にコピー</div></div>🎜もっと短い書き方もあります: 🎜 <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>function Bar() {} Bar.prototype.push = Array.prototype.push; const bar = new Bar(); bar.push(&amp;#39;A&amp;#39;); bar.push(&amp;#39;B&amp;#39;); console.log(bar);</pre><div class="contentsignin">ログイン後にコピー</div></div><div class="contentsignin">ログイン後にコピー</div></div>🎜ここでは、Arrayのプロトタイプレベルからは呼び出されず、空配列のsliceメソッドが呼び出されているだけです。 🎜🎜なぜ上記の 2 つの方法を変換できるのでしょうか? 🎜🎜まず、sliceメソッドで得られる結果は配列であり、パラメータは引数です。実際、特定の条件を満たすオブジェクトはすべて、slice メソッドによって配列に変換できます。例を見てみましょう: 🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>Bar {0: &quot;A&quot;, 1: &quot;B&quot;, length: 2}</pre><div class="contentsignin">ログイン後にコピー</div></div><div class="contentsignin">ログイン後にコピー</div></div>🎜 実行結果は次のとおりです: 🎜rrreee🎜 上記の例からわかるように、条件は次のとおりです: 1) 属性が 0、1、2... 2) length 属性がある。 🎜🎜さらに、注意が必要なことが1つあります。 ポイントは、関数の引数をリークしたり、渡したりできないことです。それはどういう意味ですか?リークされた引数の次の例を見てください: 🎜rrreee🎜 上記のアプローチでは、関数の引数オブ​​ジェクトが直接リークされ、最終的には V8 エンジンが最適化をスキップし、パフォーマンスが大幅に低下します。 🎜🎜これを行うことができます: 🎜rrreee🎜 それは非常に興味深いものです。引数を使用するときは、通常、最初のステップで引数を配列に変換します。同時に、引数を不適切に使用するとパフォーマンスの低下につながる可能性があります。引数を直接設計しない場合はどうすればよいでしょうか? 🎜🎜これは、この言語の先頭から始める必要があります。引数は、Array オブジェクトに toString、join、reverse、sort の 4 つのメソッドがあった言語の初期に導入されました。引数が Object から継承される大きな理由は、これら 4 つのメソッドが必要ないことです。現在、Array には、forEach、map、filter などの強力なメソッドが多数追加されています。では、新しいバージョンでは引数を Array から再継承させてみてはいかがでしょうか?実際、これは ES5 ドラフトに含まれていましたが、上位互換性を理由に最終的に委員会によって拒否されました。 🎜<h3 id="引数の値を変更する">2.3 引数の値を変更する</h3>🎜 strict モードと non-strict モードでは、関数のパラメータ値を変更した結果が異なります。以下の 2 つの例を見てください: 🎜rrreee🎜 出力: 🎜rrreee🎜 非厳密モードの別の例: 🎜rrreee🎜 出力は次のとおりです: 🎜rrreee🎜 上記の 2 つの例からわかるように、厳密モードでは、関数のパラメータは引数オブジェクトに関連していないため、一方の値を変更しても、もう一方の値は変更されません。非厳密モードでは、この 2 つは相互に影響します。 🎜<h3 id="ある関数から別の関数にパラメーターを渡す">2.4 ある関数から別の関数にパラメーターを渡す</h3>🎜 以下は、ある関数から別の関数にパラメーターを渡す場合の推奨される方法です。 🎜rrreee<h3 id="引数とオーバーロード">2.5 引数とオーバーロード</h3>🎜 オーバーロードは多くの言語で利用できますが、JavaScript では利用できません。まず例を見てみましょう: 🎜rrreee🎜 実行結果は次のとおりです: 🎜rrreee🎜 したがって、JavaScript では、関数は異なるパラメーターに基づいて異なる呼び出しを行いません。 🎜🎜JavaScriptにはオーバーロードはありませんか?いいえ、引数を使用してオーバーロードをシミュレートできます。まだ上記の例です。 🎜rrreee🎜実行結果は次のとおりです: 🎜rrreee🎜3. ES6 の引数🎜<h3 id="拡張演算子">3.1 拡張演算子</h3>🎜クリに直接: 🎜rrreee🎜実行結果は次のとおりです: 🎜rrreee🎜拡張演算子の引数は独立したパラメータに拡張できます。 🎜<h3 id="Rest-パラメータ">3.2 Rest パラメータ</h3>🎜同じ例: 🎜rrreee🎜実行結果は次のとおりです: 🎜rrreee🎜上記の結果からわかるように、Rest パラメータは、残りのパラメータのセットを表します。明示的な指定であり、型は Array です。 🎜<h3 id="デフォルトのパラメータ">3.3 デフォルトのパラメータ</h3>🎜チェスト: 🎜rrreee🎜実行結果は次のとおりです: 🎜rrreee🎜デフォルトのパラメータは引数に影響を与えず、引数は依然として、引数が渡されるすべてのパラメータを表すだけであることがわかります。関数を呼び出しています。 🎜<h3 id="配列への-つの引数">配列への 3.4 つの引数</h3>🎜<code>Array.from() は、すべての配列のようなオブジェクトを配列に変換できる、非常に推奨されるメソッドです。 🎜🎜4. 配列と配列のようなオブジェクト 🎜🎜 配列にはインデックスという 1 つの基本的な機能があります。これは普通の物体にはないものです。 🎜
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 arguments 对象详解的内容,更多相关内容请关注PHP中文网(www.php.cn)!

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

MySQLクエリ結果の配列をオブジェクトに変換するにはどうすればよいですか? MySQLクエリ結果の配列をオブジェクトに変換するにはどうすればよいですか? Apr 29, 2024 pm 01:09 PM

MySQL クエリ結果の配列をオブジェクトに変換する方法は次のとおりです。 空のオブジェクト配列を作成します。結果の配列をループし、行ごとに新しいオブジェクトを作成します。 foreach ループを使用して、各行のキーと値のペアを新しいオブジェクトの対応するプロパティに割り当てます。新しいオブジェクトをオブジェクト配列に追加します。データベース接続を閉じます。

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

PHP における配列とオブジェクトの違いは何ですか? PHP における配列とオブジェクトの違いは何ですか? Apr 29, 2024 pm 02:39 PM

PHP では、配列は順序付けられたシーケンスであり、要素はインデックスによってアクセスされます。オブジェクトは、new キーワードによって作成されたプロパティとメソッドを持つエンティティです。配列へのアクセスはインデックス経由で、オブジェクトへのアクセスはプロパティ/メソッド経由で行われます。配列値が渡され、オブジェクト参照が渡されます。

PHP の Request オブジェクトとは何ですか? PHP の Request オブジェクトとは何ですか? Feb 27, 2024 pm 09:06 PM

PHP の Request オブジェクトは、クライアントからサーバーに送信される HTTP リクエストを処理するために使用されるオブジェクトです。 Request オブジェクトを通じて、リクエストを処理して応答するために、リクエスト メソッド、リクエスト ヘッダー情報、リクエスト パラメータなどのクライアントのリクエスト情報を取得できます。 PHP では、$_REQUEST、$_GET、$_POST などのグローバル変数を使用して、要求された情報を取得できますが、これらの変数はオブジェクトではなく配列です。リクエスト情報をより柔軟かつ便利に処理するために、次のことができます。

JavaScript で HTTP ステータス コードを簡単に取得する方法 JavaScript で HTTP ステータス コードを簡単に取得する方法 Jan 05, 2024 pm 01:37 PM

JavaScript で HTTP ステータス コードを取得する方法の紹介: フロントエンド開発では、バックエンド インターフェイスとの対話を処理する必要があることが多く、HTTP ステータス コードはその非常に重要な部分です。 HTTP ステータス コードを理解して取得すると、インターフェイスから返されたデータをより適切に処理できるようになります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法と、具体的なコード例を紹介します。 1. HTTP ステータス コードとは何ですか? HTTP ステータス コードとは、ブラウザがサーバーへのリクエストを開始したときに、サービスが

C++ 関数がオブジェクトを返すときは何に注意する必要がありますか? C++ 関数がオブジェクトを返すときは何に注意する必要がありますか? Apr 19, 2024 pm 12:15 PM

C++ では、関数がオブジェクトを返すときに注意する点が 3 つあります。 オブジェクトのライフサイクルは、メモリ リークを防ぐために呼び出し元によって管理されます。ぶら下がりポインタを回避し、動的にメモリを割り当てるかオブジェクト自体を返すことにより、関数が戻った後もオブジェクトが有効なままであることを確認します。コンパイラーは、パフォーマンスを向上させるために、返されたオブジェクトのコピー生成を最適化する場合がありますが、オブジェクトが値セマンティクスによって渡される場合、コピー生成は必要ありません。

See all articles