From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- .../global_objects/function/apply/index.html | 241 ++++++++++++++ .../global_objects/function/arguments/index.html | 66 ++++ .../global_objects/function/bind/index.html | 350 +++++++++++++++++++++ .../global_objects/function/call/index.html | 181 +++++++++++ .../global_objects/function/caller/index.html | 84 +++++ .../global_objects/function/displayname/index.html | 90 ++++++ .../global_objects/function/function/index.html | 91 ++++++ .../reference/global_objects/function/index.html | 114 +++++++ .../global_objects/function/length/index.html | 76 +++++ .../global_objects/function/name/index.html | 233 ++++++++++++++ .../global_objects/function/tosource/index.html | 69 ++++ .../global_objects/function/tostring/index.html | 216 +++++++++++++ 12 files changed, 1811 insertions(+) create mode 100644 files/ja/web/javascript/reference/global_objects/function/apply/index.html create mode 100644 files/ja/web/javascript/reference/global_objects/function/arguments/index.html create mode 100644 files/ja/web/javascript/reference/global_objects/function/bind/index.html create mode 100644 files/ja/web/javascript/reference/global_objects/function/call/index.html create mode 100644 files/ja/web/javascript/reference/global_objects/function/caller/index.html create mode 100644 files/ja/web/javascript/reference/global_objects/function/displayname/index.html create mode 100644 files/ja/web/javascript/reference/global_objects/function/function/index.html create mode 100644 files/ja/web/javascript/reference/global_objects/function/index.html create mode 100644 files/ja/web/javascript/reference/global_objects/function/length/index.html create mode 100644 files/ja/web/javascript/reference/global_objects/function/name/index.html create mode 100644 files/ja/web/javascript/reference/global_objects/function/tosource/index.html create mode 100644 files/ja/web/javascript/reference/global_objects/function/tostring/index.html (limited to 'files/ja/web/javascript/reference/global_objects/function') diff --git a/files/ja/web/javascript/reference/global_objects/function/apply/index.html b/files/ja/web/javascript/reference/global_objects/function/apply/index.html new file mode 100644 index 0000000000..10f6c025f7 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/function/apply/index.html @@ -0,0 +1,241 @@ +--- +title: Function.prototype.apply() +slug: Web/JavaScript/Reference/Global_Objects/Function/apply +tags: + - Function + - JavaScript + - Method + - apply +translation_of: Web/JavaScript/Reference/Global_Objects/Function/apply +--- +
{{JSRef}}
+ +

apply() メソッドは、 this 値を指定して関数を呼び出し、 arguments は配列 (または配列風オブジェクト) として提供します。

+ +
{{EmbedInteractiveExample("pages/js/function-apply.html")}}
+ + + +

構文

+ +
func.apply(thisArg, [ argsArray])
+ +

引数

+ +
+
thisArg
+
+

this の値で、 func の呼び出しで提供されます。

+ +

このメソッドで指定した this が必ず呼び出したメソッドで参照されるわけではないことに注意してください。もし呼び出したメソッドが{{jsxref("Strict_mode", "厳格モードではない", "", 1)}}コード内の関数であれば、ここで渡した値が {{jsxref("null")}} もしくは {{jsxref("undefined")}} であった場合はグローバルオブジェクトに置き換えられ、プリミティブ型の変数はボックス化されます。この引数は必須です。

+
+
argsArray {{optional_inline}}
+
+

1 つの配列風のオブジェクトであり、 func 関数が呼ぶことになる引数を列挙したものです。関数に引数が渡されない場合は {{jsxref("null")}} または {{jsxref("undefined")}} となります。

+ +

ECMAScript 5 以降ではこれらの値は配列ではなく配列風のオブジェクトを用いる事になりました。後述の{{anch("Browser_compatibility", "ブラウザーの互換性")}}を参照してください。

+
+
+ +

返値

+ +

指定した this と引数で関数を呼び出した結果が返ります。

+ +

解説

+ +
+

注: 関数の構文は {{jsxref("Function.call", "call()")}} メソッドとほぼ同じですが、根本的な違いは call() メソッドは連続した引数のリストを受け取るのに対して、 apply() メソッドが引数の配列を 1 つだけ受け取るという点です。

+
+ +
+

注: 最初の引数が undefined または null の場合、配列のスプレッド構文を使用して同様の結果を得ることができます。

+
+ +

存在する関数を呼び出す時は通常と異なる this オブジェクトを渡すことができます。this はカレントオブジェクト、呼び出したオブジェクトを参照します。apply を用いることで、新たなオブジェクトのためにそのメソッドを書き直すことなく継承させることができます。

+ +

apply は、対応する引数の型を除けば {{jsxref("Function.call", "call()")}} によく似ています。引数のリストの代わりに引数の配列を用いることができます。apply は配列リテラルを引数に用いることもできます。例えば func.apply(this, ['eat', 'bananas']) のように利用でき、同様に配列オブジェクトを func.apply(this, new Array('eat', 'bananas')) のように利用できます。

+ +

argsArray で {{jsxref("Functions/arguments", "arguments")}} を利用することもできます。arguments は関数内のローカル変数です。これは、呼び出されたオブジェクトの不特定の引数すべてに対して用いることができます。つまり、 apply メソッドを使うにあたって呼び出されたオブジェクトの引数について知る必要がないのです。arguments を利用することで、引数のすべてを呼び出されたオブジェクトに渡すことができます。引数の扱いは、呼び出されたオブジェクトが受け持ちます。

+ +

ECMAScript 第5版以降では、配列風のオブジェクトも使えます。具体的には、length プロパティとその範囲 (0 から length-1 まで) の整数の名称のプロパティを持った、あらゆる種類のオブジェクトの利用を認めています。例えば、{{domxref("NodeList")}} や { 'length': 2, '0': 'eat', '1': 'bananas' } のような独自のオブジェクトを利用できます。

+ +
+

注: Chrome 14 や Internet Explorer 9 などのブラウザーでは、配列風オブジェクトを扱えずに例外が発生します。

+
+ +

+ +

apply で配列を別の配列に追加する

+ +

push で 1 つの要素を配列に追加できます。そして、push は可変長引数に対応しているので、複数の要素を一度に追加することもできます。

+ +

しかし push に配列を渡すと、配列の要素ごとにではなく配列全体を 1 つの要素として追加してしまいます。配列の中に配列が入るだけなのです。

+ +

それを望まない場合はどうすればいいのでしょう? concat ならば望みの結果を得られます。しかし、既存の配列に追加するのではなく、新しい配列を生成して返します。

+ +

既存の配列に追加したいのに... では、どうすれば?ループ文を書きますか?おことわりですよね?

+ +

apply が救ってくれます!

+ +
const array = ['a', 'b'];
+const elements = [0, 1, 2];
+array.push.apply(array, elements);
+console.info(array); // ["a", "b", 0, 1, 2]
+
+ +

apply をビルトイン関数と共に利用する

+ +

apply を賢く使うと、本来なら配列のためにループ文を書かなくてはならないような処理に対して、ビルトイン関数をそのまま使えるようになります。

+ +

下記の例では、配列の最大値・最小値を求めるために Math.max/Math.min を使っています。

+ +
// 最小値・最大値を求めたい配列
+const numbers = [5, 6, 2, 3, 7];
+
+// Math.min/Math.max と apply を使う
+let max = Math.max.apply(null, numbers);
+// これは右と同じ Math.max(numbers[0], ...)
+// または Math.max(5, 6, ...)
+
+let min = Math.min.apply(null, numbers);
+
+// 対して、ループ文を使うとこうなる
+max = -Infinity, min = +Infinity;
+
+for (let i = 0; i < numbers.length; i++) {
+  if (numbers[i] > max) {
+    max = numbers[i];
+  }
+  if (numbers[i] < min) {
+    min = numbers[i];
+  }
+}
+
+ +

