Q1. IE で使用可能な window.event
は標準化されているのでしょうか。
JavaScriptにて、配列の要素一つ一つにイベントを実装したい(15895)|teratail で notable さんより window.event
を使えば、event
オブジェクトを参照可能との回答を頂き、少し気になったので質問してみました。
私の見落としがあるかもしれませんが、7.2 The Window object - HTML Standardでは event
プロパティを発見できませんでした。
Google Chrome v44 でも window.event
を使用できましたが、非標準プロパティなのでいつでも廃止されうる&全実装で同じ挙動を期待できない不安定なものという認識でいました。
Q2. window.event
は使用するにあたって問題点はないのでしょうか。
私の認識では window.event
は他にイベントが発火したら書き換えられる不安定なプロパティなので原則使用すべきではないプロパティと認識していました。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
Q1.について
標準化されていないと思います。
私も、7.2 The Window object - HTML Standardを見ましたが、
該当するような箇所は見つかりませんでした。
w3cの仕様でもそうですね。
Q2.について
他のイベントが発火したら書き換えられる不安定なもの、という意味では、
イベントハンドラで処理している間に他のスレッドから書き換えられる事は、
仕様上は無いので、問題なさそうです。
ブラウザにバグがあって仕様を満たしていない場合は、
どうしようもありませんが。
Javascriptでのスレッドは、メインのスレッド1つと、Web Workerのスレッドしかなく、
Web Workerからはwindowオブジェクトを参照、操作できないためです。
Javascriptがシングルスレッドという事について
仕様のどの部分によるものか、私も気になっていましたので、
この機会に調べてみました。
仕様にあること、無いことをまとめると、以下の通りです。
ECMAScript 6
・[[Job]]を要素とするキューを持っており、キュー内の[[Job]]を順次実行していく。
・キューの割り込み処理は発生しうるが、[[Job]] の実行中は割り込みされない。
ECMAScript 5.1
・実行コンテキストのスタックがあり、スタックのトップにある実行コンテキストを使って処理が実行される。
・キューや割り込みについては記述が無い。
・スタックを新しく作るような記述が無いことから、シングルスレッドと推定できる。
WHATWG仕様
・イベント実行中は一つの [[Job]] と考えられ、イベント実行中は割り込み処理されない(setTimeout も同様)
そもそも、HTML5にはWeb Workerがあるので、シングルスレッドというのは正確ではないと思います。
ただ、Web Workerからはwindowオブジェクトは参照できない様なので
以降の記述では触れません。
ECMAScript 6仕様から分かること
ECMAScript 6の仕様には、シングルスレッドでの動作しか書かれていません。
以下の箇所が該当すると思います。
8.4 Jobs and Job Queues
Once execution of a Job is initiated, the Job always executes to completion. No other Job may be initiated until the currently running Job completes. However, the currently running Job or external events may cause the enqueuing of additional PendingJobs that may be initiated sometime after completion of the currently running Job.
Jobの実行中には、他のJobは実行されないこと、Jobの十個中にPendingJobsという別の
Jobをキューに追加することはあることが書かれています。
一応、初期化部分を見ると、
8.5 ECMAScript Initialization()
- In an implementation dependent manner, obtain the ECMAScript source texts (see clause 10) for zero or more ECMAScript scripts and/or ECMAScript modules.
For each such sourceText do,
a. If sourceText is the source code of a script, then
i. Perform EnqueueJob("ScriptJobs", ScriptEvaluationJob, « sourceText »).
b. Else sourceText is the source code of a module,
i. Perform EnqueueJob("ScriptJobs", TopLevelModuleEvaluationJob, « sourceText »).
のように、JobをEnqueueすることで処理を開始しており、その後の処理も
Jobの実行によって行われると解釈できると思います。
###WHATWGの仕様から分かること
WHATWGの仕様を見ても、以下のようにイベントループの説明があります。
8.1.4 Event loops
taskのキューがあって、それをイベントループが処理していくというような記述です。
There must be at least one browsing context event loop per user agent, and at most one per unit of related similar-origin browsing contexts.
ブラウジングコンテキストに対して、多くても1つしかイベントループがないと読めます。
1つのイベントループは1スレッドかどうか、ということになると思いますが、
イベントループの処理モデルを見ても、
An event loop must continually run through the following steps for as long as it exists:
の後に順番に処理するステップが書かれているだけで、マルチスレッドで処理するとは書かれていません。
また、
Each event loop has a currently running task.
とあり、「event loop has a currently running task 」なので、同時に実行するtaskは
イベントループ1つにつき1つと考えられます。
気にされているsetTimeoutについても、
taskの例として挙がっている
Events、Parsing、Callbacks、Using a resource、Reacting to DOM manipulation
の中のCallacksに該当すると考えられます。
また、以下の個所を見ても、
8.4 Timers
The timer initialisation steps, which are invoked with some method arguments, a method context, a repeat flag which can be true or false, and optionally (and only if the repeat flag is true) a previous handle, are as follows:
に記述されているステップの中に、
- Queue the task task.
とあり、これがイベントループのキューを使っていることを意味していると思います。
ECMAScript 6より前について
ECMAScript 5.1の仕様には、シングルスレッドで処理することについて、
はっきりとした記述が無い様に思います。
Jobのキューについても記述がありません。
仕様に書かれているのは、
「実行コンテキストのスタックがあり、スタックのトップにある
実行コンテキストを使って処理が実行される。」
「新しく作られた実行コンテキストは、スタックにプッシュされる。」
ことです。
別のスレッドを作るのであれば、スタックを新しく作る必要があると思いますが、
スタックを新しく作る、と言う記述は仕様中に見当たらないため、
スレッドは作られない、つまりシングルスレッドと解釈できるかな、というところです。
以下、参照した仕様と、私なりの日本語訳です。
When control is transferred to ECMAScript executable code, control is entering an execution context. Active execution contexts logically form a stack. The top execution context on this logical stack is the running execution context. A new execution context is created whenever control is transferred from the executable code associated with the currently running execution context to executable code that is not associated with that execution context. The newly created execution context is pushed onto the stack and becomes the running execution context.
ECMAScriptの実行可能コードに制御が移ると、実行コンテキストに入る。アクティブな実行コンテキストは論理的にスタックを構成する。スタックのトップの実行コンテキストは、実行中の実行コンテキストである。実行中の実行コンテキストに関連付いた実行コードから関連付いていない実行コンテキストに制御が移るときはいつも、新しい実行コンテキストが生成される。新しい実行コンテキストは、スタックのトップにプッシュされ、実行中の実行コンテキストになる。
(executeもrunも「実行」と訳したので、「実行中の実行コンテキスト」となり、
日本語として少しおかしくなってしまいました)
ECMAScript 3以前については、調べていませんが、
同様の記述があるのではないかと思います。
setTimeoutなどの非同期呼び出しについては、
strawman:oldes6 (ES Wiki)
の
Concurrency, Asynchrony, and Distributed Programming
あたりが元のようで、ES6より前には仕様化されていなかったように見えます。
投稿2015/09/28 05:39
編集2015/09/30 06:24総合スコア1546
0
-
現状でも、Firefox(Ver. 40で確認)には
window.event
はありません。 -
JavaScriptはシングルスレッド実行なので、リスナー内で使う分には他の場所から
window.event
を書き換えられる心配はありません。ただ、あとあと使いたい場合には、必要な値だけ保存しておく必要があります。
投稿2015/09/25 02:02
総合スコア145121
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/09/28 02:00
2015/09/28 03:41
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/09/28 05:43
2015/09/28 06:58
2015/09/28 15:03
2015/09/29 03:06
2015/09/30 06:26 編集
2015/10/01 03:12
2015/10/01 03:16
2015/10/01 03:22