From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- .../functions/arguments/@@iterator/index.html | 63 +++ .../functions/arguments/callee/index.html | 158 ++++++ .../functions/arguments/caller/index.html | 56 ++ .../reference/functions/arguments/index.html | 227 ++++++++ .../functions/arguments/length/index.html | 124 +++++ .../reference/functions/arrow_functions/index.html | 405 +++++++++++++++ .../functions/default_parameters/index.html | 225 ++++++++ .../javascript/reference/functions/get/index.html | 176 +++++++ .../web/javascript/reference/functions/index.html | 575 +++++++++++++++++++++ .../functions/method_definitions/index.html | 218 ++++++++ .../reference/functions/rest_parameters/index.html | 215 ++++++++ .../javascript/reference/functions/set/index.html | 146 ++++++ 12 files changed, 2588 insertions(+) create mode 100644 files/ja/web/javascript/reference/functions/arguments/@@iterator/index.html create mode 100644 files/ja/web/javascript/reference/functions/arguments/callee/index.html create mode 100644 files/ja/web/javascript/reference/functions/arguments/caller/index.html create mode 100644 files/ja/web/javascript/reference/functions/arguments/index.html create mode 100644 files/ja/web/javascript/reference/functions/arguments/length/index.html create mode 100644 files/ja/web/javascript/reference/functions/arrow_functions/index.html create mode 100644 files/ja/web/javascript/reference/functions/default_parameters/index.html create mode 100644 files/ja/web/javascript/reference/functions/get/index.html create mode 100644 files/ja/web/javascript/reference/functions/index.html create mode 100644 files/ja/web/javascript/reference/functions/method_definitions/index.html create mode 100644 files/ja/web/javascript/reference/functions/rest_parameters/index.html create mode 100644 files/ja/web/javascript/reference/functions/set/index.html (limited to 'files/ja/web/javascript/reference/functions') diff --git a/files/ja/web/javascript/reference/functions/arguments/@@iterator/index.html b/files/ja/web/javascript/reference/functions/arguments/@@iterator/index.html new file mode 100644 index 0000000000..e0690a49af --- /dev/null +++ b/files/ja/web/javascript/reference/functions/arguments/@@iterator/index.html @@ -0,0 +1,63 @@ +--- +title: 'arguments[@@iterator]()' +slug: Web/JavaScript/Reference/Functions/arguments/@@iterator +tags: + - Functions + - JavaScript + - Property + - arguments +translation_of: Web/JavaScript/Reference/Functions/arguments/@@iterator +--- +
{{jsSidebar("Functions")}}
+ +

@@iterator プロパティの初期値は {{jsxref("Array.prototype.values")}} プロパティの初期値と同じ関数オブジェクトです。

+ +

構文

+ +
arguments[Symbol.iterator]()
+ +

+ +

for...of ループを用いた反復

+ +
function f() {
+  // your browser must support for..of loop
+  // and let-scoped variables in for loops
+  for (let letter of arguments) {
+    console.log(letter);
+  }
+}
+f('w', 'y', 'k', 'o', 'p');
+
+ +

仕様書

+ + + + + + + + + + + + + + + +
仕様書
{{SpecName('ESDraft', '#sec-createunmappedargumentsobject', 'CreateUnmappedArgumentsObject')}}
{{SpecName('ESDraft', '#sec-createmappedargumentsobject', 'CreateMappedArgumentsObject')}}
+ +

ブラウザーの互換性

+ +
+ + +

{{Compat("javascript.functions.arguments.@@iterator")}}

+
+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/functions/arguments/callee/index.html b/files/ja/web/javascript/reference/functions/arguments/callee/index.html new file mode 100644 index 0000000000..a9dd72897a --- /dev/null +++ b/files/ja/web/javascript/reference/functions/arguments/callee/index.html @@ -0,0 +1,158 @@ +--- +title: arguments.callee +slug: Web/JavaScript/Reference/Functions/arguments/callee +tags: + - Deprecated + - JavaScript + - Reference + - arguments + - プロパティ + - 関数 +translation_of: Web/JavaScript/Reference/Functions/arguments/callee +--- +
{{jsSidebar("Functions")}}
+ +

arguments.callee プロパティは現在実行中の関数を示します。

+ +

説明

+ +

calleearguments オブジェクトのプロパティです。関数の本体の内部で現在実行中の関数を参照するために使用します。これは関数名が不明であるとき、たとえば名前のない関数式(「無名関数」)の内部などで便利です。

+ +
警告: ECMAScript 第5版では、 strict モードにおける arguments.callee() の使用を禁止しています。関数式に名前を付けるか、関数が自身を呼び出す必要がある場合に関数宣言を使用するかして arguments.callee() の使用を避けてください。
+ +

なぜ arguments.callee は ES5 strict mode で削除されたのか

+ +

olliej による Stack Overflow の回答によれば)

+ +

古いバージョンの JavaScript では名前付きの関数式が利用できず、このため再帰の関数式を作成することができませんでした。

+ +

例えば、以下の構文は動作しました。

+ +
function factorial (n) {
+    return !(n > 1) ? 1 : factorial(n - 1) * n;
+}
+
+[1, 2, 3, 4, 5].map(factorial);
+ +

しかし、

+ +
[1, 2, 3, 4, 5].map(function(n) {
+    return !(n > 1) ? 1 : /*ここでどうする?*/ (n - 1) * n;
+});
+ +

は動作しませんでした。これをうまくやるために arguments.callee が追加され、あなたは以下のようなことができます。

+ +
[1, 2, 3, 4, 5].map(function(n) {
+    return !(n > 1) ? 1 : arguments.callee(n - 1) * n;
+});
+ +

しかし、これは実際には本当にダメな解決法でした。これは(他の arguments や calleecaller の問題と組み合わさって)、一般的には、再帰のインライン化と末尾再帰が不可能になるのです(あなたはこれをトレースなどを通じて選択した場合では達成できます。しかし最良のコードであっても、逆に不要な検査においては最適未満です)。他の大きな問題としては、再帰呼び出しが別の this の値になることです。例えば、

+ +
var global = this;
+
+var sillyFunction = function(recursed) {
+    if (!recursed) { return arguments.callee(true); }
+    if (this !== global) {
+        alert('This is: ' + this);
+    } else {
+        alert('This is the global');
+    }
+}
+
+sillyFunction();
+ +

ECMAScript 3 は、名前付き関数式を許可することでこれらの問題を解決しました。例えば:

+ +
[1, 2, 3, 4, 5].map(function factorial(n) {
+    return !(n > 1) ? 1 : factorial(n - 1)*n;
+});
+ +

これには多くの利点があります:

+ + + +

Another feature that was deprecated was arguments.callee.caller, or more specifically Function.caller. Why is this? Well, at any point in time you can find the deepest caller of any function on the stack, and as I said above looking at the call stack has one single major effect: it makes a large number of optimizations impossible, or much much more difficult. For example, if you cannot guarantee that a function f will not call an unknown function, it is not possible to inline f. Basically it means that any call site that may have been trivially inlinable accumulates a large number of guards:

+ +
function f(a, b, c, d, e) { return a ? b * c : d * e; }
+ +

If the JavaScript interpreter cannot guarantee that all the provided arguments are numbers at the point that the call is made, it needs to either insert checks for all the arguments before the inlined code, or it cannot inline the function. Now in this particular case a smart interpreter should be able to rearrange the checks to be more optimal and not check any values that would not be used. However in many cases that's just not possible and therefore it becomes impossible to inline.

+ +

+ +

例: 無名再帰関数内での arguments.callee の使用

+ +

再帰関数は自分自身を参照する必要があります。関数が自分自身を参照するには、一般的には関数の名前を使用します。しかしながら、無名関数には名前がありません。さらにその無名関数を参照するアクセス可能な変数も無い(関数がどの変数にも代入されていない)場合、その関数には自分自身を参照する手段がありません(無名関数は関数式または Function コンストラクターによって作成できます)。したがって、これを参照するアクセス可能な変数がない場合、関数が自分自身を参照できる唯一の方法は arguments.callee による方法です。

+ +

次の例では関数を定義し、その関数内でさらに階乗関数を定義し、それを返しています。

+ +
function create() {
+   return function(n) {
+      if (n <= 1)
+         return 1;
+      return n * arguments.callee(n - 1);
+   };
+}
+
+var result = create()(5); // 120 (5 * 4 * 3 * 2 * 1) を返す
+ +

良い代替手段がない場合の arguments.callee の使用

+ +

ただし次のような場合、 arguments.callee に代わるものが無いために、その非推奨はバグである可能性があります ( {{Bug("725398")}} を参照):

+ +
function createPerson(sIdentity) {
+    var oPerson = new Function('alert(arguments.callee.identity);');
+    oPerson.identity = sIdentity;
+    return oPerson;
+}
+
+var john = createPerson('John Smith');
+
+john();
+ +