しかし注意してください。この方法で apply を使う場合、 JavaScript エンジンの引数の長さ上限を超えてしまう危険があります。多すぎる (おおよそ数万個以上だと思って下さい) 引数を与えた結果は、その上限が特に決まっていない (本当に任意の巨大なデータのかたまりに対してさえ) ためエンジンによって (JavaScriptCore ライブラリでは引数の上限は 65536 であるとハードコーディングされています) 異なります。

+ +

これは、その限界 (実際には、過剰に大きなスタックの挙動の性質さえも) が不特定であるためです。例外を投げるエンジンも存在します。さらに酷い場合では、関数へ実際に渡す引数の数を勝手に制限するものもあります。後者について詳しく解説しますと、そのエンジンの引数の上限が 4 つの場合 (実際の上限値は当然もっと上です)、上の例では、完全な配列でなく 5, 6, 2, 3apply へ渡されたかのような動作をします。

+ +

もし実装しているコードで利用する配列の変数の数が数万を超えそうなときは、以下に示すように一度に apply に渡す配列を分割して利用する方法を併用すべきでしょう。

+ +
function minOfArray(arr) {
+  let min = Infinity;
+  let QUANTUM = 32768;
+
+  for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
+    var submin = Math.min.apply(null,
+                                arr.slice(i, Math.min(i+QUANTUM, len)));
+    min = Math.min(submin, min);
+  }
+
+  return min;
+}
+
+let min = minOfArray([5, 6, 2, 3, 7]);
+
+ +

apply を利用したコンストラクターチェーン

+ +

apply を利用して、Java のように {{jsxref("Operators/new", "constructors")}} の連結を行なうことができます。

+ +

以下に示す例ではグローバルな construct という名称の {{jsxref("Function")}} オブジェクトを作成し、引数のリストの代わりに配列風オブジェクトをコンストラクターと共に利用できるようになります。

+ +
Function.prototype.construct = function(aArgs) {
+  let oNew = Object.create(this.prototype);
+  this.apply(oNew, aArgs);
+  return oNew;
+};
+
+ +
+

注: 上記で使用している Object.create() メソッドは比較的新しいです。代わりの方法として、以下の例を検討してください。

+ +

{{jsxref("Object/__proto__", "Object.__proto__")}} を利用:

+ +
Function.prototype.construct = function (aArgs) {
+  let oNew = {};
+  oNew.__proto__ = this.prototype;
+  this.apply(oNew, aArgs);
+  return oNew;
+};
+
+ +

クロージャを利用:

+ +
Function.prototype.construct = function(aArgs) {
+  let fConstructor = this, fNewConstr = function() {
+    fConstructor.apply(this, aArgs);
+  };
+  fNewConstr.prototype = fConstructor.prototype;
+  return new fNewConstr();
+};
+ +

{{jsxref("Function")}} コンストラクターを利用:

+ +
Function.prototype.construct = function (aArgs) {
+  let fNewConstr = new Function("");
+  fNewConstr.prototype = this.prototype;
+  let oNew = new fNewConstr();
+  this.apply(oNew, aArgs);
+  return oNew;
+};
+
+
+ +

使用例:

+ +
function MyConstructor() {
+  for (let nProp = 0; nProp < arguments.length; nProp++) {
+    this['property' + nProp] = arguments[nProp];
+  }
+}
+
+let myArray = [4, 'Hello world!', false];
+let myInstance = MyConstructor.construct(myArray);
+
+console.log(myInstance.property1);                // logs 'Hello world!'
+console.log(myInstance instanceof MyConstructor); // logs 'true'
+console.log(myInstance.constructor);              // logs 'MyConstructor'
+
+ +
+

注: この非ネイティブな Function.construct メソッドはいくつかのネイティブ実装されたコンストラクタ (例えば {{jsxref("Date")}} のような物) と併用できません。このようなケースにおいては {{jsxref("Function.bind")}} メソッドを利用する必要があります。

+ +

例えば [2012, 11, 4] のような配列を {{jsxref("Global_Objects/Date", "Date")}} コンストラクターに利用する事を考えてみてください。この場合では new (Function.prototype.bind.apply(Date, [null].concat([2012, 11, 4])))() のように書く必要があります。

+ +

いずれにせよこれは最適な選択肢とは言えず、実用上はいかなる状況でも用いるべきではないでしょう)

+
+ +

仕様書

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

ブラウザーの互換性

+ +
+ + +

{{Compat("javascript.builtins.Function.apply")}}

+
+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/global_objects/function/arguments/index.html b/files/ja/web/javascript/reference/global_objects/function/arguments/index.html new file mode 100644 index 0000000000..4219b3dde1 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/function/arguments/index.html @@ -0,0 +1,66 @@ +--- +title: Function.arguments +slug: Web/JavaScript/Reference/Global_Objects/Function/arguments +tags: + - Deprecated + - Function + - JavaScript + - Property + - arguments +translation_of: Web/JavaScript/Reference/Global_Objects/Function/arguments +--- +
{{JSRef}} {{deprecated_header}}
+ +

function.arguments プロパティは、関数に渡される引数に対応する、配列風のオブジェクトです。より単純な {{jsxref("Functions/arguments", "arguments")}} 変数を使用してください。このプロパティは厳格モードでは使用できません。

+ +

解説

+ +

function.arguments の構文は非推奨です。関数内で {{jsxref("Functions/arguments", "arguments")}} オブジェクトにアクセスする方法としては、変数 {{jsxref("Functions/arguments", "arguments")}} が利用できます。

+ +

再帰呼び出しの場合、すなわちコールスタックに関数 f が複数回現れる場合に、f.arguments はもっとも直近に実行された関数に対応する引数を表します。

+ +

実行中の関数の未処理の呼び出しがない (つまり、関数が呼び出された状態で返してない) 場合、 arguments プロパティの値は通常 null です。

+ +

+ +

arguments オブジェクトの使用

+ +
function f(n) { g(n - 1) }
+
+function g(n) {
+  console.log('before: ' + g.arguments[0])
+  if (n > 0) { f(n) }
+  console.log('after: ' + g.arguments[0])
+}
+
+f(2)
+
+console.log('returned: ' + g.arguments)
+
+// Output
+
+// before: 1
+// before: 0
+// after: 0
+// after: 1
+// returned: null
+
+ +

仕様書

+ +

何れかの標準で定義されたものではありません。 ECMAScript 3 で {{jsxref("Functions/arguments", "arguments")}} に置き換えられました。

+ +

ブラウザーの互換性

+ +
+ + +

{{Compat("javascript.builtins.Function.arguments")}}

+
+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/global_objects/function/bind/index.html b/files/ja/web/javascript/reference/global_objects/function/bind/index.html new file mode 100644 index 0000000000..1bba8cd72c --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/function/bind/index.html @@ -0,0 +1,350 @@ +--- +title: Function.prototype.bind() +slug: Web/JavaScript/Reference/Global_Objects/Function/bind +tags: + - ECMAScript 2015 + - ECMAScript 5 + - Function + - JavaScript + - Method + - polyfill +translation_of: Web/JavaScript/Reference/Global_Objects/Function/bind +--- +
{{JSRef}}
+ +

bind() メソッドは、呼び出された際に this キーワードに指定された値が設定される新しい関数を生成します。この値は新しい関数が呼び出されたとき、一連の引数の前に置かれます。

+ +
{{EmbedInteractiveExample("pages/js/function-bind.html", "taller")}}
+ + + +

