JavaScript の yield キーワードについて読みましたが、それを自分のプロジェクトで使用する必要があります。このキーワードは特定のバージョンの JS から実装されていると読んだので、古いブラウザーではサポートされていないと思います (右?)。
yield キーワードがサポートされているかどうかを確認する方法はありますか? または、少なくとも JS のバージョンがそのキーワードを実装するバージョン (1.7) 以上であるかどうかを確認する方法はありますか?
JavaScript の yield キーワードについて読みましたが、それを自分のプロジェクトで使用する必要があります。このキーワードは特定のバージョンの JS から実装されていると読んだので、古いブラウザーではサポートされていないと思います (右?)。
yield キーワードがサポートされているかどうかを確認する方法はありますか? または、少なくとも JS のバージョンがそのキーワードを実装するバージョン (1.7) 以上であるかどうかを確認する方法はありますか?
これは、yieldを使用できるかどうかを確認するための関数です。
var can_yield = (function(){
try {
return eval("!!Function('yield true;')().next()");
}
catch(e) {
return false;
}
})();
yield
JavaScript に新しい構文を導入します。属性 (*)yield
にバージョン番号を含めて、新しい JavaScript 構文が必要であることを指定しない限り、使用することはできません。script type
スクリプトのバージョンを指定すると、指定されたバージョンをサポートするブラウザーのみがブロックを実行します。そのため、IE、Opera、WebKit ではなく、Firefox のみが次のブロックを実行します。
<script type="text/javascript;version=1.7">
function x() {
yield 0;
}
var canyield= true;
</script>
<script type="text/javascript">
if (!window.canyield) {
// do some fallback for other browsers
}
</script>
type
(*:属性で指定されたタイプとバージョンは、外部スクリプトが取得、実行されるかどうか、および実行モードを排他的に決定することに注意してください。Content-Type
残念ながら、スクリプトの は完全に無視されます。)
厳密に言えば、Mozilla ブラウザのみが JavaScript をサポートしています。すべてのブラウザーは ECMAScript をサポートする必要があり、古いバージョンの JavaScript は ECMAScript の実装です。
このサイトには、どのバージョンのブラウザでどのバージョンの Javascript がサポートされているかがリストされています。
MSIE は JScript を使用します。JScript には yield がありません。したがって、yield を使用すると、ページのブラウザー サポートが制限されます。
JavaScript 1.7 の使用に関する情報については、https://developer.mozilla.org/en/New_in_JavaScript_1.7を試してください。
私は最近多くの時間を費やしましたがyield
、bobince は完全に間違っているわけではありませんが、Experimental JavaScript フラグがオンになっていても、Chrome 31 は JavaScript バージョンを 1.7 ブロックに解釈しません (chrome://flags/#enable-javascript-調和)。Chrome 31 と Firefox の実装の違いにより、Tymon Sturgeon の方法はyield
、Experimental JS がオンになっている Chrome 31 では検出できませんが、非常に近いものです。いくつかの変更を加えると、yield
Experimental JS がオンになっている Firefox と Chrome 31 の両方で の存在を検出できます。
最初に、yield
違いを簡単に説明します (わかりやすくするために長く書いています)。
Firefox の場合:
var fooGen = function(){ yield 1; yield 2; };
var iterator = fooGen();
console.log(iterator.next()); // prints 1
console.log(iterator.next()); // prints 2
実験的な JavaScript が有効になっている Chrome 31 の場合:
// Note the *
var fooGen = function*(){ yield 1; yield 2; };
var iterator = fooGen();
console.log(iterator.next().value); // prints 1
console.log(iterator.next().value); // prints 2
.value
はオブジェクトを生成するため、Chrome では必須ですが、さらに重要なことに、ジェネレーターでは関数定義に「*」が必要です。また、大文字の「F」関数からジェネレーターを作成する方法が見つかりませんでしnew Function('', '{yield 5;}');
た。Chrome で。方法を知っている場合は、下にコメントを残してください。
Firefox と Chrome で適切に検出するためyield
に、いくつかのコードを前後に使用しました。
<script type="application/javascript">
var can_yield = (function(){
try {
// Assuming Chrome's generator syntax
var funcUsingYield = new Function('', '{ var interp = function* generator(){ yield true; }}');
return true;
} catch(e) {
return false;
}
})();
</script>
<script type="application/javascript;version=1.7">
// Redefine the `can_yield` function inside a JS1.7 block. Probably safe to simply return true
can_yield = (function(){
try {
return eval("!!Function('yield true;')().next()");
}
catch(e) {
return false;
}
})();
</script>
<script type="application/javascript">
if(!can_yield)
{
alert("Can't Yield!");
}
</script>
テスト済み:
yield
動作しますyield
動作yield
動作しませんyield
動作しませんスカルプトも同様に行ったことに注意した後、実際にプログラムで「純粋なjavascript」、つまりパジャマ用のFIREFOX「yield」を使用せずに「yield」を実装しました。
理論的には、まったく同じことを手動で (つまり、関数をジェネレーターに変換する方法に関する規則に従って、翻訳された関数を手作業でコーディングすることによって)、または javascript-to-javascript 言語トランスレーターを介して javascript を実行することによって行うことができます ( !)
そのような「ビースト」を実装するために必要なのは、(yield ステートメントによって) 最後に「終了」したポイントまで関数をスキップできるようにする必要があることです。したがって、この一時的な状態情報を受け入れるには、すべての変数を一時的な状態 (!) に格納し、それに応じてコード実行を変更する必要があります。これには、while ステートメント、for ループ、および "if" ステートメントが含まれます。
それはできる...
...しかし、それは単なる仕事です。JavaScriptプログラムを解析し、それを「変換」して、変更されたJavaScriptを出力するコンパイラ全体を効果的に作成する必要があります。
l.
まあ、実際に使用できるテクニックがいくつかありますが、そのようなテクニックに実際の価値があるとは思えません
(function test_key_word(keyword){
var wrong = false;
try {
eval(keyword + "=42");
}
catch(e) {
wrong = true;
} finally {
if (wrong) { return "definitely wrong" }
else
if (window[keyword] !== 42) {
return "very probably, wrong"
}
else {
return "can be acceptable, but nevertheless i wouldn't rely upon such tests"
}
}})("in")