質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • JavaScript

    20414questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

名前のある関数式は無名関数でしょうか?

解決済

回答 6

投稿

  • 評価
  • クリップ 2
  • VIEW 1,353

Lhankor_Mhy

score 9124

こちらの質問に回答したのですが、
JavaScript - JSの関数について教えてください。(59737)|teratail

ふと、「名前のある関数式は無名関数なのではないだろうか」という疑問がわきましたので、お教えいただきたく質問いたします。

var f = function fn(){};
f(); 
fn(); //エラーになる


というように、名前のある関数式は名前空間を占有しないので、無名関数なのでは、と思ったのですが、

(function factorial(x){ return (x<=1) ? 1 : x * factorial(x-1) })(num)


というように、自分の名前を参照することはできますので、どちらなのか分からなくなってきました。

ECMA2016の定義を見ると、

14.1.10 Static Semantics: IsAnonymousFunctionDefinition ( production )# 
ECMAScript® 2016 Language Specification

というものがあり、この定義ですと、名前のある関数式はAnonymousFunctionDefinitionではないようなのですが、これはこれでまた別の話なような気もしています。

明確な定義や出典が見つからなければ、「自分はこう思う」というようなご意見でもかまいません。よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 6

checkベストアンサー

+9

ES6以降では、関数宣言であっても名前が無い関数が書けます
※ 匿名が可能なのはexport defaultを使ってモジュールとして作成した場合のみです。それ以外はエラーになります。

export default function () {
  console.log("hoge");
}

以上を踏まえて、ECMAScript® 2016 Language Specification(以下、仕様書)を見ながら、解釈していきます。なお、ES6以降はES5以前と内部の仕様が大きく異なります。今回はECMAScript 2016での解釈であって、ES5以前については考察の対象外です。


はじめに「無名関数」の定義をはっきりさせなければなりません。原則、根拠は仕様書から行います。仕様書に明記されていない事柄のみ、計算科学およびプログラミング言語での慣習に基づく判断とします。

【その1】英語表記との同定

まず、"nameless function"という言葉は一度も仕様書には出てきません。ただ、慣習として、無名関数=匿名関数(anonymous function)とする場合が多い(Wikipeida[ja]:無名関数)ため、仕様書内の"anonymous function"の事を示すとします。

【その2】用語定義での記載

4.3 Terms and Definitionsでは各用語が定義されていますが、このリストに"anonymous function"はありません。そのため、他の文脈からどのように使われているかで、仕様書の作者がどのような意味で使用したを推定する必要があります。

【その3】文書内での記述

"anonymous function"は仕様書内で5回現れます。

14.1.3Static Semantics: BoundNames

"*default*" is used within this specification as a synthetic name for hoistable anonymous functions that are defined using export declarations.

14.4.2 Static Semantics: BoundNames

"*default*" is used within this specification as a synthetic name for hoistable anonymous functions that are defined using export declarations.

17 ECMAScript Standard Built-in Objects

Every built-in Function object, including constructors, that is not identified as an anonymous function has a name property whose value is a String. 

19.2.4.2 name

Anonymous functions objects that do not have a contextual name associated with them by this specification do not have a name own property but inherit the name property of %FunctionPrototype%.

26.2.2.1.1 Proxy Revocation Functions

A Proxy revocation function is an anonymous function that has the ability to invalidate a specific Proxy object.

それぞれの項目から次のように言えます。

  • 名前が無い関数宣言(export defaultでのみ使用可能)は"anonymous function"である。
  • 名前が無いジェネレーター宣言(export defaultでのみ使用可能)は"anonymous function"である。
  • Proxy無効関数は"anonymous function"である。

三番目の文はビルトイン関数に関してです。

"anonymous function"とされていないコンストラクタを含む全ての関数は、文字列を値としたnameプロパティを持つ。

四番目の文は何か特定の関数について言っているのでは無く、全ての関数について言及しています。

この仕様書によって文脈的な名前と関連づけられていない"anonymous function"は、自身にnameプロパティを持たず、Functionのプロトタイプから継承したnameプロパティを持つ。

