一. 役割
デフォルトパラメータと可変長パラメータの目標は、arguments オブジェクトを完全に置き換えることです
厳格モード('use strict';)は arguments に以下の制限を課しました:
-
eval と arguments はプログラム構文を通じてバインドまたは代入できません
-
パラメータの値は arguments オブジェクトの値の変更によって変化せず、その逆も同様です
-
arguments.callee のサポートが終了しました
(厳格モード - JavaScript | MDN より引用)
最初の 2 条は arguments オブジェクトに対する不満ですが、arguments オブジェクトは可変長引数関数を実装する鍵となる方法であるため(もちろん、Object/Array タイプのパラメータでシミュレートすることもできますが、arguments ほど便利で柔軟ではありません)、引き続きサポートする必要があります。そのため、厳格モード(パッチ)を通じて arguments オブジェクトを制限しようとしています
3 条目は黒技術が封印されたことを示し、arguments は名実ともに(パラメータとのみやり取りする)なりました
ES6(新バージョン)は厳格モードを基盤としてさらに一歩進み、arguments オブジェクトを徐々に忘れることを目指しています。可変長パラメータが代替案であり、それに锦上添花するデフォルトパラメータもあります
二. 可変長パラメータ
...arg 構文がより良いセマンティクス(可変長パラメータを表す)をもたらしました
可変長パラメータは可変長引数関数(任意の数のパラメータを受け入れられる関数)の別の実装方法を提供します(arguments オブジェクトは不要)。特徴は以下の通り:
-
可読性が向上し、パラメータリストからその関数が可変長引数関数であることが分かり、パラメータインデックス(
arguments[0])の問題も解決しました -
可変長パラメータはパラメータリストの末尾に必須で、追加パラメータがない場合の値は
[]で、undefinedではありません
例:
function containsAny(s, ...aSubStr) {
for (var subStr of aSubStr) {
if (s.indexOf(subStr) !== -1) {
return true;
}
}
return false;
}
// test
console.log(containsAny('ECMAScript 6', 'es')); // false
console.log(containsAny('ECMAScript 6', 'es', '6')); // true
可変長パラメータがもたらす利便性はパラメータ操作が容易になり、以下のようなステップが不要になりました:
var fn = function(a, b) {
var args = Array.prototype.slice.call(arguments);
// 命名パラメータ a と b を切り取る
var others = args.slice(2);
// ...
}
三. デフォルトパラメータ
arg=defaultVal 構文はデフォルトパラメータを表し、他の言語と同じです。特徴は以下の通り:
-
defaultValは任意の合法な式にできるため、左側のパラメータに基づいて現在のパラメータのデフォルト値を生成できます -
undefinedを渡すのはプレースホルダーに相当し、依然としてデフォルト値が使用され、渡されたundefinedではありません -
標準では、可変長パラメータまたはデフォルトパラメータを使用する関数内でarguments オブジェクトの使用を禁止していますが、Chrome49、FF45、thinkjs はこの制限を実装していません
例:
function error(type = 'Undefined') {
console.log(`${type} error occurs`);
}
// test
error(); // Undefined error occurs
error('Script'); // Script error occurs
// 動的にデフォルト値を生成し undefined を渡す
function hoho(name, sex, words = sex === 'F' ? 'Hi Girl' : 'Hello boy') {
console.log(`${words}, you are ${name}`);
}
hoho('Sam', 'M'); // Hello boy, you are Sam
hoho('Lis', 'F'); // Hi Girl, you are Lis
hoho('Mee', 'F', undefined); // Hi Girl, you are Mee
// arguments オブジェクト
function fun(arg = 'defaultVal', ...aOther) {
var args = Array.prototype.slice.call(arguments);
console.log(args.length);
}
fun(1, 2, 3); // 3
錦上添花の小さな機能で、以前は注釈による煩雑な書き方を避ける必要がありました:
/**
* [fn description]
* @param {[type]} a [description]
* @param {[type]} b 選択可能、デフォルト値は{}、xxx を表す
* @return {Function} [description]
*/
var fn = function(a, b) {
b = b || {}; // b のデフォルト値を{}に設定
}
この古い方法は面倒でエラーも起こりやすく(b が 0 または false になり得る場合さらに面倒)、デフォルトパラメータがあれば余分な注釈は不要になります。ただし、デフォルト値の生成方法が複雑な場合は、注釈を通じて追加説明が必要です
四. まとめ
本稿の内容は非常に少なく、主にコードの可読性向上に関するもので、2 点あります:
-
デフォルトパラメータの設定がより便利になり、構文がデフォルト構文になりました
-
可変長引数関数がより合理的な実装方法を得て、arguments オブジェクトに依存しなくなりました
参考資料
- 《ES6 in Depth》:InfoQ 中文站が提供する無料電子書籍
コメントはまだありません