関数への引数はargumentsのaliasという仕様の件
下記のツイートで忘れていたので、備忘録として。
ES3->ES5への変遷で変わった仕様をES6だとどうなんだろうと思い、書こうとおもったら、どの仕様が変わったのかを忘れてしまった件
— 10万円 (@arukmn) 2015, 11月 19
結論なんだったのかと言うと、表題の通りで、
関数の引数はargumentsのaliasについてです。
ES3では関数への引数は全てargumentsへのaliasが成立していました。
ES5では成立していません。(なんでだろう)
実際のコードで表したほうがわかりやすいですね。
(ES3とES5の実行結果の比較のために
適宜"use strict";
はコメントをつけたり外したりします)
function hello(when, person) { "use strict"; var reverse = [].reverse; reverse.call(arguments); console.log("Good " + when + "! " + person.name); } var arukmn = { name: "bob" }; hello("Morning", arukmn);
特にhello関数の説明はいらないと思います。
(argumentsの要素を逆転させて、標準出力しているだけですよ。。。)
実行結果(ES3)
下記はNode.jsで動作させた結果になります。
argumentsの逆転が見事に反映され、出力に不具合が発生しています。
Good [object Object]! undefined
実行結果(ES5)
下記はNode.jsで動作させた結果になります。
ES5ではES3の実行結果と異なり
argumentsの逆転が見事に反映されず、出力も問題ありません。
Good Morning! bob
これにより下記が証明されたかと思います。
ES3では関数への引数は全てargumentsへのaliasが成立していました。
ES5では成立していません。
なので、arguments
を直接処理を加えないようにしましょう。
可変長引数に対応させる関数を作成する際は、slice
メソッドを使って、arguments
のコピーを作成しましょう。
また、arguments
はArray
オブジェクトのprototype
を継承していないので、
上記のプログラムの様に使用してくださいね!
最後に
なんで最初のツイートをしたかというと、
この仕様はES6ではどうなっているのか知りたくなってBABELで試そうとしてました(意味深。。。)
BABELはES6のシンタックスをES5にトランスコンパイルしてくれる仕組みであるから確認なんて出来ませんよね。
AHOです。
元気があれば、文献漁ってみようかなとも思ってます。以上。