構文

+ +
let boundFunc = func.bind(thisArg[, arg1[, arg2[, ...argN]]])
+
+ +

引数

+ +
+
thisArg
+
バインドされた関数が呼び出される際、 this 引数としてターゲット関数 func に渡される値です。バインドされた関数が {{jsxref("Operators/new", "new")}} 演算子によって構築された場合、この引数は無視されます。 bind を使用して setTimeout の中で (コールバックとして提供する) 関数を生成する場合、 thisArg として渡されたプリミティブ値はオブジェクトに変換されます。引数が bind に提供されなかった場合、または thisArgnull または undefined であった場合は、実行スコープの this は新しい関数のための thisArg として扱われます。
+
arg1, arg2, ...argN {{optional_inline}}
+
func を呼び出す時、バインドされた関数に与えられる引数の前に付けて渡す引数。
+
+ +

返値

+ +

this の値と初期の引数を指定された関数のコピーです。

+ +

解説

+ +

bind() 関数は、新しいバインドされた関数、すなわち元の関数オブジェクトをラップする特殊関数オブジェクト (exotic function object) (ECMAScript 2015 からの用語) を生成します。バインドされた関数を呼び出すと、通常はラップされた関数が実行される結果になります。

+ +

バインドされた関数は、以下の内部プロパティを持ちます。

+ +
+
[[BoundTargetFunction]]
+
ラップされた関数オブジェクト
+
[[BoundThis]]
+
ラップされた関数を呼び出す時に常に this に渡される値。
+
[[BoundArguments]]
+
ラップされた関数を呼び出す時に、その要素が第1引数として使われる値のリスト。
+
[[Call]]
+
オブジェクトに関連する実行コード。関数呼び出し式を通じて実行される。内部メソッドへの引数は this 値と呼び出し式によって関数に渡される引数を含むリスト。
+
+ +

バインドされた関数が呼び出されると、内部メソッド [[Call]][[BoundTargetFunction]] 上で、 Call(boundThis, ...args) の引数で呼び出します。ここで boundThis[[BoundThis]]args[[BoundArguments]] で、その後に関数呼び出しで渡された引数が続きます。

+ +

バインドされた関数は {{jsxref("Operators/new", "new")}} 演算子でも生成されます。これを行うとターゲット関数が代わりに生成されたようになります。与えられた this の値は無視され、追加された引数はエミュレートされた関数に提供されます。

+ +

+ +

バインドされた関数の生成

+ +

最もシンプルな bind() の使い方は、どのように呼び出された場合でも特定の this 値を持つ関数を生成することです。

+ +

初心者の JavaScript プログラマーがよくやる間違いは、あるオブジェクトからメソッドを取り出し、後でその関数を呼び出すとき、その内側の this 値が元のオブジェクトになると考えてしまうことです (例えば、そのメソッドをコールバック関数に使う場合)。

+ +

特に配慮しなければ、ふつうは元のオブジェクトが見えなくなります。その関数に元々のオブジェクトを bind() してバインドされた関数を生成すれば、この問題をきちんと解決することができます。

+ +
this.x = 9;    // 'this' はここではブラウザーのグローバルな 'window' オブジェクト
+const module = {
+  x: 81,
+  getX: function() { return this.x; }
+};
+
+module.getX();
+// 81 を返します
+
+const retrieveX = module.getX;
+retrieveX();
+// 9 を返します。この関数はグローバルスコープで呼び出されるためです。
+
+// 'this' を module に結びつけた新しい関数を生成
+// 初心者のプログラマーはグローバル変数の x と
+// モジュールプロパティの x とを混同するかもしれません。
+const boundGetX = retrieveX.bind(module);
+boundGetX();
+// 81 を返します
+
+ +

部分的に適用された関数

+ +

次にシンプルな bind() の使い方は、あらかじめ引数が指定された関数を生成することです。

+ +

これらの引数は、this 値の後に続けます (指定しないことも可能)。すると、バインドされた関数がいつ呼ばれても、この指定された引数を先頭にしてバインドされた関数の引数がターゲット関数に渡されます。

+ +
function list() {
+  return Array.prototype.slice.call(arguments);
+}
+
+function addArguments(arg1, arg2) {
+  return arg1 + arg2
+}
+
+const list1 = list(1, 2, 3);
+//  [1, 2, 3]
+
+const result1 = addArguments(1, 2);
+//  3
+
+// 先頭の引数が設定済みの関数を生成します。
+const leadingThirtysevenList = list.bind(null, 37);
+
+// 第一引数が設定済みの関数を生成します。
+const addThirtySeven = addArguments.bind(null, 37);
+
+const list2 = leadingThirtysevenList();
+//  [37]
+
+const list3 = leadingThirtysevenList(1, 2, 3);
+//  [37, 1, 2, 3]
+
+const result2 = addThirtySeven(5);
+//  37 + 5 = 42
+
+const result3 = addThirtySeven(5, 10);
+//  37 + 5 = 42
+//  (the second argument is ignored)
+
+ +

setTimeout での利用

+ +

既定では、 {{domxref("WindowOrWorkerGlobalScope.setTimeout()", "window.setTimeout()")}} 内部の this キーワードは {{domxref("window")}} (または global オブジェクト) に設定されます。クラスインスタンスを参照する this が必要なクラスメソッドを使う場合、 this をコールバック関数と明確に結びつけて (バインドして)、インスタンスを維持することができます。

+ +
function LateBloomer() {
+  this.petalCount = Math.floor(Math.random() * 12) + 1;
+}
+
+// 1 秒遅延させてから bloom を宣言する
+LateBloomer.prototype.bloom = function() {
+  window.setTimeout(this.declare.bind(this), 1000);
+};
+
+LateBloomer.prototype.declare = function() {
+  console.log(`I am a beautiful flower with ${this.petalCount} petals!`);
+};
+
+const flower = new LateBloomer();
+flower.bloom();
+//  after 1 second, calls 'flower.declare()'
+
+ +

コンストラクターとして使用するバインドされた関数

+ +
+

警告: この節では、 JavaScript の機能性を実演するため、 bind() メソッドの極端な例を説明しています。

+ +

以下の方法は何かを実現するのに最適な方法ではなく、むしろ本番環境では使用するべきでない方法です。

+
+ +

バインドされた関数は自動的に、 {{jsxref("Operators/new", "new")}} 演算子を使ってターゲット関数の新しいインスタンスを構築できるようになっています。新たな値を構築するために束縛された関数を使った場合、 this を与えても無視されます。

+ +

しかし、同時に与える引数はコンストラクター呼び出しの先頭部分に挿入されます:

+ +
function Point(x, y) {
+  this.x = x;
+  this.y = y;
+}
+
+Point.prototype.toString = function() {
+  return `${this.x},${this.y}`;
+};
+
+const p = new Point(1, 2);
+p.toString();
+// '1,2'
+
+
+//  以下のポリフィルには対応していません。
+
+//  ネイティブの bind ではうまく動作します。
+
+const YAxisPoint = Point.bind(null, 0/*x*/);
+
+
+const emptyObj = {};
+const YAxisPoint = Point.bind(emptyObj, 0/*x*/);
+
+const axisPoint = new YAxisPoint(5);
+axisPoint.toString();                    // '0,5'
+
+axisPoint instanceof Point;              // true
+axisPoint instanceof YAxisPoint;         // true
+new YAxisPoint(17, 42) instanceof Point; // true
+
+ +

バインドされた関数を {{jsxref("Operators/new", "new")}} で使えるように生成するのに特別なことをする必要は無いので注意してください。

+ +

