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

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

ただいまの
回答率

90.48%

  • JavaScript

    16995questions

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

  • Webサイト

    1099questions

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

  • Internet Explorer

    295questions

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

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

解決済

回答 2

投稿

  • 評価
  • クリップ 4
  • VIEW 2,739

think49

score 12161

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 は他にイベントが発火したら書き換えられる不安定なプロパティなので原則使用すべきではないプロパティと認識していました。

掲示板/JavaScript質問板[過去ログ]/一覧/onkeydown、onload、keyCodeに関して - TAG index Webサイト
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+4

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()
8. 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:
に記述されているステップの中に、
14. 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 14:43

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

    キャンセル

  • 2015/09/28 15:58

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

    キャンセル

  • 2015/09/29 00:03

    ECMAScript 6より前について追記しました。

    説明まとめ、ありがとうございます。
    概ねその通りと思います。

    > ・ES6 では [[Job]] の単位でキューを持っており、キューを順次実行していく。
    これだけ表現に違和感がありますが、認識は合っていると思います。
    私が違和感ない書き方にすると、
    ・[[Job]]を要素とするキューを持っており、キュー内の[[Job]]を順次実行していく。
    です。

    せっかくまとめて頂いたので、後で回答に反映しておこうと思いますが良いでしょうか?

    キャンセル

  • 2015/09/29 12:06

    ES5 もまとめ頂き、ありがとうございます。
    ES3 を読んでみましたが、序文は同一で "A new execution context..." (新しい実行コンテキスト)の説明が ES5 で初めて追加されたようです。
    http://bclary.com/2004/11/07/#a-10

    > せっかくまとめて頂いたので、後で回答に反映しておこうと思いますが良いでしょうか?
    是非、違和感のない形でよろしくお願い致します。

    キャンセル

  • 2015/09/30 15:24 編集

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

    キャンセル

  • 2015/10/01 12:12

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

    キャンセル

  • 2015/10/01 12:16

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

    キャンセル

  • 2015/10/01 12:22

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

    キャンセル

0

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

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

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/09/26 19:52 編集

    ありがとうございます。クロスブラウザ上の問題があるという事ですね。

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

    キャンセル

  • 2015/09/28 11:00

    JavaScriptの動作は、「イベントで呼び出された関数が終わるまでは次のイベント関数を呼ばない」ようになっています(setTimeoutは一種のイベント操作なので、登録した関数とは非同期で動作します)。なお、Web Workerは非同期で動作しますが、DOMへのアクセスはできません。

    window.alertすら標準に定義されているわけではないようですが頻繁に使っていますし、JavaScript界隈は「Break the Web」になるような変化を極力避けますので、ある程度は現実の実装に依存するような形になるのも仕方ないところではあるでしょう。

    キャンセル

  • 2015/09/28 12: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/ を見ると今まで曖昧だった(デファクトスタンダードであるものの標準化されていなかった)仕様の大半が標準化されてきているように思います。

    キャンセル

関連した質問

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

  • JavaScript

    16995questions

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

  • Webサイト

    1099questions

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

  • Internet Explorer

    295questions

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