Поддержка проверки доходности Javascript - PullRequest
28 голосов
/ 19 февраля 2010

Я прочитал о ключевом слове yield в JavaScript, и мне нужно использовать его в своем проекте. Я читал, что это ключевое слово было реализовано начиная с определенной версии JS, поэтому я думаю, что старые браузеры не поддерживают его (верно?).

Есть ли способ проверить, поддерживается ли ключевое слово yield? или, по крайней мере, есть ли способ проверить, является ли версия JS больше или равна той, которая реализует это ключевое слово (1.7)?

Ответы [ 7 ]

33 голосов
/ 31 августа 2011

Вот функция для проверки возможности использования доходности.

var can_yield = (function(){ 
    try { 
        return eval("!!Function('yield true;')().next()"); 
    } 
    catch(e) { 
        return false; 
    } 
})();
14 голосов
/ 19 февраля 2010

yield вводит новый синтаксис в JavaScript. Вы не сможете использовать yield, если не указали, что хотите использовать новый синтаксис JavaScript, включив номер версии в атрибут * script type (*).

Когда вы указываете версию скрипта, блокировка будут выполняться только браузерами, которые поддерживают данную версию. Таким образом, только Firefox, а не IE, Opera или WebKit, выполнят верхний блок в:

<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 скрипта полностью игнорируется. )

9 голосов
/ 11 апреля 2013

Вот мой пример проверки нативной поддержки yield.

var canYield = (function(){try{yield;}catch(e){}}())!==undefined;

Модернизр тест

define(['Modernizr'], function( Modernizr ) {
  // native yield support.
  Modernizr.addTest('yield', (function(){try{yield;}catch(e){}}())!==undefined);
});

Производительность http://jsperf.com/yield-support enter image description here enter image description here

6 голосов
/ 19 февраля 2010

Строго говоря, только браузеры Mozilla поддерживают JavaScript. Все браузеры должны поддерживать ECMAScript, а более ранние версии JavaScript являются реализациями ECMAScript.

На этом сайте указано, какие версии Javascript поддерживаются в каких версиях браузера.

MSIE использует JScript. JScript не имеет выхода в этом. Поэтому использование yield ограничит поддержку браузером вашей страницы.

Попробуйте https://developer.mozilla.org/en/New_in_JavaScript_1.7 для получения информации об использовании JavaScript 1.7

4 голосов
/ 25 ноября 2013

Я провел много времени с yield в последнее время, и bobince не совсем ошибается, но Chrome 31 не интерпретирует версию JavaScript в 1,7 блока, даже с включенным флагом экспериментального JavaScript (chrome: // flags / # включить-JavaScript-гармонии). Из-за различий в реализации между Chrome 31 и Firefox метод Tymon Sturgeon не может обнаружить yield в Chrome 31 при включенном Experimental JS, хотя он очень близок. С помощью нескольких модификаций он может обнаружить наличие yield для Firefox и Chrome 31 с включенным Experimental JS.

Сначала я быстро расскажу о yield различиях (напишу это для ясности):

В Firefox:

var fooGen = function(){ yield 1; yield 2; };
var iterator = fooGen();
console.log(iterator.next());    // prints 1
console.log(iterator.next());    // prints 2

В Chrome 31 с включенным экспериментальным JavaScript:

// 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. Если вы знаете как, оставьте комментарий ниже.

Чтобы правильно определить yield в Firefox и Chrome, я использовал немного кода с некоторыми перемотками вперед и назад:

<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>

Проверено в:

  • Firefox 25 : yield работает
  • Chrome 31 с Experimental JS Вкл. : yield работает
  • Chrome 31 с Experimental JS Выкл. : yield не работает
  • и IE10 : yield не работает
2 голосов
/ 05 октября 2011

мы фактически реализовали «yield» программно в «чистом javascript», т. Е. БЕЗ ИСПОЛЬЗОВАНИЯ FIREFOX «yield», для пижам, заметив, что skulpt также делал то же самое.

теоретически, то же самое можно сделать либо вручную (т. Е. С помощью кропотливого ручного кодирования переведенной функции, следуя правилам превращения функции в генератор), либо запустив javascript через javascript-to-javascript переводчик языка (!)

что требуется для реализации такого «зверя», это то, что вы должны сделать функцию способной пропускать до точки, где она в последний раз «выходила» (с помощью оператора yield). таким образом, все переменные должны храниться во временном состоянии (!), и выполнение кода должно быть соответствующим образом изменено, чтобы принять эту временную информацию о состоянии. это включает в себя операторы while, для циклов, а также операторы "if".

это можно сделать ...

... но это всего лишь трудная задача: вам нужно эффективно написать целый компилятор, который анализирует любую программу javascript, затем «преобразует» ее и затем выводит измененный javascript.

л.

1 голос
/ 29 марта 2011

Whell, на самом деле есть некоторые методы, которые вы можете использовать, но я сомневаюсь, что такие методы имеют какое-либо реальное значение

(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")
...