当然、普通に呼び出されるバインドされた関数を生成する際も特別なことは必要ありません。もしその関数を {{jsxref("Operators/new", "new")}} 演算子とともに呼び出すことにしか使いたくないと思っても、普通に呼び出すことはできてしまいます。

+ +
// この例は JavaScript コンソールで直接実行できます
+// ...上の例のつづき
+
+// 普通の関数としても実行できます
+// (あまり必要にはなりませんが)
+YAxisPoint(13);
+
+`${emptyObj.x},${emptyObj.y}`;
+// >  '0,13'
+
+ +

バインドされた関数を {{jsxref("Operators/new", "new")}} でしか使えないように制限したい場合、または通常の呼び出しだけに制限したい場合には、ターゲット関数がその制限を強制するようにしなければなりません。

+ +

ショートカットを作成する

+ +

bind() は、特定の this を必須とするような関数のショートカットを作成するのにも便利です。

+ +

例として、{{jsxref("Array.prototype.slice()")}} を取り上げます。この関数は、配列に似たオブジェクトを本物の配列へ変換するために使えます。まず、次のようにショートカットを作成するとします。

+ +
const slice = Array.prototype.slice;
+
+// ...
+
+slice.apply(arguments);
+
+ +

bind() を使うと、さらにシンプルにできます。

+ +

次のコードでは、 slice() が {{jsxref("Function.prototype")}} の {{jsxref("Function.prototype.apply()", "apply()")}} 関数に結びつけられた関数になり、その内側の this 値は {{jsxref("Array.prototype")}} の{{jsxref("Array.prototype.slice()", "slice()")}} 関数にセットされます。こうすると、いちいち apply() を呼び出す必要がなくなります。

+ +
// ひとつ前の例の "slice" と同じ
+const unboundSlice = Array.prototype.slice;
+const slice = Function.prototype.apply.bind(unboundSlice);
+
+// ...
+
+slice(arguments);
+
+ +

ポリフィル

+ +

古いブラウザーは一般的に遅いブラウザーでもあるので、古いブラウザーでのブラウジングを少しでも悪くなくすために、性能の良いポリフィルを作成することは、多くの人が認識しているよりもはるかに重要なことです。

+ +

したがって、 Function.prototype.bind() のポリフィルの選択肢を二つ示します。

+ +
    +
  1. 最初の方の方がずっと小さくて性能が良いのですが、 new 演算子を使うとうまくいきません。
  2. +
  3. 2 番目の方が大きくて性能が低いですが、new演算子を使ってバインドされた関数を使用することができます。
  4. +
+ +

一般的に、ほとんどのコードでは、バインドされた関数で new が使用されることはとても稀なので、一般的には最初の選択肢を使用するのがベストです。

+ +
//  Does not work with `new (funcA.bind(thisArg, args))`
+if (!Function.prototype.bind) (function(){
+  var slice = Array.prototype.slice;
+  Function.prototype.bind = function() {
+    var thatFunc = this, thatArg = arguments[0];
+    var args = slice.call(arguments, 1);
+    if (typeof thatFunc !== 'function') {
+      // closest thing possible to the ECMAScript 5
+      // internal IsCallable function
+      throw new TypeError('Function.prototype.bind - ' +
+             'what is trying to be bound is not callable');
+    }
+    return function(){
+      var funcArgs = args.concat(slice.call(arguments))
+      return thatFunc.apply(thatArg, funcArgs);
+    };
+  };
+})();
+ +

以下のコードをスクリプトの先頭に挿入すれば、その状況をいくらか変えることができます。ネイティブで対応されていない実装において、 bind() の多くの機能を使えるようになります。

+ +
//  Yes, it does work with `new (funcA.bind(thisArg, args))`
+if (!Function.prototype.bind) (function(){
+  var ArrayPrototypeSlice = Array.prototype.slice;
+  Function.prototype.bind = function(otherThis) {
+    if (typeof this !== 'function') {
+      // closest thing possible to the ECMAScript 5
+      // internal IsCallable function
+      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
+    }
+
+    var baseArgs= ArrayPrototypeSlice.call(arguments, 1),
+        baseArgsLength = baseArgs.length,
+        fToBind = this,
+        fNOP    = function() {},
+        fBound  = function() {
+          baseArgs.length = baseArgsLength; // reset to default base arguments
+          baseArgs.push.apply(baseArgs, arguments);
+          return fToBind.apply(
+                 fNOP.prototype.isPrototypeOf(this) ? this : otherThis, baseArgs
+          );
+        };
+
+    if (this.prototype) {
+      // Function.prototype doesn't have a prototype property
+      fNOP.prototype = this.prototype;
+    }
+    fBound.prototype = new fNOP();
+
+    return fBound;
+  };
+})();
+
+ +

このアルゴリズムと仕様上のアルゴリズムとの間には、いくつか大きな違いがあります (真剣に網羅することを目指したわけではないので、他にも差はあるかもしれません)。

+ + + +

この部分的な実装を使用することを選択した場合、ECMA-262 第5版から動作が逸脱している場合には、それに頼ってはいけません! ありがたいことに、このような仕様からの逸脱は、ほとんどのコーディングの状況では (今までにも) ほとんど出てきません。上記の仕様からの逸脱を理解していない場合は、この特定のケースでは、これらの非準拠の逸脱の詳細を気にしないのが安全です。

+ +

どうしても必要で、性能が気にならない場合は、はるかに遅い (しかし、より仕様に準拠した) 解決法が https://github.com/Raynos/function-bind にあります。

+ +

仕様書

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

ブラウザーの互換性

+ +
+ + +

{{Compat("javascript.builtins.Function.bind")}}

+
+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/global_objects/function/call/index.html b/files/ja/web/javascript/reference/global_objects/function/call/index.html new file mode 100644 index 0000000000..22febfb7f2 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/function/call/index.html @@ -0,0 +1,181 @@ +--- +title: Function.prototype.call() +slug: Web/JavaScript/Reference/Global_Objects/Function/call +tags: + - Call + - Function + - JavaScript + - Method + - メソッド +translation_of: Web/JavaScript/Reference/Global_Objects/Function/call +--- +
{{JSRef}}
+ +

call() メソッドは、 this の値と、独立して提供された引数によって関数を呼び出します。

+ +
{{EmbedInteractiveExample("pages/js/function-call.html")}}
+ + + +

構文

+ +
func.call([thisArg[, arg1, arg2, ...argN]])
+ +

引数

+ +
+
thisArg {{optional_inline}}
+
+

func が呼び出されたときに this として使用される値です。

+ +
+

注意: 特定の場面では、 thisArg はメソッドから見える実際の値でない場合があります。

+ +

もし、そのメソッドが{{jsxref("Strict_mode", "厳格モード", "", 1)}}の関数ではなかった場合、 {{jsxref("Global_Objects/null", "null")}} と {{jsxref("Global_Objects/undefined", "undefined")}} はグローバルオブジェクトで置き換えられ、プリミティブ値はオブジェクトに変換されます。

+
+
+
arg1, arg2, ...argN {{optional_inline}}
+
呼び出し先の関数に渡される引数です。
+
+ +

返値

+ +

this の値と引数を指定して関数を呼び出した結果です。

+ +

解説

+ +

call() はあるオブジェクトに所属する関数やメソッドを、別なオブジェクトに割り当てて呼び出すことができます。

+ +

call() は関数やメソッドに this の新しい値を提供します。 call() によって、いったんメソッドを書いてから、新しいオブジェクトへメソッドを描き直さずに他のオブジェクトへと継承することができます。

+ +
+

