Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?

Flash Advent Calendar 6日目 - クロージャのスコープ問題 -

今日はちょっと小休憩的な感じで書きたいと思います。

FlashのActionScriptをエミュレーションする中で
クロージャーのスコープ問題にぶつかりました。

JavaScriptの実装になれていればすんなり解決していたと思うのですが・・・

ActionScriptサンプル


import flash.display.MovieClip;
import flash.events.Event;

public class Main extends MovieClip
{
    public function Main ()
    {
        super();
        this.addEventListener(Event.ENTER_FRAME, this._onEnterFrame);
    }

    private function _onEnterFrame ()
    {
        trace(this);
    }
}

_onEnterFrameで出力される情報は

[object Main]

つまり、スコープはクラスに向いています。

これが、JavaScriptだと

new Main(); // <= [Window]が出力される

と、globalのwindowクラスに向いてしまいます。

当時、ここが全然理解できず結構苦戦しました。。。
JavaScript - MDN - Mozillaを徘徊してbindを見つけました。

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

ActionScriptをエミュレートするには、JavaScript側でthis._onEnterFrame関数に対してbind(this)をコールしてスコープを確約させる必要があります。

this.addEventListener(Event.ENTER_FRAME, this._onEnterFrame.bind(this));

解決してしまえば、それほど大きな問題ではないのですが
当時は結構苦戦しました。。。

また、この後、ActionScriptのaddEventListenerの仕様で
同一のスコープで、同一の関数は追加しない。っという仕様にぶつかったのですが
きっとJavaScriptだけで実装していれば関わらない仕様だと思うのでサラッと書きます。

ドキュメントにあるようにbind関数をコールすると新しい関数が生成されます。

const method = this._onEnterFrame.bind(this);
console.log(method === this._onEnterFrame); // false

既存の関数から新たにスコープが確約された関数が生成されます。
なので、元の関数と生成された関数は別物として扱われます。

こういった、ActionScriptとJavaScriptの挙動の違いを詰めていく調査と検証に大きな時間がかかってしまいました。

ただ、その副産物でJavaScript特有の仕様や機能など知る事もできたので
言語を理解するという点ではとても勉強になり
今でも仕事で役に立っているので結果オーライですw

明日は、WebWorkerに関して書こうと思います!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?