仕様策定状況

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
仕様書状況コメント
{{SpecName('ES1')}}{{Spec2('ES1')}}初回定義。 JavaScript 1.2 で実装
{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ESDraft')}}
+ +

ブラウザー実装状況

+ + + +

{{Compat("javascript.functions.arguments.callee")}}

+ +

関連項目

+ + diff --git a/files/ja/web/javascript/reference/functions/arguments/caller/index.html b/files/ja/web/javascript/reference/functions/arguments/caller/index.html new file mode 100644 index 0000000000..3626d7644b --- /dev/null +++ b/files/ja/web/javascript/reference/functions/arguments/caller/index.html @@ -0,0 +1,56 @@ +--- +title: caller +slug: Web/JavaScript/Reference/Functions/arguments/caller +translation_of: Archive/Web/JavaScript/arguments.caller +--- +

 

+ +

{{ Obsolete_header() }}

+ +

{{ 英語版章題("Summary") }}

+ +

概要

+ +

現在実行している関数を呼び出した関数を示します。

+ + + + + + + + + + + +
arguments のプロパティ
実装されたバージョン:JavaScript 1.1, NES 2.0 +

JavaScript 1.3: 非推奨とする。JavaScript ??: Removed

+
+ +

{{ 英語版章題("Description") }}

+ +

説明

+ +

arguments.caller はもはや使用されていません。 代わりに関数オブジェクトの非標準の {{jsxref("Function.caller")}} プロパティが使えます。詳細はその説明を参照してください。

+ +

arguments.caller プロパティは関数本体の中でのみ利用可能です。

+ +

{{ 英語版章題("Examples") }}

+ +

+ +

次のコードは、関数の中で arguments.caller の値をチェックします。

+ +
function myFunc() {
+   if (arguments.caller == null) {
+      return ("The function was called from the top!");
+   } else
+      return ("This function's caller was " + arguments.caller);
+}
+
+ +

 

+ +

 

+ +

{{ languages( { "en": "en/JavaScript/Reference/Functions_and_function_scope/arguments/caller", "fr": "fr/R\u00e9f\u00e9rence_de_JavaScript_1.5_Core/Fonctions/arguments/caller", "pl": "pl/Dokumentacja_j\u0119zyka_JavaScript_1.5/Funkcje/arguments/caller" } ) }}

diff --git a/files/ja/web/javascript/reference/functions/arguments/index.html b/files/ja/web/javascript/reference/functions/arguments/index.html new file mode 100644 index 0000000000..4990f359bc --- /dev/null +++ b/files/ja/web/javascript/reference/functions/arguments/index.html @@ -0,0 +1,227 @@ +--- +title: arguments +slug: Web/JavaScript/Reference/Functions/arguments +tags: + - Functions + - JavaScript + - Namespace + - Reference + - arguments + - 名前空間 +translation_of: Web/JavaScript/Reference/Functions/arguments +--- +
{{JSSidebar("Functions")}}
+ +

arguments配列風 (Array-like) オブジェクトであり、関数に渡された引数の値を含んでおり、関数内からアクセスすることができます。

+ +
{{EmbedInteractiveExample("pages/js/functions-arguments.html")}}
+ + + +

解説

+ +
+

注: ES6 互換のコードを書く場合は、残余引数が推奨されます。

+
+ +
+

注: 「配列風」とは、 arguments が {{jsxref("Functions/arguments/length", "length")}} プロパティと 0 から始まる添字のプロパティを持っているものの、 {{JSxRef("Array")}} の組込みメソッド、例えば {{jsxref("Array.forEach", "forEach()")}} や {{jsxref("Array.map", "map()")}} を持っていないということです。詳しくは 解説の節を見てください。

+
+ +

arguments オブジェクトはすべての(アローではない)関数内で利用可能なローカル変数です。arguments オブジェクトを使うことにより、関数内で関数の引数を参照できます。このオブジェクトは、関数に渡された各引数に対する入力を含みます。最初の入力の添え字は 0 から始まります。

+ +

たとえば、もし関数に 3 つの引数が渡されたなら、次のようにその引数を参照できます。

+ +
arguments[0] // 1 番目の引数
+arguments[1] // 2 番目の引数
+arguments[2] // 3 番目の引数
+
+ +

引数を設定したり再代入したりすることもできます。

+ +
arguments[1] = 'new value';
+
+ +

arguments オブジェクトは {{jsxref("Array")}} ではありません。似ていますが、 Array のプロパティは {{jsxref("Array.length", "length")}} 以外ありません。たとえば、 {{jsxref("Array.pop", "pop()")}} メソッドはありません。

+ +

しかしながら、本当の Array に変換することはできます。

+ +
var args = Array.prototype.slice.call(arguments);
+// 配列リテラルを使用すると上記よりも短くなりますが、空の配列を作成します
+var args = [].slice.call(arguments);
+
+ +

arguments に限らず、配列様オブジェクトは ES2015 の {{jsxref("Array.from()")}} メソッドやスプレッド構文によって、本当の配列に変換することができます。

+ +
var args = Array.from(arguments);
+var args = [...arguments];
+
+ +

arguments オブジェクトは、あらかじめ定義された引数の数よりも多くの引数で呼び出される関数に便利です。このテクニックは Math.min() などの 可変数の引数を受け入れる関数に便利です。この例の関数は、任意の数の文字列が引数で、引数の中で一番長い文字列を返します。

+ +
function longestString() {
+  var longest = '';
+  for (var i=0; i < arguments.length; i++) {
+    if (arguments[i].length > longest.length) {
+      longest = arguments[i];
+    }
+  }
+  return longest;
+}
+
+ +

呼び出された関数に渡された引数を数えるために {{jsxref("Functions/arguments/length", "arguments.length")}} を使用することができます。関数が受け取る引数を数えたいのであれば、関数の {{jsxref("Function.length", "length")}} プロパティを調べてください。

+ +

arguments に対する typeof の使用

+ +

{{jsxref("Operators/typeof", "typeof")}} 演算子を arguments に対して使用すると、 'object' が返されます。

+ +
console.log(typeof arguments); // 'object' 
+ +

個々の引数の型は、 arguments に添字を使用して判断することができます。

+ +
console.log(typeof arguments[0]); // 最初の引数の型を返す
+ +

プロパティ

+ +
+
{{jsxref("Functions/arguments/callee", "arguments.callee")}}
+
個の引数が所属する、現在実行中の関数を参照します。厳格モードでは禁止されています。
+
{{jsxref("Functions/arguments/length", "arguments.length")}}
+
関数に渡された引数の数を示します。
+
{{jsxref("Functions/arguments/@@iterator", "arguments[@@iterator]")}}
+
新しい {{jsxref("Array/@@iterator", "Array iterator", "", 0)}} オブジェクトで、 arguments のそれぞれの要素の値を含みます。
+
+ +

+ +

複数の文字列を連結する関数を定義する

+ +

この例では、複数の文字列を連結する関数を定義します。この関数の唯一の仮引数は、連結する項目を区切る文字を指定する文字列です。この関数は次のように定義されます。

+ +
function myConcat(separator) {
+  let args = Array.prototype.slice.call(arguments, 1);
+  return args.join(separator);
+}
+ +

この関数へは好きな数だけ引数を渡すことができます。これはリスト中のそれぞれの引数を使用した文字列リストを返します。

+ +
// "red, orange, blue" を返します
+myConcat(', ', 'red', 'orange', 'blue');
+
+// "elephant; giraffe; lion; cheetah" を返します
+myConcat('; ', 'elephant', 'giraffe', 'lion', 'cheetah');
+
+// "sage. basil. oregano. pepper. parsley" を返します
+myConcat('. ', 'sage', 'basil', 'oregano', 'pepper', 'parsley');
+ +

HTML のリストを作る関数の定義

+ +

この例では、リストのための HTML を含む文字列を作る関数を定義します。この関数の第 1 引数には、順不同リスト (中黒付き) なら "u"、順序リスト (番号付き) なら "o" を指定します。関数は次のように定義します。

+ +
function list(type) {
+  var html = '<' + type + 'l><li>';
+  var args = Array.prototype.slice.call(arguments, 1);
+  html += args.join('</li><li>');
+  html += '</li></' + type + 'l>'; // end list
+  return html;
+}
+ +

この関数には任意の数の引数を渡すことができ、それぞれの引数を指定された型のリストに項目として追加します。例を示します。

+ +
var listHTML = list('u', 'One', 'Two', 'Three');
+
+/* listHTML の内容は以下のような文字列となります。
+"<ul><li>One</li><li>Two</li><li>Three</li></ul>"
+*/
+ +

残余引数、デフォルト引数、分割引数

+ +
+

arguments オブジェクトを 残余デフォルト分割引数と組み合わせて使用できます。

+
+ +
function foo(...args) {
+  return args;
+}
+foo(1, 2, 3); // [1, 2, 3]
+
+ +

厳格モードのコードでは、残余引数、デフォルト引数、分割引数があっても arguments オブジェクトの動作は変わりませんが、厳格モードでない場合は微妙な違いがあります。

+ +

厳格モードでは、 arguments オブジェクトは関数に残余引数、デフォルト引数、分割引数が渡されたかどうかにかかわらず同じ動作をします。すなわち、関数の本体で変数に新しい値を代入しても、 arguments オブジェクトには影響しません。また、 arguments オブジェクトに新しい変数を代入しても、変数の値には影響ありません。

+ +
+

注: "use strict"; ディレクティブを、残余引数、デフォルト引数、分割引数を受け付ける関数の本体に書くことはできません。そうすると、構文エラーが発生します。

+
+ +

厳格モードでない関数で、単純な引数のみを渡した場合 (すなわち、残余引数、デフォルト引数、分割引数ではない場合)、関数の本体で変数の値を新しい値にすると、 arguments オブジェクトと同期します。

+ +
function func(a) {
+  arguments[0] = 99; // arguments[0] を更新すると a も更新される
+  console.log(a);
+}
+func(10); // 99
+
+ +

および

+ +
function func(a) {
+  a = 99; // a を更新すると arguments[0] も更新される
+  console.log(arguments[0]);
+}
+func(10); // 99
+
+ +

それに対して、厳格モードでない関数で、残余引数、デフォルト引数、分割引数が渡されると、関数の本体で引数の変数に新しい値が代入されても、 arguments オブジェクトと同期されません。複雑な引数を持つ厳格モードでない関数の arguments オブジェクトは、関数が呼び出されたときに関数に渡された値を常に反映します (これは、渡される変数の型に関係なく、すべての厳格モードの関数の場合と同じ動作です)。

+ +
function func(a = 55) {
+  arguments[0] = 99; // arguments[0] を更新しても a は更新されない
+  console.log(a);
+}
+func(10); // 10
+ +

および

+ +
function func(a = 55) {
+  a = 99; // a を更新しても arguments[0] は更新されない
+  console.log(arguments[0]);
+}
+func(10); // 10
+
+ +

および

+ +
// デフォルト引数は追跡されません。
+function func(a = 55) {
+  console.log(arguments[0]);
+}
+func(); // undefined
+ +

仕様書

+ + + + + + + + + + + + +
仕様書
{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}
+ +

ブラウザーの互換性

+ + + +

{{Compat("javascript.functions.arguments")}}

+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/functions/arguments/length/index.html b/files/ja/web/javascript/reference/functions/arguments/length/index.html new file mode 100644 index 0000000000..cc8781a8c6 --- /dev/null +++ b/files/ja/web/javascript/reference/functions/arguments/length/index.html @@ -0,0 +1,124 @@ +--- +title: arguments.length +slug: Web/JavaScript/Reference/Functions/arguments/length +tags: + - arguments +translation_of: Web/JavaScript/Reference/Functions/arguments/length +--- +
{{jsSidebar("Functions")}}
+ +

arguments.length プロパティは、関数に渡された引数の数を含みます。

+ +

構文

+ +
arguments.length
+ +

説明

+ +

The arguments.length プロパティは、実際に関数に渡された引数の数を提供します。これは、定義されたパラメーターの数以上にも以下にもできます({{jsxref("Function.length")}} を見てください)。

+ +

+ +

arguments.length を使用する

+ +

この例では、2 つ以上の数を加算する関数を定義しています。

+ +
function adder(base /*, n2, ... */) {
+  base = Number(base);
+  for (var i = 1; i < arguments.length; i++) {
+    base += Number(arguments[i]);
+  }
+  return base;
+}
+
+ +

仕様

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
仕様ステータスコメント
{{SpecName('ES1')}}{{Spec2('ES1')}}初期定義。JavaScript 1.1 で実装。
{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ESDraft')}} 
+ +

ブラウザ実装状況

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
機能ChromeFirefox (Gecko)Internet ExplorerOperaSafari
基本サポート{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
機能AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基本サポート{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

関連項目

+ + diff --git a/files/ja/web/javascript/reference/functions/arrow_functions/index.html b/files/ja/web/javascript/reference/functions/arrow_functions/index.html new file mode 100644 index 0000000000..b178700bd9 --- /dev/null +++ b/files/ja/web/javascript/reference/functions/arrow_functions/index.html @@ -0,0 +1,405 @@ +--- +title: アロー関数 +slug: Web/JavaScript/Reference/Functions/Arrow_functions +tags: + - ECMAScript 2015 + - Functions + - Intermediate + - JavaScript + - Reference +translation_of: Web/JavaScript/Reference/Functions/Arrow_functions +--- +
{{jsSidebar("Functions")}}
+ +

アロー関数式は、より短く記述できる、通常の function 式の代替構文です。また、this, arguments, super, new.target を束縛しません。アロー関数式は、メソッドでない関数に最適で、コンストラクタとして使うことはできません。

+ +

{{EmbedInteractiveExample("pages/js/functions-arrow.html")}}

+ +

構文

+ +

基本的な構文

+ +
(param1, param2, …, paramN) => { statements }
+(param1, param2, …, paramN) => expression
+// 上記の式は、次の式と同等です: => { return expression; }
+
+// 引数が 1 つしかない場合、丸括弧 () の使用は任意です:
+(singleParam) => { statements }
+singleParam => { statements }
+
+// 引数がない場合、丸括弧を書かねばいけません:
+() => { statements }
+
+ +

高度な構文

+ +
// object リテラル式を返す場合は、本体を丸括弧 () で囲みます:
+params => ({foo: bar})
+
+// 残余引数デフォルト引数 をサポートしています
+(param1, param2, ...rest) => { statements }
+(param1 = defaultValue1, param2, …, paramN = defaultValueN) => {
+statements }
+
+// 引数リスト内の分割代入もサポートしています
+var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
+f(); // 6
+
+ +

説明

+ +

hacks.mozilla.org の "ES6 In Depth: Arrow functions" も参照してください。

+ +

2 つの理由から、アロー関数が導入されました。1 つ目の理由は関数を短く書きたいということで、2 つ目の理由は this を束縛したくない、ということです。

+ +

関数の短縮形

+ +
var elements = [
+  'Hydrogen',
+  'Helium',
+  'Lithium',
+  'Beryllium'
+];
+
+elements.map(function(element) {
+  return element.length;
+}); // このステートメントが返す配列: [8, 6, 7, 9]
+
+// 上記の通常の関数は、以下のアロー関数として記述できます
+elements.map((element) => {
+  return element.length;
+}); // [8, 6, 7, 9]
+
+// パラメータが一つしか無い場合、周囲の括弧を削除できます:
+elements.map(element => {
+  return element.length;
+}); // [8, 6, 7, 9]
+
+// アロー関数の唯一のステートメントが `return` の場合、 `return` を削除し
+// 周囲の波括弧も削除できます
+elements.map(element => element.length); // [8, 6, 7, 9]
+
+// この場合、必要なのは length property のみなので、分割パラメータを使用できます:
+// 文字列 `"length"` は取得したいプロパティに対応しますが
+// 明らかに特別でない `lengthFooBArX` は、任意の有効な変数名に
+// 変更可能な変数名です
+elements.map(({ "length": lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]
+
+// この分割パラメータの代入は、以下のように記述することも可能です。ただし、この例では、
+// 作成されたプロパティに `length` の値を代入していないことに注意して下さい。代わりに、
+// 変数 `length` のリテラル名自体が、オブジェクトから取得するプロパティとして使用されます。
+elements.map(({ length }) => length); // [8, 6, 7, 9]
+
+ +

this を束縛しない

+ +

アロー関数以前は、関数の呼び出し方法に応じて自身の this 値を定義していました

+ + + +

これは、オブジェクト指向プログラミングをする上で煩わしいということが分かりました。

+ +
function Person() {
+  // Person() のコンストラクタは、自分のインスタンスを `this` として定義する。
+  this.age = 0;
+
+  setInterval(function growUp() {
+    // 非 strict モードでは、growUp() 関数は `this` を
+    // グローバルオブジェクトとして定義する。
+    // (そこで grouUp()が実行されているため)
+    // Person() コンストラクタが定義した `this` とは違う。
+    this.age++;
+  }, 1000);
+}
+
+var p = new Person();
+ +

ECMAScript 3/5 では、この問題は this の値をスコープ内の変数に代入することで解決できました。

+ +
function Person() {
+  var that = this;
+  that.age = 0;
+
+  setInterval(function growUp() {
+    // このコールバックは、期待されるオブジェクトの値を
+    // `that` 変数で参照する。
+    that.age++;
+  }, 1000);
+}
+ +

あるいは、適切な this の値を対象の関数(上の例では growUp() 関数)に渡すように、束縛関数を作成することもできました。

+ +

アロー関数自身は this を持ちません。レキシカルスコープの this 値を使います。つまり、アロー関数内の this 値は通常の変数検索ルールに従います。このためスコープに this 値がない場合、その一つ外側のスコープで this 値を探します。

+ +

そのため、次のコードで setInterval に渡される関数の this の値は、外部関数の this と同じ値になります:

+ +
function Person(){
+  this.age = 0;
+
+  setInterval(() => {
+    this.age++; // |this| は person オブジェクトを適切に参照します。
+  }, 1000);
+}
+
+var p = new Person();
+ +

strict モードとの関連

+ +

this がレキシカルなもので与えられる場合、strict モードthis に関する規則は無視されます。

+ +
var f = () => { 'use strict'; return this; };
+f() === window; // またはグローバルオブジェクト
+ +

他の strict モードの規則は通常通り適用されます。

+ +

call や apply からの呼び出し

+ +

アロー関数は自身で this を持たないので、call()apply() メソッドは引数しか渡せません。this は無視されます。

+ +
var adder = {
+  base: 1,
+
+  add: function(a) {
+    var f = v => v + this.base;
+    return f(a);
+  },
+
+  addThruCall: function(a) {
+    var f = v => v + this.base;
+    var b = {
+      base: 2
+    };
+
+    return f.call(b, a);
+  }
+};
+
+console.log(adder.add(1));         // 2 を出力する
+console.log(adder.addThruCall(1)); // やはり 2 を出力する
+ +

arguments を束縛しない

+ +

アロー関数は自身で arguments オブジェクトを持ちません。そのため、この例では、arguments は囲っているスコープでの同名変数への参照にすぎません。

+ +
var arguments = [1, 2, 3];
+var arr = () => arguments[0];
+
+arr(); // 1
+
+function foo(n) {
+  var f = () => arguments[0] + n; // foo は arguments を暗黙的に束縛している。arguments[0] は n である。
+  return f();
+}
+
+foo(3); // 6
+
+ +

多くの場合、残余引数arguments オブジェクトの代わりに使えます。

+ +
function foo(n) {
+  var f = (...args) => args[0] + n;
+  return f(10);
+}
+
+foo(1); // 11
+ +

メソッドとして使われるアロー関数

+ +

前に述べたように、アロー関数式は非メソッド型の関数に最もよく合っています。これをメソッドとして使った時のことを見てみましょう:

+ +
'use strict';
+
+var obj = {
+  i: 10,
+  b: () => console.log(this.i, this),
+  c: function() {
+    console.log(this.i, this);
+  }
+};
+
+obj.b(); // prints undefined, Window {...} (or the global object)
+obj.c(); // prints 10, Object {...}
+
+ +

アロー関数は自身の this を持ちません。{{jsxref("Object.defineProperty()")}} を使う例です。

+ +
'use strict';
+var obj = {
+  a: 10
+};
+
+Object.defineProperty(obj, 'b', {
+  get: () => {
+    console.log(this.a, typeof this.a, this); // undefined 'undefined' Window {...} (or the global object)
+    return this.a + 10; // represents global object 'Window', therefore 'this.a' returns 'undefined'
+  }
+});
+
+ +

new 演算子の使用

+ +

アロー関数はコンストラクタとして使用できず、new と共に使うとエラーになります。

+ +
var Foo = () => {};
+var foo = new Foo(); // TypeError: Foo is not a constructor
+ +

prototype プロパティの使用

+ +

アロー関数には prototype プロパティはありません。

+ +
var Foo = () => {};
+console.log(Foo.prototype); // undefined
+
+ +

yield キーワードの使用

+ +

{{jsxref("Operators/yield", "yield")}} キーワードはアロー関数内で使用できません(内部で入れ子になった関数が許可されている場合を除く)。結果として、アロー関数はジェネレーターとして使用できません。

+ +

関数の Body 部分

+ +

アロー関数は、「簡潔文体 (concise body)」か、もしくはより一般的な「ブロック文体 (block body) 」のどちらかを使用することができます。

+ +

簡潔文体 (concise body) においては、単一の式だけが記述できるので、その式が明示的に return される値となります。しかし、ブロック文体においては、自動的に return はされないので、明示的に return 文を使用する必要があります。

+ +
var func = x => x * x;
+// 簡潔構文の場合、明示せずとも"return" されます
+var func = (x, y) => { return x + y; };
+// ブロック文体では、明示的に "return" を宣言する必要があります
+
+ +

オブジェクトリテラルを返す

+ +

短縮構文 params => {object:literal} を使ってオブジェクトリテラルを返そうとしても、期待通りに動作しないことに注意しましょう。

+ +
var func = () => { foo: 1 };
+// 呼び出した func() は undefined を返す!
+
+var func = () => { foo: function() {} };
+// SyntaxError: function 文には名前が必要
+
+ +

これは、括弧 ({}) 内のコードが文の列として構文解析されてしまっているからです(つまり、foo はオブジェクトリテラル内のキーでなく、ラベルとして扱われています)。

+ +

オブジェクトリテラルは括弧で囲むのを忘れないでください。

+ +
var func = () => ({ foo: 1 });
+ +

改行

+ +

アロー関数には括弧とアロー(矢印)の間に改行を入れられません。

+ +
var func = ()
+           => 1;
+// SyntaxError: expected expression, got '=>'
+ +

しかし、下記の例は、アローの後に改行を入れたり、括弧を使って、更に引数の内側で改行を使うことで、綺麗で柔らかなコードに修正できることを確認しています。引数の途中に改行を入れることもできます。

+ +
var func = (a, b, c) =>
+  1;
+
+var func = (a, b, c) => (
+  1
+);
+
+var func = (a, b, c) => {
+  return 1
+};
+
+var func = (
+  a,
+  b,
+  c
+) => 1;
+
+// no SyntaxError thrown
+ +

解析の順序

+ +

アロー関数内のアロー(矢印)はオペレーターではないですが、アロー関数は通常の関数と異なり、オペレーターを引き継いだ特別な解析ルールを持ちます。

+ +
let callback;
+
+callback = callback || function() {}; // ok
+
+callback = callback || () => {};
+// SyntaxError: invalid arrow-function arguments
+
+callback = callback || (() => {});    // ok
+
+ +

さらなる例

+ +
// 空のアロー関数は undefined を返します
+let empty = () => {};
+
+(() => 'foobar')();
+// "foobar" を返します
+// (this is an Immediately Invoked Function Expression)
+
+var simple = a => a > 15 ? 15 : a;
+simple(16); // 15
+simple(10); // 10
+
+let max = (a, b) => a > b ? a : b;
+
+// 簡単な配列のフィルターリング、マッピング等
+
+var arr = [5, 6, 13, 0, 1, 18, 23];
+
+var sum = arr.reduce((a, b) => a + b);
+// 66
+
+var even = arr.filter(v => v % 2 == 0);
+// [6, 0, 18]
+
+var double = arr.map(v => v * 2);
+// [10, 12, 26, 0, 2, 36, 46]
+
+// さらに簡潔な promise チェーン
+promise.then(a => {
+  // ...
+}).then(b => {
+  // ...
+});
+
+// 見た目に解析が簡単な引数なしのアロー関数
+setTimeout( () => {
+  console.log('I happen sooner');
+  setTimeout( () => {
+    // deeper code
+    console.log('I happen later');
+  }, 1);
+}, 1);
+
+ +

仕様

+ + + + + + + + + + +
仕様書
{{SpecName('ESDraft', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}
+ +

ブラウザーの実装状況

+ +
+ + +

{{Compat("javascript.functions.arrow_functions")}}

+
+ +

関連項目

+ + diff --git a/files/ja/web/javascript/reference/functions/default_parameters/index.html b/files/ja/web/javascript/reference/functions/default_parameters/index.html new file mode 100644 index 0000000000..f671389fba --- /dev/null +++ b/files/ja/web/javascript/reference/functions/default_parameters/index.html @@ -0,0 +1,225 @@ +--- +title: デフォルト引数 +slug: Web/JavaScript/Reference/Functions/Default_parameters +tags: + - ECMAScript 2015 + - Functions + - JavaScript + - Language feature + - 言語機能 + - 関数 +translation_of: Web/JavaScript/Reference/Functions/Default_parameters +--- +
{{jsSidebar("Functions")}}
+ +

関数のデフォルト引数 は、関数に値が渡されない場合や undefined が渡される場合に、デフォルト値で初期化される形式上の引数を指定できます。

+ +
{{EmbedInteractiveExample("pages/js/functions-default.html")}}
+ + + +

構文

+ +
function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) {
+   
+}
+
+ +

解説

+ +

JavaScript では、関数の引数は、指定しなければ {{jsxref("undefined")}} になります。しかし、別な既定値を設定すると有用な場合がよくあります。そのような場合に、デフォルト引数が役立ちます。

+ +

以前は、既定値を設定するための一般的な方法は、関数の本体で引数の値を検査し、undefined であった場合に値を代入することでした。

+ +

次の例では、b の値を指定せずに multiply を呼び出した場合、a * b を評価するときに b の値が undefined となり、multiplyNaN を返します。

+ +
function multiply(a, b) {
+  return a * b
+}
+
+multiply(5, 2)  // 10
+multiply(5)     // NaN !
+
+ +

こうなることを防ぐためには、2行目で使われているように、multiply が 1 つだけの引数で呼び出された場合に b1 に設定します。

+ +
function multiply(a, b) {
+  b = (typeof b !== 'undefined') ?  b : 1
+  return a * b
+}
+
+multiply(5, 2)  // 10
+multiply(5)     // 5
+
+ +

ES2015 のデフォルト引数を用いると、関数本体内のチェックはもはや必要なくなります。関数の先頭で 1b の既定値として設定するだけです。

+ +
function multiply(a, b = 1) {
+  return a * b
+}
+
+multiply(5, 2)          // 10
+multiply(5)             // 5
+multiply(5, undefined)  // 5
+
+ +

+ +

undefined とその他の falsy な値を渡した場合

+ +

この例の 2番目の呼び出しでは、第1引数で明示的に (null やその他の {{glossary("falsy")}} な値ではなく) undefined を設定していても、num 引数の値は既定値のままになります

+ +
function test(num = 1) {
+  console.log(typeof num)
+}
+
+test()           // 'number' (num は 1 に設定)
+test(undefined)  // 'number' (こちらも num は 1 に設定)
+
+// 他の falsy な値での検査
+test('')         // 'string' (num は '' に設定)
+test(null)       // 'object' (num は null に設定)
+
+ +

呼び出し時の評価

+ +

デフォルト引数は呼び出し時に評価されるので、Python などと異なり、関数が呼ばれる度に新しいオブジェクトが生成されます。

+ +
function append(value, array = []) {
+  array.push(value)
+  return array
+}
+
+append(1)  //[1]
+append(2)  //[1, 2] ではなく [2]
+
+ +

これは、関数と変数にも適用されます。

+ +
function callSomething(thing = something()) {
+  return thing
+}
+
+let numberOfTimesCalled = 0
+function something() {
+  numberOfTimesCalled += 1
+  return numberOfTimesCalled
+}
+
+callSomething()  // 1
+callSomething()  // 2
+
+ +

前の引数を後のデフォルト引数で利用可能

+ +

前に (左側で) 定義された引数は、その後のデフォルト引数で利用することができます。

+ +
function greet(name, greeting, message = greeting + ' ' + name) {
+  return [name, greeting, message]
+}
+
+greet('David', 'Hi')                     // ["David", "Hi", "Hi David"]
+greet('David', 'Hi', 'Happy Birthday!')  // ["David", "Hi", "Happy Birthday!"]
+
+ +

この機能はこの、いくつもの極端な例を扱うデモに近いかもしれません。

+ +
function go() {
+  return ':P'
+}
+
+function withDefaults(a, b = 5, c = b, d = go(), e = this,
+                      f = arguments, g = this.value) {
+  return [a, b, c, d, e, f, g]
+}
+
+function withoutDefaults(a, b, c, d, e, f, g) {
+  switch (arguments.length) {
+    case 0:
+      a;
+    case 1:
+      b = 5;
+    case 2:
+      c = b;
+    case 3:
+      d = go();
+    case 4:
+      e = this;
+    case 5:
+      f = arguments;
+    case 6:
+      g = this.value;
+    default:
+  }
+  return [a, b, c, d, e, f, g];
+}
+
+withDefaults.call({value: '=^_^='});
+// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="]
+
+withoutDefaults.call({value: '=^_^='});
+// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="]
+
+ +

関数本体の内部で定義された関数

+ +

関数の本体の中で宣言された関数は、外側の関数のデフォルト引数の中で参照することができません。これを行おうとすると、{{jsxref("ReferenceError")}} が発生します。

+ +

デフォルト引数は、常に最初に実行され、関数本体内の関数宣言は、その後に評価されるからです。

+ +
// 動作しません。ReferenceError が発生します。
+function f(a = go()) {
+  function go() { return ':P' }
+}
+
+ +

デフォルト引数の後の既定値なしの引数

+ +

引数は左から右に設定され、後の引数に既定値がなくてもデフォルト引数を上書きします。

+ +
function f(x = 1, y) {
+  return [x, y]
+}
+
+f()   // [1, undefined]
+f(2)  // [2, undefined]
+
+ +

既定値のある分割代入の引数

+ +

既定値の代入を、{{jsxref("Operators/Destructuring_assignment", "分割代入", "", 1)}}表記で行うことができます。

+ +
function f([x, y] = [1, 2], {z: z} = {z: 3}) {
+  return x + y + z
+}
+
+f()  // 6
+ +

仕様書

+ + + + + + + + + + + + +
仕様書
{{SpecName('ESDraft', '#sec-function-definitions', 'Function Definitions')}}
+ +

ブラウザーの互換性

+ +
+ + +

{{Compat("javascript.functions.default_parameters")}}

+
+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/functions/get/index.html b/files/ja/web/javascript/reference/functions/get/index.html new file mode 100644 index 0000000000..bd036a5733 --- /dev/null +++ b/files/ja/web/javascript/reference/functions/get/index.html @@ -0,0 +1,176 @@ +--- +title: ゲッター +slug: Web/JavaScript/Reference/Functions/get +tags: + - ECMAScript 2015 + - ECMAScript 5 + - Functions + - JavaScript + - Language feature + - 言語機能 + - 関数 +translation_of: Web/JavaScript/Reference/Functions/get +--- +
{{jsSidebar("Functions")}}
+ +

get 構文は、オブジェクトのプロパティを関数に結びつけ、プロパティが参照された時に関数が呼び出されるようにします。

+ +
{{EmbedInteractiveExample("pages/js/functions-getter.html")}}
+ + + +

構文

+ +
{get prop() { ... } }
+{get [expression]() { ... } }
+ +

引数

+ +
+
prop
+
与えられた関数に結び付けられるプロパティの名前
+
expression
+
ECMAScript 6 より、算出されたプロパティ名 (computed property name) の式を使用して関数に結び付けることもできます。
+
+ +

解説

+ +

時として、動的に計算した値を返すプロパティにアクセスを許可したほうが望ましい場合や、明示的なメソッドを呼び出すことなく内部変数に状態を反映させたい場合があります。 JavaScript では、ゲッターを使ってこれを行うことが可能です。

+ +

プロパティに結び付けられたゲッターと、実際に値を持つプロパティを同時に持つことはできませんが、ゲッターとセッターを組み合わせて使用し、一種の擬似プロパティを作成することはできます。

+ +

get 構文を使用する際の注意事項:

+ + + +

+ +

オブジェクト初期化時における新しいオブジェクトのゲッターの定義

+ +

以下の例では、オブジェクト obj の擬似プロパティとして、 log 内の最後の配列アイテムを返す latest プロパティを作成します。

+ +
const obj = {
+  log: ['example','test'],
+  get latest() {
+    if (this.log.length === 0) return undefined;
+    return this.log[this.log.length - 1];
+  }
+}
+console.log(obj.latest); // "test"
+
+ +

latest に値を代入しようとしても、変更はされないことに注意して下さい。

+ +

delete 演算子によるゲッターの削除

+ +

ゲッターを削除したい場合は、 {{jsxref("Operators/delete", "delete")}} を使用します。

+ +
delete obj.latest;
+
+ +

既存のオブジェクトへの defineProperty を使用したゲッターの定義

+ +

任意のタイミングで既存のオブジェクトにゲッターを追加するには、 {{jsxref("Object.defineProperty()")}} を使用します。

+ +
const o = {a: 0};
+
+Object.defineProperty(o, 'b', { get: function() { return this.a + 1; } });
+
+console.log(o.b) // getter を実行。a + 1 を算出する (結果は 1)
+ +

算出されたプロパティ名の使用

+ +
const expr = 'foo';
+
+const obj = {
+  get [expr]() { return 'bar'; }
+};
+
+console.log(obj.foo); // "bar"
+ +

スマート / 自己書き換え / 怠惰なゲッター

+ +

ゲッターはオブジェクトのプロパティを定義する手段を提供しますが、アクセスされるまでプロパティの値を計算しません。ゲッターは値を計算するコストを、値が必要になるまで先送りします。値が必要でなければ、そのコストを負担しません。

+ +

プロパティの値の計算を先送りしたり後のアクセスのためにキャッシュするための付加的な最適化技術が、スマート (またはメモ化) ゲッターです。初めてゲッターにアクセスされたときに、値を計算してキャッシュします。以降のアクセスでは再計算せずに、キャッシュした値を返します。これは次のような状況で役に立ちます。

+ + + +
+

値が変わると見込まれるプロパティで、怠惰なゲッターを使用してはいけません。このようなゲッターは値を再計算しないためです。

+
+ +

以下の例では、オブジェクトが自身のプロパティとしてゲッターを持っています。プロパティを取得すると、プロパティはオブジェクトから削除された後に再追加されますが、このとき暗黙的にデータプロパティとして追加されます。最終的に、値が返されます。

+ +
get notifier() {
+  delete this.notifier;
+  return this.notifier = document.getElementById('bookmarked-notification-anchor');
+},
+ +

Firefox のコードでは、 XPCOMUtils.jsm コードモジュールもご覧ください。これは defineLazyGetter() 関数を定義しています。

+ +

getdefineProperty

+ +

get キーワードと {{jsxref("Object.defineProperty()")}} の使用は似た結果になりますが、 {{jsxref("classes")}} 上で使用する場合は微妙な違いがあります。

+ +

get を使用した場合は、プロパティはインスタンスのプロトタイプに定義されるのに対し、 {{jsxref("Object.defineProperty()")}} を使用した場合は、プロパティは適用されたインスタンスに定義されます。

+ +
class Example {
+  get hello() {
+    return 'world';
+  }
+}
+
+const obj = new Example();
+console.log(obj.hello);
+// "world"
+
+console.log(Object.getOwnPropertyDescriptor(obj, 'hello'));
+// undefined
+
+console.log(
+  Object.getOwnPropertyDescriptor(
+    Object.getPrototypeOf(obj), 'hello'
+  )
+);
+// { configurable: true, enumerable: false, get: function get hello() { return 'world'; }, set: undefined }
+ +

仕様書

+ + + + + + + + + + + + +
仕様書
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}
+ +

ブラウザーの互換性

+ + + +

{{Compat("javascript.functions.get")}}

+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/functions/index.html b/files/ja/web/javascript/reference/functions/index.html new file mode 100644 index 0000000000..a9e3cee514 --- /dev/null +++ b/files/ja/web/javascript/reference/functions/index.html @@ -0,0 +1,575 @@ +--- +title: 関数 +slug: Web/JavaScript/Reference/Functions +tags: + - Function + - Functions + - Guide + - JavaScript + - Parameter + - parameters +translation_of: Web/JavaScript/Reference/Functions +--- +
{{jsSidebar("Functions")}}
+ +

一般的に言うと、関数とは外部 (再帰の場合は内部) から 呼ばれる ことのできる「サブプログラム」です。プログラムそのもののように、関数は{{ 訳語("関数本体", "function body") }}と呼ばれる連続した文で構成されます。値を関数に 渡す 事ができ、関数は値を返す事ができます。

+ +

JavaScript において、関数は第一級オブジェクトです。すなわち、関数はオブジェクトであり、他のあらゆるオブジェクトと同じように操作したり渡したりする事ができます。具体的には、関数は Function オブジェクトです。

+ +

より詳細な例や解説については、JavaScript の関数のガイドを参照してください。

+ +

解説

+ +

JavaScript における全ての関数は、実際には Function オブジェクトです。Function オブジェクトのプロパティとメソッドについての情報は {{jsxref("Function")}} をご覧ください。

+ +

初期値以外の値を返すためには、返す値を指定する return 文が関数内になくてはなりません。return 文を持たない関数は初期値を返します。new キーワードとともに constructor が呼び出された場合、その this パラメータが初期値となります。それ以外の全ての関数がデフォルトで返す値は {{jsxref("undefined")}} です。

+ +

関数の仮引数 (パラメータ) には、関数呼び出しにおいて実引数 (アーギュメント) が渡されます。実引数は、関数に「値渡し」されます: 関数の中で引数の値を変更しても、その変更はグローバルスコープもしくは呼び出し元の関数内には反映されません。オブジェクト参照も「値」ですが、こちらは特別です: 参照されているオブジェクトのプロパティを関数の中で変更すると、次の例にあるように、その変更を関数の外部から見ることができます:

+ +
 /* 関数 'myFunc' を宣言 */
+function myFunc(theObject) {
+  theObject.brand = "Toyota";
+}
+
+/*
+ * 変数 'mycar' を宣言
+ * 新しいオブジェクトの生成と初期化
+ * 'mycar' への参照をオブジェクトに代入
+ */
+var mycar = {
+  brand: "Honda",
+  model: "Accord",
+  year: 1998
+};
+
+/* 'Honda' を出力 */
+console.log(mycar.brand);
+
+/* オブジェクト参照を関数に渡す */
+myFunc(mycar);
+
+/*
+ * オブジェクトの 'brand' プロパティの値は関数によって変更されたので
+ * 'Toyota' と出力される
+ */
+console.log(mycar.brand);
+
+ +

this キーワードは現在実行中の関数を参照しません。よって、関数内部であっても、名前によって Function オブジェクトを参照しなければなりません。

+ +

関数を定義する

+ +

関数を定義するのにはいくつかの方法があります。

+ +

関数宣言 (function 文)

+ +

関数を宣言するための特殊な構文があります。(詳細は function 文を参照)

+ +
function name([param[, param[, ... param]]]) {
+   statements
+}
+
+ +
+
name
+
関数名。
+
+ +
+
param
+
関数に渡される引数の名前です。
+
+ +
+
statements
+
関数の本体を構成する文。
+
+ +

関数式 (function 演算子)

+ +

関数式は、関数宣言と似ており、同じ構文を持っています (詳細は function 演算子を参照)。関数式はより大きな式の一部になることもあります。「名前付き」の関数式を定義することもできます(例えばその名前はコールスタック内で使われるかもしれません)し、「無名の」関数式を定義することもできます。関数式はスコープの開始時に「巻き上げ」られないので、コード内でそれらが登場するより前に使用することはできません。

+ +
function [name]([param[, param[, ... param]]]) {
+   statements
+}
+
+ +
+
name
+
関数名。省略する事ができ、その場合関数は無名関数と見なされます。
+
+ +
+
param
+
関数に渡される引数の名前です。
+
statements
+
関数の本体を構成する文。
+
+ +

以下は無名の関数式(名前が使われていない)の例です。

+ +
var myFunction = function() {
+    statements
+}
+ +

名前付きの関数式を作るため、定義の中で名前を提供することも可能です。

+ +
var myFunction = function namedFunction(){
+    statements
+}
+
+ +

名前付きの関数式を作ることのメリットの 1 つは、エラーに遭遇したとき、スタックトレースがその関数の名前を含めるため、エラーの発生源をより容易に特定できるということです。

+ +

ここまで見てきたように、どちらの例も function キーワードから開始されていません。function から開始せずに関数を含んでいる文が関数式です。

+ +

関数を一度だけ使うときの一般的なパターンが {{glossary("IIFE", "IIFE (Immediately Invokable Function Expression)")}} です。

+ +
(function() {
+    statements
+})();
+ +

即時関数は、関数を宣言した直後に実行する関数式です。

+ +

ジェネレーター関数宣言 (function* 文)

+ +

ジェネレーター関数の宣言のための特別な構文です(詳細は {{jsxref('Statements/function*', 'function* 文')}} を参照してください)。

+ +
function* name([param[, param[, ... param]]]) {
+   statements
+}
+
+ +
+
name
+
関数名。
+
+ +
+
param
+
関数に渡される引数の名前です。
+
+ +
+
statements
+
関数の本体を構成する文。
+
+ +

ジェネレーター関数式 (function* 演算子)

+ +

ジェネレーター関数式は、ジェネレーター関数宣言と似ており、同じ構文を持っています (詳細は {{jsxref('Operators/function*', 'function* 演算子')}} を参照してください)。

+ +
function* [name]([param[, param[, ... param]]]) {
+   statements
+}
+
+ +
+
name
+
関数名。省略する事ができ、その場合関数は無名関数と見なされます。
+
+ +
+
param
+
関数に渡される引数の名前です。
+
statements
+
関数の本体を構成する文。
+
+ +

アロー関数式 (=>)

+ +

アロー関数式は短縮構文を持ち、また関数の this 値を語彙的に束縛します (詳細はアロー関数を参照):

+ +
([param[, param]]) => {
+   statements
+}
+
+param => expression
+
+ +
+
param
+
引数の名前。引数が 0 個の場合は () で示すことが必要です。引数が 1 個の場合のみ、丸括弧は必須ではありません。(例えば foo => 1)
+
statements または expression
+
複数の文は中括弧で括らなければなりません。単一の式では、中括弧は必須ではありません。式は、関数の暗黙的な戻り値でもあります。
+
+ +

Function コンストラクタ

+ +
+

メモ: Function コンストラクターによる関数の生成は推奨されません。これは、文字列として関数本体が必要で、JS エンジンによる最適化を妨げたり、他の問題を引き起こしたりする場合があるためです。

+
+ +

他の全てのオブジェクトと同じように、new 演算子を使って {{jsxref("Function")}} オブジェクトを作成する事ができます。

+ +
new Function (arg1, arg2, ... argN, functionBody)
+
+ +
+
arg1, arg2, ... argN
+
関数で仮引数名として使われる、0 個以上の名前。それぞれが、妥当な JavaScript 識別子に相当する文字列、もしくはそういった文字列のカンマで分割されたリストでなくてはなりません。
+
+ +
+
functionBody
+
関数定義を構成する JavaScript 文を含む文字列。
+
+ +

Function コンストラクタを関数として (new 演算子を使わずに) 呼び出しても、コンストラクタとして呼び出すのと同じ効果があります。

+ +

GeneratorFunction コンストラクタ

+ +
+

メモ: GeneratorFunction はグローバルオブジェクトではありませんが、ジェネレーター関数のインスタンスから得ることができます(詳細は {{jsxref("GeneratorFunction")}} を参照してください)。

+
+ +
+

メモ: GeneratorFunction コンストラクタによる関数の生成は推奨されません。これは、文字列として関数本体が必要で、JS エンジンによる最適化を妨げたり、他の問題を引き起こしたりする場合があるためです。

+
+ +

他の全てのオブジェクトと同じように、new 演算子を使って {{jsxref("GeneratorFunction")}} オブジェクトを作成する事ができます。

+ +
new GeneratorFunction (arg1, arg2, ... argN, functionBody)
+
+ +
+
arg1, arg2, ... argN
+
関数で仮引数名として使われる、0 個以上の名前。それぞれが、妥当な JavaScript 識別子に相当する文字列、もしくはそういった文字列のカンマで分割されたリストでなくてはなりません。例えば "x" 、"theValue"、もしくは "a,b" などです。
+
+ +
+
functionBody
+
関数定義を構成する JavaScript 文を含む文字列。
+
+ +

Function コンストラクタを関数として (new 演算子を使わずに) 呼び出しても、コンストラクタとして呼び出すのと同じ効果があります。

+ +

関数の引数

+ +

デフォルト引数

+ +

関数のデフォルト引数は、関数に値が渡されない場合や undefined が渡される場合に、デフォルト値で初期化される形式上の引数を指定できます。詳細はデフォルト引数を参照してください。

+ +

Rest parameters

+ +

rest parameters とは、不特定多数の引数を配列として受け取る構文です。詳細は rest parameters を参照してください。

+ +

arguments オブジェクト

+ +

arguments オブジェクトを使って、関数内部で関数の引数を参照することができます。arguments を参照してください。

+ + + +

メソッドを定義する

+ +

getter と setter 関数

+ +

新しいプロパティの追加をサポートする、どの標準ビルトインオブジェクトあるいはユーザー定義オブジェクトにも、getter(accessor メソッド)や setter (mutator メソッド)を定義することができます。getter と setter を定義するための構文は、オブジェクトリテラル構文を使用します。

+ +
+
get
+
+

オブジェクトのプロパティを、そのプロパティが検索されたときに呼び出される関数に束縛します。

+
+
set
+
オブジェクトのプロパティを、そのプロパティに代入しようとしたときに呼び出される関数に束縛します。
+
+ +

メソッド定義構文

+ +

ECMAScript 2015 からは、独自のメソッドを、getter と setter に似た、より短い構文で定義することができます。詳細はメソッド定義を参照してください。

+ +
var obj = {
+  foo() {},
+  bar() {}
+};
+ +

コンストラクタか関数宣言か関数式か

+ +

以下のものを比較してみて下さい。

+ +

Function コンストラクタによって定義され、変数 multiply に代入された関数:

+ +
var multiply = new Function('x', 'y', 'return x * y');
+ +

multiply と命名された関数の 関数宣言:

+ +
function multiply(x, y) {
+   return x * y;
+} // ここにセミコロンは必要ありません
+
+ +

変数 multiply に代入された、無名関数の関数式:

+ +
var multiply = function(x, y) {
+   return x * y;
+};
+
+ +

変数 multiply に代入された、func_name と命名された関数式:

+ +
var multiply = function func_name(x, y) {
+   return x * y;
+};
+
+ +

相違点

+ +

これらは全ておおよそ同じ働きをしますが、いくつか微妙に異なる点があります。

+ +

関数名と関数が代入された変数の間には違いがあります。関数名は変える事ができませんが、関数が代入された変数は再代入する事ができます。関数名は関数本体の内部でのみ使用する事ができます。関数本体の外側でそれを使用しようとするとエラー (その関数名がそれより前に var 文によって宣言されていれば undefined ) になります。例えば、

+ +
var y = function x() {};
+alert(x); // エラーを投げる
+
+ +

関数名は Function の toString メソッドによってシリアライズしたときにも現れます。

+ +

一方、関数が代入された変数はそのスコープ内でのみ有効で、そのスコープは関数が宣言されたスコープを含んでいる事が保証されています。

+ +

4 つめの例にあるように、関数名はその関数が代入される変数と違っていても構いません。お互いの間に関連性は有りません。関数宣言は同時にその関数名と同じ名前の変数を作成します。よって、関数式で定義されたものと違って、関数宣言で定義された関数は定義されたスコープ内でその名前によってアクセスできます。

+ +

new Function によって定義された関数は関数名を持ちません。しかし、JavaScript エンジンの SpiderMonkey では、その関数をシリアライズされた形式にすると "anonymous" という名前を持っているかのように表示されます。例えば、alert(new Function()) はこのように出力されます。

+ +
function anonymous() {
+}
+
+ +

この関数は実際には名前を持っていないので、anonymous は関数内部でアクセスできる変数ではありません。例えば、次の文はエラーになります。

+ +
var foo = new Function("alert(anonymous);");
+foo();
+
+ +

関数式や Function コンストラクタで定義されたものとは違い、関数宣言で定義された関数は、関数自体が宣言される前に使用する事ができます。例えば、

+ +
foo(); // FOO! とアラートされる
+function foo() {
+   alert('FOO!');
+}
+
+ +

関数式で定義された関数は現在のスコープを継承します。つまり、関数がクロージャを形成します。一方、Function コンストラクタで定義された関数は (あらゆる関数が継承する) グローバルスコープ以外はどんなスコープも継承しません。

+ +
/*
+ * Declare and initialize a variable 'p' (global)
+ * and a function 'myFunc' (to change the scope) inside which
+ * declare a varible with same name 'p' (current) and
+ * define three functions using three different ways:-
+ *     1. function declaration
+ *     2. function expression
+ *     3. function constructor
+ * each of which will log 'p'
+ */
+var p = 5;
+function myFunc() {
+    var p = 9;
+
+    function decl() {
+        console.log(p);
+    }
+    var expr = function() {
+        console.log(p);
+    };
+    var cons = new Function('\tconsole.log(p);');
+
+    decl();
+    expr();
+    cons();
+}
+myFunc();
+
+/*
+ * Logs:-
+ * 9  - for 'decl' by function declaration (current scope)
+ * 9  - for 'expr' by function expression (current scope)
+ * 5  - for 'cons' by Function constructor (global scope)
+ */
+
+ +

関数式と関数宣言で定義された関数は一度しか解析されませんが、Function コンストラクタで定義された関数はそうではありません。つまり、Function コンストラクタに渡された関数本体を表す文字列が、評価されるたびに必ず解析されます。関数式は毎回クロージャを作成しますが、関数本体は再解析されないので、"new Function(...)" よりは関数式の方がまだ高速です。したがって Function コンストラクタはできる限り避けるべきでしょう。

+ +

ただし、Function コンストラクタの文字列を解析することで生成された関数内で入れ子にされている関数式や関数宣言は、繰り返し解析されないことに注意してください。例えば:

+ +
var foo = (new Function("var bar = \'FOO!\';\nreturn(function() {\n\talert(bar);\n});"))();
+foo(); // 関数本体の文字列で "function() {\n\talert(bar);\n}" の部分は再解析されません
+ +

関数宣言はとても簡単に (しばしば意図せずに) 関数式に変化します。関数宣言は以下のような時には関数宣言ではなくなります。

+ + + +
var x = 0;               // ソース要素
+if (x === 0) {           // ソース要素
+   x = 10;               // ソース要素ではない
+   function boo() {}     // ソース要素ではない
+}
+function foo() {         // ソース要素
+   var y = 20;           // ソース要素
+   function bar() {}     // ソース要素
+   while (y === 10) {    // ソース要素
+      function blah() {} // ソース要素ではない
+      y++;               // ソース要素ではない
+   }
+}
+
+ +

+ +
// 関数宣言
+function foo() {}
+
+// 関数式
+(function bar() {})
+
+// 関数式
+x = function hello() {}
+
+
+if (x) {
+   // 関数式
+   function world() {}
+}
+
+
+// 関数宣言
+function a() {
+   // 関数宣言
+   function b() {}
+   if (0) {
+      // 関数式
+      function c() {}
+   }
+}
+
+ +

ブロックレベル関数

+ +

ES2015 で始まった strict モードでは、ブロック内の関数はそのブロックに新しいスコープを形成します。ES2015 より前では、ブロックレベル関数は strict モードでは禁止されています。

+ +
'use strict';
+
+function f() {
+  return 1;
+}
+
+{
+  function f() {
+    return 2;
+  }
+}
+
+f() === 1; // true
+
+// 非 strict モードでは f() === 2
+
+ +

非 strict コードにおけるブロックレベル関数

+ +

一言、使わないでください。

+ +

非 strict コードでは、ブロック内の関数宣言は奇妙な動作をします。次の例を見てください。

+ +
if (shouldDefineZero) {
+   function zero() {     // 危険: 互換性リスク
+      console.log("This is zero.");
+   }
+}
+
+ +

ES2015 では shouldDefineZero が false の場合、このブロックが実行されることはないので、zero は決して定義されないとされています。しかし、これは標準において新しいパーツです。歴史的には、このことは仕様とならないまま残されていました。いくつかのブラウザーでは、ブロックが実行されてもされなくても、zero を定義したでしょう。

+ +

strict モードでは、ES2015 をサポートする全てのブラウザーは、これを同じように扱います。zeroshouldDefineZero が true の場合のみ定義され、かつ if ブロックのスコープに限られます。

+ +

条件付きで関数を定義するより安全な方法は、変数に関数式を代入することです。

+ +
var zero;
+if (shouldDefineZero) {
+   zero = function() {
+      console.log("This is zero.");
+   };
+}
+
+ +

+ +

フォーマットされた数値を返す

+ +

次の関数は、数値の先頭にゼロを足して固定長にした形で表される文字列を返します。

+ +
// この関数は先頭にゼロを足して固定長にした文字列を返す
+function padZeros(num, totalLen) {
+   var numStr = num.toString();             // 戻り値を文字列に初期化する
+   var numZeros = totalLen - numStr.length; // ゼロの数を計算する
+   for (var i = 1; i <= numZeros; i++) {
+      numStr = "0" + numStr;
+   }
+   return numStr;
+}
+
+ +

次の文で padZeros 関数を呼び出します。

+ +
var result;
+result = padZeros(42,4); // "0042" を返す
+result = padZeros(42,2); // "42" を返す
+result = padZeros(5,4);  // "0005" を返す
+
+ +

関数が存在するかどうか確認する

+ +

typeof 演算子を使うと関数が存在するかどうかを確かめる事ができます。次の例では、window オブジェクトが noFunc という関数のプロパティを持つかどうかを確かめるためのテストが行われます。もし持っていたら、それが使われます。そうでなければ、他の行動が取られます。

+ +
 if ('function' == typeof window.noFunc) {
+   // noFunc() を使う
+ } else {
+   // 何か他のことをする
+ }
+
+ +

if のテストの中で、noFunc への参照が使われているのに注目してください。関数名の後に括弧 "()" が無いので、実際の関数は呼ばれません。

+ +

仕様

+ + + + + + + + + + +
仕様書
{{SpecName('ESDraft', '#sec-function-definitions', 'Function definitions')}}
+ +

ブラウザーの互換性

+ + + +

{{Compat("javascript.functions")}}

+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/functions/method_definitions/index.html b/files/ja/web/javascript/reference/functions/method_definitions/index.html new file mode 100644 index 0000000000..14f21a5b91 --- /dev/null +++ b/files/ja/web/javascript/reference/functions/method_definitions/index.html @@ -0,0 +1,218 @@ +--- +title: メソッド定義 +slug: Web/JavaScript/Reference/Functions/Method_definitions +tags: + - ECMAScript 2015 + - ECMAScript6 + - Functions + - JavaScript + - Object + - Syntax +translation_of: Web/JavaScript/Reference/Functions/Method_definitions +--- +
{{JsSidebar("Functions")}}
+ +

ECMAScript 2015 より、オブジェクトイニシャライザのメソッド定義のための短い構文が導入されました。これは、メソッドの名前に割り当てられた関数の省略形です。

+ +
{{EmbedInteractiveExample("pages/js/functions-definitions.html")}}
+ + + +

構文

+ +
const obj = {
+  get property() {},
+  set property(value) {},
+  property( parameters… ) {},
+  *generator( parameters… ) {},
+  async property( parameters… ) {},
+  async* generator( parameters… ) {},
+
+  // 算出されたキーも使用可能:
+  get [property]() {},
+  set [property](value) {},
+  [property]( parameters… ) {},
+  *[generator]( parameters… ) {},
+  async [property]( parameters… ) {},
+  async* [generator]( parameters… ) {},
+};
+
+ +

説明

+ +

簡略構文は、ECMAScript 第 5 版で導入された gettersetter 構文に似ています。

+ +

次のコードを例にすると:

+ +
var obj = {
+  foo: function() {
+    /* コード */
+  },
+  bar: function() {
+    /* コード */
+  }
+};
+
+ +

これを以下のように短縮することができます:

+ +
var obj = {
+  foo() {
+    /* コード */
+  },
+  bar() {
+    /* コード */
+  }
+};
+
+
+ +

短縮形ジェネレーターメソッド

+ +

Generator メソッドは同様に簡略構文を使用して定義することができます。

+ +

簡略構文では:

+ + + +
// 名前付きプロパティを使用 (ES6 より前)
+const obj2 = {
+  g: function*() {
+    let index = 0
+    while(true)
+      yield index++
+  }
+};
+
+// 簡略構文を使用して同じオブジェクトを生成
+const obj2 = {
+  * g() {
+    let index = 0;
+    while(true)
+      yield index++
+  }
+};
+
+const it = obj2.g()
+console.log(it.next().value) // 0
+console.log(it.next().value) // 1
+ +

Async メソッド

+ +

{{jsxref("Statements/async_function", "Async メソッド", "", 1)}}も簡略構文を使用して定義することができます。

+ +
// 名前付きプロパティ
+const obj3 = {
+  f: async function () {
+    await some_promise
+  }
+};
+
+// 簡略構文を使用して同じオブジェクトを生成
+const obj3 = {
+  async f() {
+    await some_promise
+  }
+};
+
+ +

Async ジェネレーターメソッド

+ +

Generator メソッドも {{jsxref("Statements/async_function", "async", "", 1)}} 関数にすることができます。

+ +
const obj4 = {
+  f: async function* () {
+    yield 1
+    yield 2
+    yield 3
+  }
+};
+
+// 簡略構文を使用して同じオブジェクトを生成
+const obj4 = {
+  async* f() {
+   yield 1
+   yield 2
+   yield 3
+  }
+};
+ +

メソッド定義はコンストラクタブルではない

+ +

すべてのメソッド定義がコンストラクターではない(簡略構文のみ!)ため、インスタンス化しようとすると {{jsxref("TypeError")}} が発生します。

+ +
const obj = {
+  method() {},
+};
+new obj.method // TypeError: obj.method is not a constructor
+
+const obj = {
+  * g() {}
+};
+new obj.g; // TypeError: obj.g is not a constructor (ES2016 で変更)
+
+ +

+ +

簡単なテストケース

+ +
const obj = {
+  a: 'foo',
+  b() { return this.a }
+};
+console.log(obj.b()) // "foo"
+
+ +

計算されたプロパティ名

+ +

簡略構文は計算されたプロパティ名もサポートします。

+ +
const bar = {
+  foo0: function() { return 0 },
+  foo1(){ return 1 },
+  ['foo' + 2](){ return 2 },
+};
+
+console.log(bar.foo0()) // 0
+console.log(bar.foo1()) // 1
+console.log(bar.foo2()) // 2
+
+// A global function
+function foo() {
+  return 1
+}
+
+let name = 'foo'
+console.log(window[name]())  // 1
+ +

仕様

+ + + + + + + + + + + + +
仕様書
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}
+ +

ブラウザー実装状況

+ + + +

{{Compat("javascript.functions.method_definitions")}}

+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/functions/rest_parameters/index.html b/files/ja/web/javascript/reference/functions/rest_parameters/index.html new file mode 100644 index 0000000000..37e1727538 --- /dev/null +++ b/files/ja/web/javascript/reference/functions/rest_parameters/index.html @@ -0,0 +1,215 @@ +--- +title: 残余引数 +slug: Web/JavaScript/Reference/Functions/rest_parameters +tags: + - Functions + - JavaScript + - Language feature + - Rest + - Rest parameters + - 残余引数 + - 言語機能 + - 関数 +translation_of: Web/JavaScript/Reference/Functions/rest_parameters +--- +
{{jsSidebar("Functions")}}
+ +

残余引数構文により、不定数の引数を配列として表すことができます。

+ +
{{EmbedInteractiveExample("pages/js/functions-restparameters.html")}}
+ + + +

構文

+ +
function f(a, b, ...theArgs) {
+  // ...
+}
+ +

解説

+ +

関数の最後の引数に ... の接頭辞を付けると、(ユーザーが提供した) その位置にある残りの引数を JavaScript の「標準の」配列の中に入れることができます。

+ +

最後の引数のみが「残余引数」になることができます。

+ +
function myFun(a,  b, ...manyMoreArgs) {
+  console.log("a", a)
+  console.log("b", b)
+  console.log("manyMoreArgs", manyMoreArgs)
+}
+
+myFun("one", "two", "three", "four", "five", "six")
+
+// コンソール出力:
+// a, one
+// b, two
+// manyMoreArgs, [three, four, five, six]
+
+ +

残余引数と arguments オブジェクトとの違い

+ +

残余引数と {{jsxref("Functions/arguments", "arguments")}} オブジェクトの間には、主に 3 つの違いがあります。

+ + + +

arguments から配列へ

+ +

残余引数は、引数により引き起こされる定型コードを減らすために導入されました。

+ +
// 残余引数の登場以前は、"arguments" を普通の配列に変換するには以下のようにしていました。
+
+function f(a, b) {
+
+  let normalArray = Array.prototype.slice.call(arguments)
+  // -- or --
+  let normalArray = [].slice.call(arguments)
+  // -- or --
+  let normalArray = Array.from(arguments)
+
+  let first = normalArray.shift()  // OK、最初の引数が得られる
+  let first = arguments.shift()    // エラー (arguments は通常の配列ではない)
+}
+
+// 残余引数を使ってふつうの配列へのアクセスが得られるようになりました
+
+function f(...args) {
+  let normalArray = args
+  let first = normalArray.shift() // OK、最初の引数が得られる
+}
+
+ +

+ +

残余引数の使用

+ +

この例では、最初の引数が a に、2番目の引数が b に割り当てられますので、これらの名前付き引数はふつう通り使われます。

+ +

しかし、3番目の引数、manyMoreArgs は、3番目、4番目、5番目、6番目、・・・n番目 — ユーザーが入れただけの数の引数を持つ配列になります。

+ +
function myFun(a, b, ...manyMoreArgs) {
+  console.log("a", a)
+  console.log("b", b)
+  console.log("manyMoreArgs", manyMoreArgs)
+}
+
+myFun("one", "two", "three", "four", "five", "six")
+
+// a, one
+// b, two
+// manyMoreArgs, [three, four, five, six]
+
+ +

以下の例では・・・値が 1 つしかなくても、最後の引数は配列に入れられます。

+ +
// 上記の例と同じ関数定義を使用
+
+myFun("one", "two", "three")
+
+// a, one
+// b, two
+// manyMoreArgs, [three]
+ +

以下の例では、3番目の引数が提供されていませんが、manyMoreArgs は配列のままです (ただし空のものです)。

+ +
// 上記の例と同じ関数定義を使用
+
+myFun("one", "two")
+
+// a, one
+// b, two
+// manyMoreArgs, []
+ +

引数の長さ

+ +

theArgs は配列なので、length プロパティを使用して要素数を取得することができます。

+ +
function fun1(...theArgs) {
+  console.log(theArgs.length)
+}
+
+fun1()         // 0
+fun1(5)        // 1
+fun1(5, 6, 7)  // 3
+
+ +

通常の引数と残余引数

+ +

次の例では、残余引数を使用して 2 番目の引数から最後の引数までを配列に集めています。それからそれぞれを最初の引数と乗算し、その配列を返します。

+ +
function multiply(multiplier, ...theArgs) {
+  return theArgs.map(element => {
+    return multiplier * element
+  })
+}
+
+let arr = multiply(2, 1, 2, 3)
+console.log(arr)  // [2, 4, 6]
+
+ +

arguments との使用

+ +

Array のメソッドを残余引数で利用することができますが、arguments オブジェクトでは利用できません。

+ +
function sortRestArgs(...theArgs) {
+  let sortedArgs = theArgs.sort()
+  return sortedArgs
+}
+
+console.log(sortRestArgs(5, 3, 7, 1)) // 1, 3, 5, 7
+
+function sortArguments() {
+  let sortedArgs = arguments.sort()
+  return sortedArgs  // これは実行されない
+}
+
+
+console.log(sortArguments(5, 3, 7, 1))
+// TypeError が発生 (arguments.sort は関数ではない)
+
+ +

arguments オブジェクト上で Array メソッドを使用するには、まずオブジェクトを実配列に変換する必要があります。

+ +
function sortArguments() {
+  let args = Array.from(arguments)
+  let sortedArgs = args.sort()
+  return sortedArgs
+}
+console.log(sortArguments(5, 3, 7, 1))  // 1, 3, 5, 7
+
+ +

仕様

+ + + + + + + + + + + + +
仕様書
{{SpecName('ESDraft', '#sec-function-definitions', 'Function Definitions')}}
+ +

ブラウザーの互換性

+ + + +

{{Compat("javascript.functions.rest_parameters")}}

+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/functions/set/index.html b/files/ja/web/javascript/reference/functions/set/index.html new file mode 100644 index 0000000000..32b1d9b623 --- /dev/null +++ b/files/ja/web/javascript/reference/functions/set/index.html @@ -0,0 +1,146 @@ +--- +title: セッター +slug: Web/JavaScript/Reference/Functions/set +tags: + - ECMAScript 5 + - Functions + - JavaScript + - Language feature + - 言語機能 + - 関数 +translation_of: Web/JavaScript/Reference/Functions/set +--- +
{{jsSidebar("Functions")}}
+ +

set 構文は、あるオブジェクトプロパティを関数にバインドして、プロパティに設定しようとしたときに呼び出される関数に結びつけます。

+ +
{{EmbedInteractiveExample("pages/js/functions-setter.html")}}
+ + + +

構文

+ +
{set prop(val) { . . . }}
+{set [expression](val) { . . . }}
+ +

引数

+ +
+
prop
+
与えられた関数を割り当てるプロパティの名称です。
+
val
+
prop に設定しようとする値を保持する変数のエイリアスです。
+
expression
+
ECMAScript 2015 より、算出されたプロパティ名 (computed property name) の式を使用して関数に結び付けることもできます。
+
+ +

説明

+ +

JavaScript では、特定のプロパティを変更しようとするたびに関数を実行するため、セッターを利用できます。セッターはたいていゲッターと合わせて、擬似的なプロパティを作成するために用いられます。実際の値を持つプロパティが、同時にセッターを持つことはできません。

+ +

set 構文を使用する際の注意事項:

+ +
+ +
+ +

+ +

新しいオブジェクトでオブジェクトの初期化時にセッターを定義

+ +

以下の例では、擬似プロパティ currentlanguage オブジェクトに定義します。 current に値が代入されると、 log をその値で更新します。

+ +
const language = {
+  set current(name) {
+    this.log.push(name);
+  },
+  log: []
+}
+
+language.current = 'EN';
+console.log(language.log); // ['EN']
+
+language.current = 'FA';
+console.log(language.log); // ['EN', 'FA']
+
+ +

current は定義されておらず、あらゆるアクセスを試みてもその結果は undefined になることに注意してください。

+ +

delete 演算子によるセッターの削除

+ +

セッターを削除したい場合は、 {{jsxref("Operators/delete", "delete")}} だけで削除できます。

+ +
delete language.current;
+
+ +

defineProperty を使用して既存のオブジェクトにセッターを定義する

+ +

既存のオブジェクトにセッターを追加するには、 {{jsxref("Object.defineProperty()")}} を使用します。

+ +
const o = {a: 0};
+
+Object.defineProperty(o, 'b', {
+  set: function(x) { this.a = x / 2; }
+});
+
+o.b = 10;
+// セッターを実行し、 10 / 2 (5) を 'a' プロパティに代入
+
+console.log(o.a)
+//  5
+ +

算出されたプロパティ名を使用する

+ +
const expr = 'foo';
+
+const obj = {
+  baz: 'bar',
+  set [expr](v) { this.baz = v; }
+};
+
+console.log(obj.baz);
+//  "bar"
+
+obj.foo = 'baz';
+// セッターを実行
+
+console.log(obj.baz);
+//  "baz"
+
+ +

仕様書

+ + + + + + + + + + + + +
仕様書
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}
+ +

ブラウザー実装状況

+ + + +

{{Compat("javascript.functions.set")}}

+ +

関連情報

+ + -- cgit v1.2.3-54-g00ecf