注: このメソッドの構文は {{jsxref("Function.prototype.apply", "apply()")}} とほぼ同じですが、基本的な違いは call()引数リストを受け取るのに対して、 apply()引数の単一の配列を受け取る点です。

+
+ +

+ +

call メソッドを使用してオブジェクトのコンストラクターを連鎖させる

+ +

call を使用して (Java と同様に) オブジェクトのコンストラクターを連鎖させることができます。

+ +

下記の例では、 Product オブジェクトのコンストラクターは nameprice の二つの引数で定義されています。

+ +

他の FoodToy の二つの関数は、 Product を呼び出して thisnameprice を渡します。 Productnameprice プロパティを初期化し、どちらも特化した関数が category を定義します。

+ +
function Product(name, price) {
+  this.name = name;
+  this.price = price;
+}
+
+function Food(name, price) {
+  Product.call(this, name, price);
+  this.category = 'food';
+}
+
+function Toy(name, price) {
+  Product.call(this, name, price);
+  this.category = 'toy';
+}
+
+const cheese = new Food('feta', 5);
+const fun = new Toy('robot', 40);
+
+ +

call メソッドを使用した無名関数の呼び出し

+ +

次の例では、無名関数を作成して call を使用して配列内の各オブジェクトに対して呼び出しを行います。

+ +

ここでの無名関数の主な目的は、 print 関数をすべてのオブジェクトに追加することで、配列内のオブジェクトの正しいインデックスを表示できるようにします。実際には this の値としてオブジェクトを渡す必要ありませんが、例示の目的で使用しています。

+ +
+

オブジェクトを this の値として渡すことは厳密には必要ではありませんが、説明のために使用しました。

+
+ +
const animals = [
+  { species: 'Lion', name: 'King' },
+  { species: 'Whale', name: 'Fail' }
+];
+
+for (let i = 0; i < animals.length; i++) {
+  (function(i) {
+    this.print = function() {
+      console.log('#' + i + ' ' + this.species
+                  + ': ' + this.name);
+    }
+    this.print();
+  }).call(animals[i], i);
+}
+
+ +

call を使用した関数を呼び出しと 'this' のコンテキストの指定

+ +

次の例では、greet メソッドを呼ぶとき、this の値を obj オブジェクトにバインドしています。

+ +
function greet() {
+  const reply = [this.animal, 'typically sleep between', this.sleepDuration].join(' ');
+  console.log(reply);
+}
+
+const obj = {
+  animal: 'cats', sleepDuration: '12 and 16 hours'
+};
+
+greet.call(obj);  // cats typically sleep between 12 and 16 hours
+
+ +

call を使用した最初の引数を指定しない関数の呼び出し

+ +

下記の例では、 display 関数を、最初の引数を渡さずに呼び出しています。最初の引数が渡されないと、 this の値はグローバルオブジェクトに結び付けられます。

+ +
var sData = 'Wisen';
+
+function display() {
+  console.log('sData value is %s ', this.sData);
+}
+
+display.call();  // sData value is Wisen
+ +
+

注: 厳格モードでは this の値は undefined になります。以下を参照してください。

+
+ +
'use strict';
+
+var sData = 'Wisen';
+
+function display() {
+  console.log('sData value is %s ', this.sData);
+}
+
+display.call(); // undefined の 'sData' のプロパティは読めない
+ +

仕様書

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

ブラウザーの互換性

+ + + +

{{Compat("javascript.builtins.Function.call")}}

+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/global_objects/function/caller/index.html b/files/ja/web/javascript/reference/global_objects/function/caller/index.html new file mode 100644 index 0000000000..0261d4f48d --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/function/caller/index.html @@ -0,0 +1,84 @@ +--- +title: Function.caller +slug: Web/JavaScript/Reference/Global_Objects/Function/caller +tags: + - Deprecated + - Function + - JavaScript + - Property +translation_of: Web/JavaScript/Reference/Global_Objects/Function/caller +--- +
{{JSRef}} {{deprecated_header}}
+ +

function.caller プロパティは、指定した関数の呼び出し元の関数を返します。厳格モード、非同期関数、ジェネレーター関数の呼び出し元については null を返します。

+ +

解説

+ +

関数 f が最上位のコードで呼び出された場合、 f.caller の値は {{jsxref("null")}} に、それ以外の場合の値は f を呼び出した関数になります。厳格モード、非同期関数、ジェネレーター関数の呼び出し元についても null を返します。

+ +

このプロパティは、廃止された {{jsxref("Functions/arguments", "arguments")}} オブジェクトの {{jsxref("Functions/arguments/caller", "arguments.caller")}} プロパティを置き換えます。

+ +

特殊プロパティである __caller__ は呼び出し元の activation オブジェクトを返し、スタックの再現に利用できましたが、セキュリティ上の理由により削除されました。

+ +

+ +

再帰呼び出しの場合、このプロパティを用いてコールスタックを再現することはできません。以下について考えてみましょう。

+ +
function f(n) { g(n - 1); }
+function g(n) { if (n > 0) { f(n); } else { stop(); } }
+f(2);
+
+ +

stop() が呼び出された時点のコールスタックは以下のようになるでしょう。

+ +
f(2) -> g(1) -> f(1) -> g(0) -> stop()
+
+ +

以下は真になります。

+ +
stop.caller === g && f.caller === g && g.caller === f
+
+ +

従って、stop() 関数のスタックトレースを以下のようにして取得するとします。

+ +
var f = stop;
+var stack = 'Stack trace:';
+while (f) {
+  stack += '\n' + f.name;
+  f = f.caller;
+}
+
+ +

これは無限ループになります。

+ +

+ +

関数の caller プロパティの値を確認する

+ +

以下のコードは、関数の caller プロパティの値を確認します。

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

仕様書

+ +

いずれの標準仕様でも定義されていません。

+ +

ブラウザーの互換性

+ + + +

{{Compat("javascript.builtins.Function.caller")}}

+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/global_objects/function/displayname/index.html b/files/ja/web/javascript/reference/global_objects/function/displayname/index.html new file mode 100644 index 0000000000..d197df7952 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/function/displayname/index.html @@ -0,0 +1,90 @@ +--- +title: Function.displayName +slug: Web/JavaScript/Reference/Global_Objects/Function/displayName +tags: + - Function + - JavaScript + - Non-standard + - Property +translation_of: Web/JavaScript/Reference/Global_Objects/Function/displayName +--- +
{{JSRef}} {{non-standard_header}}
+ +

function.displayName プロパティは、関数の表示名を返します。

+ +

+ +

displayName の設定

+ +

通常、コンソールやプロファイラーでは関数名を表示するのに {{jsxref("Function.name", "func.name")}} よりも好まれます。

+ +

以下のものをコンソールに入力すると、 "function My Function()" のように表示されます。

+ +
var a = function() {};
+a.displayName = 'My Function';
+
+a; // "function My Function()"
+ +

displayName プロパティが定義されると、関数の表示名が返されます。

+ +
function doSomething() {}
+
+console.log(doSomething.displayName); // "undefined"
+
+var popup = function(content) { console.log(content); };
+
+popup.displayName = 'Show Popup';
+
+console.log(popup.displayName); // "Show Popup"
+
+ +

関数式の displayName の定義

+ +

{{jsxref("Functions_and_function_scope", "関数式", "", 1)}}内で、関数と同時に表示名を定義できます。

+ +
var object = {
+  someMethod: function() {}
+};
+
+object.someMethod.displayName = 'someMethod';
+
+console.log(object.someMethod.displayName); // logs "someMethod"
+
+try { someMethod } catch(e) { console.log(e); }
+// ReferenceError: someMethod is not defined
+
+ +

動的な displayName の変更

+ +