問題は「この仕様書によって文脈的な名前と関連づけられていない」が"anonymous function"の必要条件なのか十分条件なのかです。名前が関連づけられた"anonymous function"や名前が関連づけられていない非"anonymous function"があるかはわかりません。

【その4】抽象操作(abstract operation)名での使用

"anonymous function"と名付けられているものに次があります。

14.1.10 Static Semantics: IsAnonymousFunctionDefinition ( production )

これはprudoctionにあたるコード自体(つまり定義の仕方)を検査するためのもので、prudoctionによって生成される物が何かと言うことを検査することではありません。定義としては、IsFunctionDefinitionがtrue、かつ、HasNameがfalseになるときだけ、trueになります。その条件を満たすのか下記です。

  • アロー関数(定義): ArrowParameters => ConciseBody
  • 関数式: function ( FormalParameters ) { FunctionBody }
  • ジェネレーター式: function * ( FormalParameters ) { GeneratorBody }
  • クラス式: class { ClassBody }
  • 継承ありクラス式: class extends LeftHandSideExpression { ClassBody }

IsAnonymousFunctionDefinitionの対象となるのは代入の右辺に現れることができるであるため、宣言は操作の対象として含まれていません。つまり、IsAnonymousFunctionDefinitionと宣言は全く無関係であり、対象となっていないため、検査自体ができません。

さらに、このIsAnonymousFunctionDefinitionが具体的にどう使われているかというと、関数が変数に代入されたときに関数のnameプロパティに変数名を入れる必要があるかどうかの判定に使われます(12.15.4 Runtime Semantics: Evaluation)。つまり、IsAnonymousFunctionDefinitionがtrueであっても、最終的に、関数のnameプロパティが設定されている場合があると言うことです。


以上のことから、それぞれの文脈と矛盾無く用語の定義を考えて、私はこのように解釈しました。

  • JavaScriptにおける無名関数(匿名関数、nameless function、anonymous function)とは、自身にnameプロパティを持たない関数、ジェネレーター、アロー関数、クラスである。関数宣言であるとか関数式であるとか関係無い。
  • JavaScriptにおける無名関数定義(匿名関数定義、nameless function definition、anonymous function definition)とは、名前が指定されていない関数宣言、ジェネレーター宣言、クラス宣言、関数式、ジェネレーター式、クラス式、アロー関数(定義)である。その後の変数の代入等により、生成された関数オブジェクトが無名関数では無くなる場合があり得る。

つまり、ECMAScirpt 2016においては、

var hoge = function() {
  console.log("hoge");
};

は、無名関数定義を使用しているが、生成される関数は無名関数では無い、というふうに解釈します。あくまで私の解釈であり、仕様書には用語定義がないため、絶対的に正しいと保証する物ではありません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/12/25 13:53

    おお、なるほど、なんか腑に落ちますね。
    つまり、使い捨てされない関数(式)は基本的に無名関数ではない、と。

    キャンセル

  • 2016/12/25 14:11

    変数やプロパティに代入される場合は、関数式でもジェネレーター式でもクラス式でもアロー関数であっても、無名では無い(つまり名前がある)と私は考えています。理由は単純に代入の処理によって関数のnameプロパティが設定されるからです。ただ、この動作はES6以降なので、そんなことはしてくれないES5以前は、もう直接記述することはないし、どうでもいいかなと思っています。

    キャンセル

+4

名前付き関数式
名前付き無名関数の哲学を考えてみた

無名関数に名前をつけたもの(名前付き無名関数[named anonymous function])という認識でよろしいかと思います。

無名関数それ自身で再帰ができるようになります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/12/24 16:26

    ありがとうございます。javascriptにおいて、関数式はすべて無名関数だというご見解ですね。
    他の言語ではどうなんでしょうか。たとえば「名前付きラムダ式」みたいなものが存在するんでしょうか。

    キャンセル

  • 2016/12/24 16:34

    様々な言語について詳しく知っているわけではないので、ためしに
    「名前付き無名関数 -JavaScript」でググって見ましたが、そのような実装されている他の言語は見当たらないですね。

    キャンセル

  • 2016/12/24 17:11

    なるほど。
    つまり、x = function f(){}のように書ける言語はまれなので、「名前付き関数式は無名関数に分類すべきなのか否か」と一般化せずに、javascriptローカルの問題として考える方が妥当、というところですかねー。

    キャンセル

