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

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

ただいまの
回答率

90.48%

  • JavaScript

    17082questions

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

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

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 1,126

ngyuki

score 4369

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

(function func(){
    console.log(func);  // [Function: func]
    func = 123;
    console.log(func);  // [Function: func]
}());

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

(function func(){
    console.log(func);  // [Function: func]
    func = 123;
    console.log(func);  // 123
}());

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

(function func(){
    var func;
    console.log(func);  // undefined
    func = 123;
    console.log(func);  // 123
}());

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

console.log(typeof func); // undefined
(function func(){
    var func;
    console.log(func);    // undefined
    func = 123;
    console.log(func);    // 123
}());
console.log(typeof func); // undefined

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

console.log(func);      // [Function: func]
function func(){
    console.log(func);  // [Function: func]
    func = 123;
    console.log(func);  // 123
}
func();
console.log(func);      // 123

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

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

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

名前付き関数式の内部での関数名の識別子は、通常の変数とは異なる何かなのでしょうか?
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+6

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 13:03

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

    外側のスコープと内側のスコープの間に ImmutableBinding として関数名の識別子がある感じなんですね

    キャンセル

+1

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

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

関連した質問

  • 解決済

    javascript インスタンス化

    初めまして、javascript prototype/インスタンス化に関しての質問です。  使い始めてから日が浅いので不手際ございましたら申し訳ありません。  またコードに不備が

  • 受付中

    未経験者にnullと0の違いを説明する方法

    新人にjavascriptを教えている最中ですが、 nullと0の違いがなかなか理解できないみたいです。 まったくのプログラム未経験者に伝えるにはどのように伝えれば Null

  • 解決済

    void 0, undefined, null の 違いを教えて下さい

     知りたいことリスト GC時の扱いが異なるのか?また異なるのはなぜか? undefined = true  //=> true となるのは何がいけないのか? Cof

  • 解決済

    オブジェクト、コンストラクタの考え方

    お世話になっております。 Javascriptの基礎的な部分を本気で理解しようとしているのですが、どうもどの参考書やサイトを見ても一足飛びのところがあり、腹落ちしない部分があ

  • 解決済

    JSでオブジェクトの中身が取り出せない

    Javascriptで、オブジェクトを扱っています。 以下のようにして取り出そうとおもっても undefinedになってしまいます。 var routeInfo = {}; r

  • 解決済

    JavaScriptの構文

    JavaScript勉強中のものです。 すごく基本的なことを聞いてしまいますが、 下記の構文は、どういう意味があるのでしょうか? ソースコード var hoge; (fun

  • 受付中

    JSのundefined対策について

    JavaScriptのundefined対策について、スマートな方法がないか試行錯誤しています。 例えば下記のList.jsの例では、msgList配列をmapでループする場合、m

  • 解決済

    javascriptでのnull値判断がうまくいかない

    問題点 javascriptでのnull(空文字?)値の判断がうまくいきません。if文に入らない。 何か間違っていますでしょうか。 ソースコード if (msg.err!=''

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

  • JavaScript

    17082questions

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