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

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

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

Q&A

解決済

2回答

2318閲覧

JavaScript の名前付き関数式の名前への再代入

ngyuki

総合スコア4514

JavaScript

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

0グッド

1クリップ

投稿2014/11/24 00:12

下記のコードを Node.js 0.10.26 / Chrome 39 / FireFox 33.1 のいずれで実行しても、console.log の引数の func は関数オブジェクトになります。

lang

1(function func(){ 2 console.log(func); // [Function: func] 3 func = 123; 4 console.log(func); // [Function: func] 5}());

てっきり↓こうなると思っていました。

lang

1(function func(){ 2 console.log(func); // [Function: func] 3 func = 123; 4 console.log(func); // 123 5}());

関数内部で var func を付けると、func は普通の変数になります。

lang

1(function func(){ 2 var func; 3 console.log(func); // undefined 4 func = 123; 5 console.log(func); // 123 6}());

もちろん、関数式の外側のスコープに関数式の名前の識別子は存在しません。

lang

1console.log(typeof func); // undefined 2(function func(){ 3 var func; 4 console.log(func); // undefined 5 func = 123; 6 console.log(func); // 123 7}()); 8console.log(typeof func); // undefined

関数宣言の場合は再代入すれば普通に値が変わるため、関数宣言の関数名の識別子は普通の変数のように思います。

lang

1console.log(func); // [Function: func] 2function func(){ 3 console.log(func); // [Function: func] 4 func = 123; 5 console.log(func); // 123 6} 7func(); 8console.log(func); // 123

再代入できないものとして this とか null とかを思いつきましたが、これらに再代入しようとするとエラーになります。

lang

1null = 123; // ReferenceError: Invalid left-hand side in assignment

名前付き関数式の内部での関数名の識別子は、これらの再代入できない this や null とも違う動きをしますし、通常の変数の識別子とも違う動きをするように思います。

名前付き関数式の内部での関数名の識別子は、通常の変数とは異なる何かなのでしょうか?

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

ECMAscript の仕様書によると、

13 Function Definition

(中略)

The production
FunctionExpression : function Identifier ( FormalParameterListopt ) { FunctionBody }
is evaluated as follows:

  1. Let funcEnv be the result of calling NewDeclarativeEnvironment passing the running execution context’s Lexical Environment as the argument
  2. Let envRec be funcEnv’s environment record.
  3. Call the CreateImmutableBinding concrete method of envRec passing the String value of Identifier as the argument.

 
(後略)

とあり、CreateImmutableBinding とはなんじゃろな、と思ってその項を読むと、

10.2.1.1 Declarative Environment Records

Each declarative environment record is associated with an ECMAScript program scope containing variable and/or function declarations. A declarative environment record binds the set of identifiers defined by the declarations contained within its scope.

In addition to the mutable bindings supported by all Environment Records, declarative environment records also provide for immutable bindings. An immutable binding is one where the association between an identifier and a value may not be modified once it has been established.

とのことで、イミュータブルということらしいですから変更ができないのは仕様通りということになります。

投稿2014/11/24 02:27

Lhankor_Mhy

総合スコア36104

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ngyuki

2014/11/24 04:03

ご回答ありがとうございます。 外側のスコープと内側のスコープの間に ImmutableBinding として関数名の識別子がある感じなんですね
guest

0

間違えて回答に投稿してしまったので削除したい

投稿2014/11/24 04:03

ngyuki

総合スコア4514

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問