関数の displayName を動的に変更できます。

+ +
var object = {
+  // anonymous
+  someMethod: function(value) {
+    arguments.callee.displayName = 'someMethod (' + value + ')';
+  }
+};
+
+console.log(object.someMethod.displayName); // "undefined"
+
+object.someMethod('123')
+console.log(object.someMethod.displayName); // "someMethod (123)"
+
+ +

仕様書

+ +

どの仕様にも含まれていません。

+ +

ブラウザーの互換性

+ +
+ + +

{{Compat("javascript.builtins.Function.displayName")}}

+
+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/global_objects/function/function/index.html b/files/ja/web/javascript/reference/global_objects/function/function/index.html new file mode 100644 index 0000000000..0cc3ed2489 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/function/function/index.html @@ -0,0 +1,91 @@ +--- +title: Function() コンストラクター +slug: Web/JavaScript/Reference/Global_Objects/Function/Function +tags: + - Constructor + - Function + - JavaScript + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Function/Function +--- +
{{JSRef}}
+ +

Function コンストラクターは、新しい Function オブジェクトを生成します。コンストラクターを直接呼び出すと動的に関数を生成することができますが、セキュリティや、 {{jsxref("eval")}} と似た性能の (ただし、はるかに重要性の低い) 問題を抱えます。ただし eval とは異なり、 Function コンストラクターはグローバルスコープで実行される関数のみを生成します。

+ +
{{EmbedInteractiveExample("pages/js/function-constructor.html","shorter")}}
+ + + +

構文

+ +
new Function([arg1 [, arg2 [, ...argN]] ,] functionBody)
+ +

引数

+ +
+
arg1, arg2, ... argN
+
仮引数の名前として関数で用いるための名前。各々は、妥当な JavaScript の識別子と一致する文字列か、カンマで区切られた文字列などのリストでなければなりません。例えば、 "x", "theValue", "x,theValue" などです。
+
functionBody
+
関数定義を形成する JavaScript の文を含む文字列。
+
+ +

解説

+ +

Function コンストラクターで生成された Function オブジェクトは、関数が作成されたときに解釈されます。これは、関数を{{jsxref("Operators/function", "関数式", "", 1)}}や{{jsxref("Statements/function", "関数文", "", 1)}}を使って定義してコード内で呼び出した場合に比べ、コードの他の部分と一緒に解釈されるため、効率が落ちます。

+ +

関数に渡されるすべての引数は、関数のパラメーター識別名として、渡される順番どおりに作成されます。引数を省略すると、その引数の値は undefined になります。

+ +

(new 演算子を用いずに) 関数として、Function コンストラクターを実行することは、コンストラクターとして実行することと同じです。

+ +

+ +

Function コンストラクターに引数を指定する

+ +

以下のコードは二つの引数を取る Function オブジェクトを生成します。

+ +
// この例は JavaScript コンソールで直接実行することができます
+
+// 二つの引数を取り、その合計を返す関数を生成します
+const adder = new Function('a', 'b', 'return a + b');
+
+// 関数を呼び出します
+adder(2, 6);
+// 8
+
+ +

引数 "a" および "b" は関数の本体 "return a + b" の中で使用される形式的な引数名です。

+ +

仕様書

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

ブラウザーの互換性

+ +
+ + +

{{Compat("javascript.builtins.Function")}}

+
+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/global_objects/function/index.html b/files/ja/web/javascript/reference/global_objects/function/index.html new file mode 100644 index 0000000000..25856fcd15 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/function/index.html @@ -0,0 +1,114 @@ +--- +title: Function +slug: Web/JavaScript/Reference/Global_Objects/Function +tags: + - Class + - Function + - JavaScript +translation_of: Web/JavaScript/Reference/Global_Objects/Function +--- +
{{JSRef}}
+ +

JavaScript の関数は、実際にはすべて Function オブジェクトです。これは、 (function(){}).constructor === Function というコードが true を返すことで確認することができます。

+ +

コンストラクター

+ +
+
{{jsxref("Function/Function", "Function()")}}
+
新しい Function オブジェクトを生成します。コンストラクターを直接呼び出すと関数を動的に生成することができますが、セキュリティや、 {{jsxref("eval")}} と似た性能の (ただし、はるかに重要性の低い) 問題を抱えます。ただし eval とは異なり、 Function コンストラクターはグローバルスコープで実行される関数のみを生成します。
+
+ +

インスタンスプロパティ

+ +
+
{{jsxref("Function.arguments")}}
+
関数に渡した引数に対応する配列です。
+ これは {{jsxref("Function")}} オブジェクトのプロパティとしては非推奨です。代わりに関数内に用意されている {{jsxref("Functions/arguments", "arguments")}} オブジェクト (関数内で使用可能) を使用してください。
+
{{jsxref("Function.caller")}}
+
現在実行している関数を呼び出した関数を返します。
+ このプロパティは非推奨であり、一部の厳格モードではない関数でのみ機能します。
+
{{jsxref("Function.displayName")}}
+
関数の表示名です。
+
{{jsxref("Function.length")}}
+
関数によって期待される引数の数を指定します。
+
{{jsxref("Function.name")}}
+
関数の名前です。
+
+ +

インスタンスメソッド

+ +
+
{{jsxref("Function.prototype.apply()", "Function.prototype.apply(thisArg [, argsArray])")}}
+
関数を呼び出し、 this を提供された thisArg に設定します。引数は {{jsxref("Array")}} として渡すことができます。
+
{{jsxref("Function.prototype.bind()", "Function.prototype.bind(thisArg[, arg1[, arg2[, ...argN]]])")}}
+
新しい関数を作成し、呼び出されたときに、 this を提供された thisArg に設定します。任意で、指定された一連の引数が、新しく結びつけられた関数が呼び出されたときに与えられた引数の前に付加されます。
+
{{jsxref("Function.prototype.call()", "Function.prototype.call(thisArg[, arg1, arg2, ...argN])")}}
+
関数を呼び出して、 this に提供した値を設定します。引数は、指定するオブジェクトのものとして渡すことができます。
+
{{jsxref("Function.prototype.toString()", "Function.prototype.toString()")}}
+
関数のソースコードを表す文字列を返します。
+ {{jsxref("Object.prototype.toString")}} メソッドを上書きします。
+
+ +

+ +

Funciton コンストラクターと関数宣言の違い

+ +

Function コンストラクターで生成された関数は、生成コンテキストにクロージャを作りません。つまり常にグローバルスコープで生成されます。これを実行すると、 Function コンストラクターの呼び出し元のスコープは入らず、自身のローカル変数とグローバル変数だけにアクセスできます。これは関数式のコードに {{jsxref("eval")}} を使うのとは異なります。

+ +
var x = 10;
+
+function createFunction1() {
+    var x = 20;
+    return new Function('return x;'); // この |x| はグローバルの |x| を表す
+}
+
+function createFunction2() {
+    var x = 20;
+    function f() {
+        return x; // この |x| は上記のローカルの |x| を表す
+    }
+    return f;
+}
+
+var f1 = createFunction1();
+console.log(f1());          // 10
+var f2 = createFunction2();
+console.log(f2());          // 20
+
+ +

このコードはウェブブラウザーでは動作しますが、 Node.js では f1()ReferenceError が発生します。 x が見つからないためです。これは Node の最上位のスコープがグローバルスコープではなく、 x はモジュールのローカルになるからです。

+ +

仕様書

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

ブラウザーの互換性

+ +
+ + +

{{Compat("javascript.builtins.Function")}}

