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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Internet Explorer

Internet Explorer(IE;MSIE)はマイクロソフトが開発したウェブブラウザです。Microsoft Windowsに組み込まれています。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

JavaScript

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

Q&A

解決済

2回答

6883閲覧

window.event の標準化及び使用の是非について

think49

総合スコア18156

Internet Explorer

Internet Explorer(IE;MSIE)はマイクロソフトが開発したウェブブラウザです。Microsoft Windowsに組み込まれています。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

JavaScript

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

0グッド

4クリップ

投稿2015/09/09 00:36

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ページで確認できます。

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

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

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

guest

回答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()

  1. 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:

に記述されているステップの中に、

  1. Queue the task task.

とあり、これがイベントループのキューを使っていることを意味していると思います。

ECMAScript 6より前について

ECMAScript 5.1の仕様には、シングルスレッドで処理することについて、
はっきりとした記述が無い様に思います。
Jobのキューについても記述がありません。

仕様に書かれているのは、
「実行コンテキストのスタックがあり、スタックのトップにある
実行コンテキストを使って処理が実行される。」
「新しく作られた実行コンテキストは、スタックにプッシュされる。」
ことです。
別のスレッドを作るのであれば、スタックを新しく作る必要があると思いますが、
スタックを新しく作る、と言う記述は仕様中に見当たらないため、
スレッドは作られない、つまりシングルスレッドと解釈できるかな、というところです。

以下、参照した仕様と、私なりの日本語訳です。

10.3 Execution Contexts

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
eripong

総合スコア1546

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

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

eripong

2015/09/28 05:43

ECMAScript 6の仕様を見ていたので、それ以前についてどうかは、別途見てみます。
think49

2015/09/28 06:58

ES6, HTML Living Standard 仕様に沿った詳細な説明ありがとうございます。ES6 についてはまだ理解が浅い為、とても参考になりました。 説明をまとめると、こういう事でしょうか。 ・ES6 では [[Job]] の単位でキューを持っており、キューを順次実行していく。 ・キューの割り込み処理は発生しうるが、[[Job]] の実行中は割り込みされない。 ・WHATWG 仕様ではイベント実行中は一つの [[Job]] と考えられ、イベント実行中は割り込み処理されない(setTimeout も同様) まだ回答の途中のようですので、質問を締め切るのはもう少し待ちたいと思います。
eripong

2015/09/28 15:03

ECMAScript 6より前について追記しました。 説明まとめ、ありがとうございます。 概ねその通りと思います。 > ・ES6 では [[Job]] の単位でキューを持っており、キューを順次実行していく。 これだけ表現に違和感がありますが、認識は合っていると思います。 私が違和感ない書き方にすると、 ・[[Job]]を要素とするキューを持っており、キュー内の[[Job]]を順次実行していく。 です。 せっかくまとめて頂いたので、後で回答に反映しておこうと思いますが良いでしょうか?
think49

2015/09/29 03:06

ES5 もまとめ頂き、ありがとうございます。 ES3 を読んでみましたが、序文は同一で "A new execution context..." (新しい実行コンテキスト)の説明が ES5 で初めて追加されたようです。 http://bclary.com/2004/11/07/#a-10 > せっかくまとめて頂いたので、後で回答に反映しておこうと思いますが良いでしょうか? 是非、違和感のない形でよろしくお願い致します。
eripong

2015/09/30 06:26 編集

まとめを追記しました。 ES3も、明確には書かれていないが推測はできる、という感じですね。
think49

2015/10/01 03:12

ありがとうございます。 まだ、全てを理解したとは言い難いですが、時間のある時に再度読み直したいと思います。
eripong

2015/10/01 03:16

再度読み返した際にでも、間違った箇所があれば教えていただければと思います。
think49

2015/10/01 03:22

わかりました。何度も補足頂きましてありがとうございました。
guest

0

  1. 現状でも、Firefox(Ver. 40で確認)にはwindow.eventはありません。

  2. JavaScriptはシングルスレッド実行なので、リスナー内で使う分には他の場所からwindow.eventを書き換えられる心配はありません。ただ、あとあと使いたい場合には、必要な値だけ保存しておく必要があります。

投稿2015/09/25 02:02

maisumakun

総合スコア145121

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

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

think49

2015/09/28 03:28 編集

ありがとうございます。クロスブラウザ上の問題があるという事ですね。 > 2. JavaScriptはシングルスレッド実行なので シングルスレッドについては理解が及んでいないのですが、setTimeout や XMLHttpRequest のような非同期処理でも割り込みが入る事はないという認識で良かったでしょうか。 JavaScript がシングルスレッドであるという理屈はよく耳にしますが、それが仕様上のどこで保証されているのかを見つけられなくてもやもやしています。
maisumakun

2015/09/28 02:00

JavaScriptの動作は、「イベントで呼び出された関数が終わるまでは次のイベント関数を呼ばない」ようになっています(setTimeoutは一種のイベント操作なので、登録した関数とは非同期で動作します)。なお、Web Workerは非同期で動作しますが、DOMへのアクセスはできません。 window.alertすら標準に定義されているわけではないようですが頻繁に使っていますし、JavaScript界隈は「Break the Web」になるような変化を極力避けますので、ある程度は現実の実装に依存するような形になるのも仕方ないところではあるでしょう。
think49

2015/09/28 03:41

> JavaScriptの動作は、「イベントで呼び出された関数が終わるまでは次のイベント関数を呼ばない」ようになっています 例えば、window.setTimeout は HTML Living Standard (HTML5) に仕様がありますが、setTimeout 実行中は割り込み処理が入らない事を仕様のどの記述で保証されている事が分かるでしょうか。 http://momdo.github.io/html5/webappapis.html#timers https://html.spec.whatwg.org/multipage/webappapis.html#timers > window.alertすら標準に定義されているわけではないようですが頻繁に使っていますし window.alert は HTML5 で標準化されました。 http://momdo.github.io/html5/browsers.html#the-window-object MDN で便宜上、「DOM Level 0」と定義された仕様の大半は HTML5 で標準化されています。 https://spec.whatwg.org/ を見ると今まで曖昧だった(デファクトスタンダードであるものの標準化されていなかった)仕様の大半が標準化されてきているように思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問