+4

 Function#name (ECMAScript 2016 / ECMAScript 7)

ES2016 には次の一文があります。

Anonymous functions objects that do not have a contextual name associated with them by this specification do not have a name own property but inherit the name property of %FunctionPrototype%.

機械翻訳「この仕様で関連付けられたコンテキスト名を持たない匿名関数オブジェクト(Anonymous functions objects)は独自のプロパティを持たず、%FunctionPrototype% の name プロパティを継承します。」

従って、Function#name を利用する事でそれが匿名関数(Anonymous function)か識別する事が可能です。

function foo () {}     // Function Declaration (関数宣言)
console.log(foo.name); // "foo" (Named Function Declaration) ※名前付き関数宣言

console.log(function (){}.name);      // ""    (Anonymous Function Expression) ※匿名関数式
console.log(function bar (){}.name);  // "bar" (Named Function Expression) ※名前付き関数式
console.log((()=>{}).name);           // "bar" (Anonymous Arrow Function) ※匿名アロー関数

var piyo = ()=>{};      // Arrow Function
console.log(piyo.name); // "piyo" (Named Arrow Function) ※名前付きアロー関数 (厳密には、アロー関数自身に名前があるわけではありませんが…)

 一般呼称としての無名関数 (Nameless Function)

(私の観測範囲ではという前提付きですが)
一般に「無名関数」と呼ぶときには関数式と関数宣言を区別する為に使われる事が多いように感じています。

(使用例1) addEventListener の第二引数は関数宣言した変数を入れる方法と無名関数を入れる方法があります。
(使用例2) setTimeout の第一引数には無名関数を入れましょう。

いずれも「関数式」に置き換えても意味が通りますし、「無名関数式」である必然性はありません。
名前付き関数式にすれば再帰呼び出しも可能です。

setTimeout(function sample (i) {
  console.log(i);
  setTimeout(sample, 100, ++i);
}, 100, 0);

それでも「無名関数」という呼称がよく使われるのは「関数式」に馴染みがないからだと思います。
一般人からすれば「関数式 === 無名関数」であり、名前付き関数式の存在は知らない人が大半です。
ですので、「無名関数」という表現が使われた時には文脈的にそれが「関数式」を表しているのか、「無名関数式」を表しているのか読み取る必要があると考えます。

私は表現のゆらぎが嫌いなので必要であれば、「無名関数式」と書いています。
初心者が「無名関数」を理解させようとすると著者や文脈によって意味が変わる事で混乱させてしまいます。
「無名関数」は一種のバズワードだと思います。
raccy さんが仰るように仕様書の用語定義に「Anonymous Function(匿名関数)」「Nameless Function(無名関数)」はない為、積極的に使うべき用語ではないと思います。

 (余談) IE8- は名前付き関数式を関数宣言としても扱う

var f = function fn(){};
f();
fn(); //エラーになる

余談ですが、IE8- では上記コードはエラーにならず、関数呼び出し出来ます。
ECMAScript 上はエラーになるはずで IE8- のバグなのですが、ふと思い出したので参考まで。

Re: Lhankor_Mhy さん

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/12/25 13:37

    ありがとうございます。

    > 一種のバズワード
    マジですか…… 情報科学で定義があるような言葉だと思っていました。

    キャンセル

  • 2016/12/25 22:48

    Lhankor_Mhyさんのように十分に理解している人同士で会話する分には困りませんが、初心者に伝える言葉としては混乱をもたらしかねない言葉だと思います。
    (当人が『関数宣言』『無名関数』の分類しか知らなくて良い、と考えているならそれでもいいかもしれませんが…。)
    この質問の元となったスレッドでは、質問者は余所のサイトで見た「無名関数の説明」と「回答の中の説明」の矛盾に折り合いが付かなくて混乱されているようです。
    情報ソースのしっかりしたサイトだけ読めばいいのですが、初心者からするとそういうサイトは難しすぎると敬遠する傾向があるように思います。
    既にたくさんの「無名関数」の解説サイトがある以上、「その説明は厳密には間違っています」と主張してもなかなか受け入れてもらえない、と感じています。

    キャンセル