+
+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/global_objects/function/length/index.html b/files/ja/web/javascript/reference/global_objects/function/length/index.html new file mode 100644 index 0000000000..f64e2ee9d7 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/function/length/index.html @@ -0,0 +1,76 @@ +--- +title: Function.length +slug: Web/JavaScript/Reference/Global_Objects/Function/length +tags: + - Function + - JavaScript + - Property +translation_of: Web/JavaScript/Reference/Global_Objects/Function/length +--- +
{{JSRef}}
+ +

length プロパティは、関数が期待する引数の数を示します。

+ +
{{EmbedInteractiveExample("pages/js/function-length.html")}}
+ + + +
{{js_property_attributes(0,0,1)}}
+ +

解説

+ +

length は function オブジェクトのプロパティであり、関数が期待する引数の数、つまり形式上の引数の数を示します。この数に{{jsxref("rest_parameters", "残余引数", "", 1)}}は含まれず、既定値を持つ引数が最初に登場する前までしか含みません。これに対し、 {{jsxref("Functions_and_function_scope/arguments/length", "arguments.length")}} は関数のローカルスコープ内で用いられ、関数が実際に受け取った引数の数、つまり実引数の数を参照するのに用いるものです。

+ +

Function コンストラクターのデータプロパティ

+ +

{{jsxref("Function")}} コンストラクター自体は、{{jsxref("Function")}} オブジェクトです。この length データプロパティの値は 1 です。プロパティの属性は、 Writable: false、Enumerable: false、Configurable: true です。

+ +

Function プロトタイプのオブジェクトのプロパティ

+ +

{{jsxref("Function")}} プロトタイプオブジェクトの length プロパティの値は 0 です。

+ +

+ +

関数の length の使用

+ +
console.log(Function.length); /* 1 */
+
+console.log((function()        {}).length); /* 0 */
+console.log((function(a)       {}).length); /* 1 */
+console.log((function(a, b)    {}).length); /* 2 etc. */
+
+console.log((function(...args) {}).length);
+// 0, rest parameter は数に含まれない
+
+console.log((function(a, b = 1, c) {}).length);
+// 1, 既定値を持つ引数が最初に登場する前までの
+// 引数だけが数に含まれる
+ +

仕様書

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

ブラウザーの互換性

+ +
+ + +

{{Compat("javascript.builtins.Function.length")}}

+
+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/global_objects/function/name/index.html b/files/ja/web/javascript/reference/global_objects/function/name/index.html new file mode 100644 index 0000000000..bdc6731b70 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/function/name/index.html @@ -0,0 +1,233 @@ +--- +title: Function.name +slug: Web/JavaScript/Reference/Global_Objects/Function/name +tags: + - ECMAScript6 + - Function + - JavaScript + - Property +translation_of: Web/JavaScript/Reference/Global_Objects/Function/name +--- +
{{JSRef}}
+ +

{{jsxref("Function")}} オブジェクトの name プロパティは読み取り専用で、作成時に付けられた関数の名前、もしくは無名関数の場合は anonymous または '' (空文字列) を返します。

+ +
{{EmbedInteractiveExample("pages/js/function-name.html")}}
+ + + +
{{js_property_attributes(0,0,1)}}
+ +
+

標準外であった ES2015 以前の実装では、configurable 属性も false であることに注意してください。

+
+ +

JavaScript の圧縮とミニファイ

+ +
+

警告: Function.name を使用しているときに、 JavaScript の圧縮 (ミニファイ) や難読化のような変換を行う際には注意が必要です。これらのツールは JavaScript ビルドパイプラインの一部として、本番環境に設置する前にプログラムのサイズを縮小するためによく使用されます。それらの変換は、ビルド時に関数名を変更することがあります。

+
+ +

次のようなソースコードは、

+ +
function Foo() {};
+let foo = new Foo();
+
+if (foo.constructor.name === 'Foo') {
+  console.log("'foo' は 'Foo' のインスタンスである");
+} else {
+  console.log('おおっと!');
+}
+
+ +

このように圧縮されるかもしれません。

+ +
function a() {};
+let b = new a();
+if (b.constructor.name === 'Foo') {
+  console.log("'foo' は 'Foo' のインスタンスである");
+} else {
+  console.log('おおっと!');
+}
+
+ +

非圧縮版では、プログラムは真の方の分岐を実行し、「'foo' は 'Foo' のインスタンスである」と表示するのに対し、圧縮版は異なる振る舞いをし、偽の方の分岐を実行します。それゆえ、上述の例のように Function.name に依存するならば、ビルドパイプラインが関数名を変更しないようにするか、特定の関数名を想定しない構造にする必要があります。

+ +

+ +

関数文の名前

+ +

name プロパティは関数文の名前を返します。

+ +
function doSomething() {}
+doSomething.name; // "doSomething"
+
+ +

Function コンストラクターの名前

+ +

構文 new Function(...) または単に Function(...) で関数を作成すると、 {{jsxref("Function")}} オブジェクトが作成され、その名前は "anonymous" になります。

+ +
(new Function).name; // "anonymous"
+ +

無名関数式

+ +

function キーワードを使用して生成された関数式またはアロー関数は、名前が "" (空文字列) になっています。

+ +
(function() {}).name; // ""
+(() => {}).name; // ""
+
+ +

関数名の推測

+ +

変数とメソッドは、構文上の位置から無名関数の名前を推論できます (ECMAScript 2015 から)。

+ +
let f = function() {};
+let object = {
+  someMethod: function() {}
+};
+
+console.log(f.name); // "f"
+console.log(object.someMethod.name); // "someMethod"
+
+ +

{{jsxref("Operators/Function", "関数式", "", 1)}} で名前を持つ関数を定義することができます。

+ +
let object = {
+  someMethod: function object_someMethod() {}
+};
+console.log(object.someMethod.name); // "object_someMethod" と表示
+
+try { object_someMethod } catch(e) { console.log(e); }
+// ReferenceError: object_someMethod is not defined
+
+ +

name プロパティは読み取り専用であり、代入演算子で変更することはできません。

+ + + +
 let object = {
+  // anonymous
+  someMethod: function() {}
+};
+
+object.someMethod.name = 'otherMethod';
+console.log(object.someMethod.name); // someMethod
+
+ +

変更したければ、{{jsxref("Object.defineProperty()")}} を使ってください。

+ +

短縮メソッドの名前

+ +
var o = {
+  foo(){}
+};
+o.foo.name; // "foo";
+ +

バインドされた関数の名前

+ +

{{jsxref("Function.bind()")}} が関数を作成する時、その名前は "bound " とその関数名を合わせたものとなります。

+ +
function foo() {};
+foo.bind({}).name; // "bound foo"
+
+ +

ゲッターとセッターの関数名

+ +

getset を使う時は、 "get" や "set" が関数名に含まれます。

+ +
let o = {
+  get foo(){},
+  set foo(x){}
+};
+
+var descriptor = Object.getOwnPropertyDescriptor(o, "foo");
+descriptor.get.name; // "get foo"
+descriptor.set.name; // "set foo";
+ +

クラスでの関数名

+ +

obj.constructor.name でオブジェクトの「クラス」を知ることができます (ただし、下記の警告を確認してください)。

+ +
function Foo() {}  // ES2015 構文の場合: class Foo {}
+
+var fooInstance = new Foo();
+console.log(fooInstance.constructor.name); // "Foo" と表示
+
+ +
+

警告: スクリプトインタープリターは、関数が自身の name プロパティを持っていない場合に限り、組み込みの Function.name プロパティを設定します (9.11.2. of the ECMAScript2015 Language Specification セクションをご覧ください)。しかし ES2015 では、static キーワードを指定すると、その静的メソッドはクラスのコンストラクタ関数の OwnProperty として設定されます (ECMAScript2015, 14.5.14.21.b + 12.2.6.9)。