+1

※以下は私の考え方です

あんまり深く考えたことがないですね。。
(その域まで達していない(恥)

javascriptで表現すると、

var f = function fn(){};
は無名関数 + 関数名

var f = function (){};
は無名関数

(function factorial(x){ return (x<=1) ? 1 : x * factorial(x-1) })(num)
は即時関数 + 関数名

(function (x){ return (x<=1) ? 1 : x * factorial(x-1) })(num)
は即時関数

function
で定義しているものは関数(関数定義)

つまり、
var f = function fn(){};
は無名関数という事かなと考えます。

文献はないですが、
上記のように解釈しています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/12/24 16:12

    ありがとうございます。

    キャンセル

+1

そもそも、「無名関数」という区分自体がJavaScriptになじまないと個人的には思います。

コードで示しますが、

var foo = { bar: function(){ /* その1 */ } }
foo.bar();

foo.baz = function(){ /* その2 */ };

var tmp = function(){ /* その3 */ };
foo.quz = tmp;

このように、「リテラルに名前を書かなかった関数」が「オブジェクトのメソッドになる」ことすらごく普通にあるような言語です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/12/24 17:46

    ご回答ありがとうございます。

    あれ? 他の言語ではできないですか?

    キャンセル

  • 2016/12/24 17:55

    はい、「関数式を入れたプロパティ≒メソッド」となるのはJavaScriptの特徴です(C++やJava、Rubyでこのようなメソッドの作成はできません)。

    キャンセル

  • 2016/12/24 18:11

    なるほど、Pythonではできるはずなので、他言語でもそれなりにできるのかと思っていました。

    キャンセル

-2

あなたはたぶん、「関数宣言文」が分かっていないのだと思います。

以下の「関数宣言文」は
function fn() {}

var window.fn = function fn() {};
と等価です(ブラウザで実行するJavaScriptの場合に限定)。

「関数宣言文」は暗黙的に、グローバルオブジェックトのプロパティに関数オブジェクトを代入しているのです。それを省略した書き方に過ぎないのです。ただそれだけですよ。

※そんな言葉はない気がしますがこのページでは、名前がある関数を便宜的に「有名関数」と呼ぶことにします。

有名関数を代入したら代入式です。関数宣言文ではないのでグローバルオブジェックトのプロパティに設定されないので、呼び出せないだけです。

以下のサンプルコードを実行してみてください。

// 関数宣言文
function fn1() {
    console.log(this === window);
    console.log(this.fn1.name);
}

// 有名関数の代入式
var f2 = function fn2() {
    console.log(this === window);
    console.log(this.f2.name);
};

// 無名関数の代入式
var f3 = function() {
    console.log(this === window);
    console.log(this.f3.name);
};

fn1();
f2();
f3();

thisはwindowを指し示すのです。ですから当然、「window.fn1();」などと書いても呼び出せます。

無名関数は名前が定義されていないというだけです。変数f3に代入している関数は、無名関数でも何度も呼び出せるのです。nameを確認すると設定されていないことが分かります。確かに無名なのです。少なくともFirefoxとEdgeではそうなります。ですので呼び出せるかどうかと有名か無名かは関係のない概念です。区別しましょう。

※ただし、Chromeで実行すると、変数名が設定されています。これはChromeの独自仕様だと思います。名前は設定されないのが本来の仕様として正しいと思います。

名前のある関数式は名前空間を占有しないので、無名関数なのでは、と思ったのですが、

無名かどうかは名前があるかどうかです。名前空間がどうとかいう話は関係ありません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/12/24 21:58

    > 以下の「関数宣言文」は...
    「関数宣言文」とありますが、関数宣言(FunctionDeclaration)は文(Statement)ではありません。
    分類的には「宣言(Declaration)」でしょうか。
    https://www.ecma-international.org/ecma-262/7.0/index.html#sec-function-definitions
    https://www.ecma-international.org/ecma-262/7.0/index.html#sec-ecmascript-language-statements-and-declarations
    関数文(FunctionStatement)はたまに聞く表現ですが、この誤解はMDNにも原因があると考えています。
    http://okwave.jp/qa/q8212855.html

    キャンセル

  • 2016/12/24 23:34

    MDNなんかどうでもいいのですが、オライリーのJavaScriptでは「function文」と表現されています。「新たにJavaScriptの関数を定義するときに、function文を使用します」と。これも間違っているというお考えですかね。

    キャンセル

  • 2016/12/25 09:05 編集

    > オライリーのJavaScriptでは「function文」と表現されています。
    間違っていますね。
    オライリー本は通称としての表現をする事が多く、仕様に厳格な説明をしているとは言い難い表現をすることがあります。
    過去に読んだ『JavaScript 第五版』でも微妙な表現が何点か見受けられました。

    > MDNなんかどうでもいいのですが、オライリーのJavaScriptでは
    Lhankor_Mhyさんは ECMAScript 2016 仕様に沿った説明を求めていますので、参考にすべきはオライリー本ではなく、ECMAScript 2016 だと思います。

    キャンセル

  • 2016/12/25 13:03

    think49さんが「宣言は文ではない」「区別すべきもの」と考えているらしいということはわかりました。
    ECMAScript 2016 だけを根拠にするのなら、あとは、和訳の根拠でしかなくなります。

    「Statements」は「文」と訳すのが適切で、
    「Declarations」を「宣言文」と訳すのが適切ではないと考えた根拠は何でしょうか?

    キャンセル

  • 2016/12/25 14:24

    ありがとうございます。
    raccyさんと同じく、「代入された名前のない関数式は、名前でアクセスできるので無名関数ではない」というお考えですね。よく分かりました。

    あと、まあ、「関数定義文」については個人的には瑣末な問題かなあ、と思います。
    ただ、ECMAscriptに公式な日本語訳はないので、「関数定義文」と訳そうとかまわないと言えばかまわないのでしょうが、一般にステートメントは「文」と訳されるので誤解を生みやすいかと思います。
    (ただまあ、ブラウザによりますが、本来は「文」ではない関数定義をブロック内に記述しても動作してしまうので、関数定義「文」が実装上存在すると言えなくもない……)

    キャンセル

  • 2016/12/25 15:55 編集

    > ※ただし、Chromeで実行すると、変数名が設定されています。これはChromeの独自仕様だと思います。名前は設定されないのが本来の仕様として正しいと思います。

    違います。nameプロパティが設定させるのがES6以降での仕様です。ChromeとSafariとNode.jsは対応済み、Firefoxは53(開発中)から、Edgeは"Enable experimental Javascript features"を有効にすれば対応済み、IEは開発が停止しているため対応の見込み無し、です。
    https://kangax.github.io/compat-table/es6/#test-function_name_property_variables_(function)

    ES5について「だけ」の話であれば、ES5と明記していただいた方が話が通じます。私はJavaScriptの仕様に関する回答をするときは、要らぬ混乱を避けるために必ず明記するようにしています。

    キャンセル

  • 2016/12/26 03:25

    To: miu_ras さん
    当たり前のようにどこでも使われていると認識していました…。探してみたら結構見つかりますね。

    原文 http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf
    日本語 http://www2u.biglobe.ne.jp/~oz-07ams/2002/ecma262r3/

    原文 http://ecma-international.org/ecma-262/5.1/
    日本語 https://tsofthome.appspot.com/ecmascript.html
    日本語 http://www.shuwasystem.co.jp/products/7980html/3892.html (※書籍なのでWebサイトはありませんが、手元の本では「文」と「宣言」を確認できます)

    原文 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements
    日本語 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements

    原文 http://www.ibm.com/developerworks/library/wa-ecma262/
    日本語 https://www.ibm.com/developerworks/jp/web/library/wa-ecma262/

    『JavaScript 第5版(日本語訳)』 https://www.oreilly.co.jp/books/9784873113296/
    明らかに ECMAScript 2016 における Statement の節を「文」と説明しています。
    関数宣言があるべき部分の単語には「function 文」とあります。

    https://ja.wikipedia.org/wiki/%E6%96%87_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)

    逆に聞きますが、「Statements」は何と訳すのが適切とお考えでしょうか。また、その根拠は何でしょうか。
    「Declarations」を「宣言文」と訳すのが適切と考えた根拠は何でしょうか。
    オライリー本では「Declarations」が「宣言文」と訳されているのでしょうか(ここまで聞かれるとオライリー本の原文が気になります)。

    キャンセル

  • 2016/12/26 04:13 編集

    To: Lhankor_Mhy さん
    > (ただまあ、ブラウザによりますが、本来は「文」ではない関数定義をブロック内に記述しても動作してしまうので、関数定義「文」が実装上存在すると言えなくもない……)
    nanto_vi さんがまさにこの独自拡張仕様を FunctionStatement と呼んでいて感心した記憶があります。
    http://nanto.asablo.jp/blog/2005/12/10/172622
    当時は Firefox の独自拡張でしたが、teratailで raccy さんに ES6/ES7 仕様あたりで規定された、と教えて頂いた記憶があります。
    …が、探しても該当記述が見つかりませんでした。記憶違いでしょうか…。

    キャンセル

  • 2016/12/26 12:43

    > think49さん
    リンク先拝読。
    なるほどなるほど、ChromeなどとFirefoxのふるまいが違う理由はこういう事情でしたか。

    キャンセル

  • 2016/12/28 01:04

    think49さん
    think49さんが挙げたいくつかのサイトがthink49さんの根拠ということですかね…。一応、わかりました。ありがとうございました。

    「関数宣言は文ではない」「分類的には宣言」「オライリーは間違っている」とかなり強く書かれていましたがその根拠は挙げられていなかったので、根拠は何ですかと尋ねたまでです。気分を害されたならすみません。

    念のために書いておきますが、私は「宣言文」という言葉にこだわっているわけではありません。function文でも関数文でも大差ないと思います。文の仲間だと思っているのです。

    また仮に「関数宣言」という表現であっても「関数宣言は文の仲間です」という説明だったら、表現上の小さな差異くらいにしか感じません。ですが「文ではない、別の分類です」になると違和感を感じます。

    私が重要に感じている点としてES6以降で分類が変わり、Statementsの章にDeclarationsが組み込まれたことが挙げられます。この変化は、「区別すべきもの」ではなく「同じ分類で扱うべきもの」と判断したということだと私は思うのですけどね。

    キャンセル

  • 2016/12/28 01:30

    To: miu_ras さん
    > ES6以降で分類が変わり、Statementsの章にDeclarationsが組み込まれたことが挙げられます。
    私の見落としでしたら申し訳ないのですが、Statement に統合された事が分かるURLがあれば教えて頂ければ有難いです。
    ES6 では "Statements and Declarations" となっているので Declarations が Statements に統合されたというより、Statements と Declarations をまとめて一つの章で説明するように編集したものと認識しています。
    Syntax を読む限りでは、Statement, Declaration がそれぞれ頂点にあるので、それで分類できるものと理解していました。
    http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-statements-and-declarations
    もし、13章の見出しが「ECMAScript Language: Statements」で Syntax 上で Statement の中に Declaration が含まれていたらなら、私も Declaration が Statement に含まれると判断すると思います。

    キャンセル

  • 2016/12/28 09:43

    横から(になるのかな?)すみません。

    たとえば、「ごはん類、めん類およびパン類」という表現を読んで「パンはめん類だ」と主張することは、かなりずれています。「パンはめん類の仲間だ」という表現はあいまいな部分がありますが、大抵の人は「ああ、『パンは主食だ』と言いたいのだろう」と正しく読むと思います。

    miu_rasさんは、「Declaration は上位分類である『Statements and Declarations』の仲間である」とおっしゃりたいのではないか、と感じました。
    これをやわらかく「関数宣言は文の仲間である」と省略して表現することは、Declaration が Statement に含まれていないことは文法上明らかですので、いらぬ誤解を生むであろうとは思います。
    もちろん、普段はそれほど厳密な表現にこだわる必要はない、と思います。実は質問文冒頭に書いた質問で、私も「関数定義文」という言葉を使っています。

    ただ、miu_rasさんが『違和感を感じます』とまでおっしゃることには、いささか違和感があります。「パンはめん類ではない」という表現も正しいのでは、と思うのですが。

    キャンセル

同じタグがついた質問を見る

  • JavaScript

    20414questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。