+
+ +

従って、name() という静的メソッドを持つクラスでは、事実上そのクラス名を取得することはできません:

+ +
class Foo {
+  constructor() {}
+  static name() {}
+}
+
+ +

static name() メソッドが存在する場合、Foo.name はクラス名ではなく、 name() 関数オブジェクトへの参照を持つことになります。Chrome や Firefox では、上記の ES2015 の構文によるクラス定義は、下記の ES5 構文のコードと同じような挙動をします:

+ +
function Foo() {}
+Object.defineProperty(Foo, 'name', { writable: true });
+Foo.name = function() {};
+
+ +

fooInstance.constructor.namefooInstance のクラスを取得しようとしても、得られるのはクラス名ではなく静的メソッドへの参照です。例えば:

+ +
let fooInstance = new Foo();
+console.log(fooInstance.constructor.name); // 関数 name() を表示
+
+ +

先ほどの ES5 の構文の例では、Chrome や Firefox での Foo.name の静的な定義の際に writable を指定しています。このような独自の手法を用いなければ、デフォルトでは read-only となります:

+ +
Foo.name = 'Hello';
+console.log(Foo.name); // Foo が static name() を持つ場合は "Hello"、そうでなければ "Foo" と表示する。
+
+ +

従って、Function.name プロパティが常にクラス名を保持しているとは考えないほうがいいでしょう。

+ +

関数名としての Symbol

+ +

{{jsxref("Symbol")}} を関数名として使用し、Symbol が description を持っている場合、関数名はブラケット [ ] 内の description となります。

+ +
let sym1 = Symbol("foo");
+let sym2 = Symbol();
+let o = {
+  [sym1]: function(){},
+  [sym2]: function(){}
+};
+
+o[sym1].name; // "[foo]"
+o[sym2].name; // ""
+ +

仕様書

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

ブラウザーの互換性

+ +
+ + +

{{Compat("javascript.builtins.Function.name")}}

+ +

関連情報

+ + +
diff --git a/files/ja/web/javascript/reference/global_objects/function/tosource/index.html b/files/ja/web/javascript/reference/global_objects/function/tosource/index.html new file mode 100644 index 0000000000..6fdc0141be --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/function/tosource/index.html @@ -0,0 +1,69 @@ +--- +title: Function.prototype.toSource() +slug: Web/JavaScript/Reference/Global_Objects/Function/toSource +tags: + - Function + - JavaScript + - Method + - Non-standard + - Obsolete +translation_of: Web/JavaScript/Reference/Global_Objects/Function/toSource +--- +
{{JSRef}} {{obsolete_header}}
+ +

toSource() メソッドは、オブジェクトのソースコードを表す文字列を返します。このメソッドは通常、コード中で明示的に呼び出されるのではなく、 JavaScript から内部的に呼び出されます。デバッグ中にオブジェクトの内容を調査する目的で toSource() を呼び出すことができます。

+ +

構文

+ +
function.toSource();
+
+ +

返値

+ +

オブジェクトのソースコードを表す文字列です。

+ +

解説

+ +

ネイティブ関数

+ +

組込みの {{jsxref("Function")}} オブジェクトでは、 toSource() は次の文字列を返してソースコードが使用できないことを示します。

+ +
function Function() {
+  [native code]
+}
+
+ +

独自の関数

+ +

独自に作成した関数では、 toSource() はオブジェクトを定義する JavaScript のソースコードを文字列として返します。

+ +
// 例:
+function hello() {
+  console.log("Hello, World!");
+}
+
+hello.toSource();
+
+ +
// 結果:
+"function hello() {
+    console.log(\"Hello, World!\");
+}"
+ +

仕様書

+ +

いずれの標準仕様でも定義されていません。

+ +

ブラウザーの互換性

+ +
+ + +

{{Compat("javascript.builtins.Function.toSource")}}

+
+ +

関連情報

+ + diff --git a/files/ja/web/javascript/reference/global_objects/function/tostring/index.html b/files/ja/web/javascript/reference/global_objects/function/tostring/index.html new file mode 100644 index 0000000000..bd433a5b99 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/function/tostring/index.html @@ -0,0 +1,216 @@ +--- +title: Function.prototype.toString() +slug: Web/JavaScript/Reference/Global_Objects/Function/toString +tags: + - Function + - JavaScript + - Method + - Prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Function/toString +--- +
{{JSRef}}
+ +

toString() メソッドは、関数のソースコードを表す文字列を返します。

+ +
{{EmbedInteractiveExample("pages/js/function-tostring.html")}}
+ + + +

構文

+ +
function.toString()
+ +

返値

+ +

関数のソースコードを表す文字列です。

+ +

解説

+ +

{{jsxref("Function")}} オブジェクトは、 {{jsxref("Object")}} から継承した {{jsxref("Object.prototype.toString", "toString")}} メソッドをオーバーライドします。つまり、 {{jsxref("Object.prototype.toString")}} を継承しません。 {{jsxref("Function")}} オブジェクトについて、 toString メソッドは関数宣言を表現するオブジェクトを表す文字列を返します。

+ +

{{jsxref("Function")}} を文字列値として表現するとき、JavaScript は自動的に toString メソッドを呼び出します。例えば、関数が文字列と連結されるときです。

+ +

this 値のオブジェクトが Function オブジェクトでない場合、 toString() メソッドは {{jsxref("TypeError")}} 例外 ("Function.prototype.toString called on incompatible object") を発生します。

+ +
Function.prototype.toString.call('foo'); // TypeError
+
+ +

toString() メソッドが組込み関数オブジェクトや Function.prototype.bind 作成された関数に対して呼び出されると、 toString() は、次のようなネイティブ関数文字列を返します。

+ +
"function () {\n    [native code]\n}"
+
+ +

toString() メソッドが Function コンストラクターで生成された関数に対して呼び出されると、 toString() は "anonymous" という名前の関数宣言に、提供された引数と関数の本体を合成したソースコードを返します。

+ +

+ 演算子を使用して、関数の文字列表現を明示的に取得することもできます。

+ +
function foo() { return 'bar' }
+console.log(foo + ''); // "function foo() { return 'bar' }"
+ +

+ +

実際のソースコードと toString の結果との比較

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FunctionFunction.prototype.toString の結果
+
+function f(){}
+
+
+"function f(){}"
+
+
+class A { a(){} }
+
+
+"class A { a(){} }"
+
+
+function* g(){}
+
+
+"function* g(){}"
+
+
+a => a
+
+
+"a => a"
+
+
+({ a(){} }.a)
+
+
+"a(){}"
+
+
+({ *a(){} }.a)
+
+
+"*a(){}"
+
+
+({ [0](){} }[0])
+
+
+"[0](){}"
+
+
+Object.getOwnPropertyDescriptor({
+    get a(){}
+}, "a").get
+
+
+"get a(){}"
+
+
+Object.getOwnPropertyDescriptor({
+    set a(x){}
+}, "a").set
+
+
+"set a(x){}"
+
+
+Function.prototype.toString
+
+
+"function toString() { [native code] }"
+
+
+(function f(){}.bind(0))
+
+
+"function () { [native code] }"
+
+
+Function("a", "b")
+
+
+"function anonymous(a\n) {\nb\n}"
+
+ +

仕様書

+ + + + + + + + + + + + +
仕様書
{{SpecName('ESDraft', '#sec-function.prototype.tostring', 'Function.prototype.toString')}}
+ +

ブラウザーの互換性

+ +
+ + +

{{Compat("javascript.builtins.Function.toString")}}

+
+ +

関連情報

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