28

我阅读了 JavaScript 中的 yield 关键字,我需要在我的项目中使用它。我读到这个关键字是从某个版本的 JS 开始实现的,所以我认为旧浏览器不支持它(对吗?)。

有没有办法检查是否支持 yield 关键字?或者至少有办法检查 JS 的版本是否大于或等于实现该关键字的版本(1.7)?

4

7 回答 7

33

这是一个检查是否可以使用 yield 的函数。

var can_yield = (function(){ 
    try { 
        return eval("!!Function('yield true;')().next()"); 
    } 
    catch(e) { 
        return false; 
    } 
})();
于 2011-08-30T20:40:55.100 回答
14

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不幸的是,脚本的 ' 完全被忽略了。)

于 2010-02-19T16:09:09.853 回答
9

这是我对检查本机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 在此处输入图像描述 在此处输入图像描述

于 2013-04-11T18:11:09.430 回答
6

严格来说,只有 Mozilla 浏览器支持 JavaScript。所有浏览器都应该支持 ECMAScript,旧版本的 JavaScript 是 ECMAScript 的实现。

该站点列出了哪些版本的浏览器支持哪些版本的 Javascript。

MSIE 使用 JScript。JScript 中没有 yield。因此,使用 yield 会限制浏览器对您的页面的支持。

尝试https://developer.mozilla.org/en/New_in_JavaScript_1.7获取有关使用 JavaScript 1.7 的信息

于 2010-02-19T15:23:14.680 回答
4

我最近花了很多时间yield,并且 bobince 并没有完全错误,但是 Chrome 31 不会将 JavaScript 版本解释为 1.7 块,即使打开了 Experimental JavaScript 标志(chrome://flags/#enable-javascript-和谐)。由于 Chrome 31 和 Firefox 之间的实现差异,Tymon Sturgeon 的方法无法yield在启用 Experimental JS 的 Chrome 31 中检测到,尽管它非常接近。通过一些修改,它可以在yield启用 Experimental JS 的情况下检测 Firefox 和 Chrome 31 的存在。

首先,我将快速介绍yield差异(为了清楚起见,写很长的路要走):

在火狐中:

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>

测试:

  • Firefox 25yield有效
  • 带有实验性 JS 的Chrome 31yield有效
  • 关闭实验性 JS 的Chrome 31yield不起作用
  • IE10yield不起作用
于 2013-11-25T06:25:16.087 回答
2

我们实际上在“纯javascript”中以编程方式实现了“yield”,即不使用Firefox“yield”,用于睡衣,注意到skulpt也做了同样的事情。

从理论上讲,完全相同的事情可以手动完成(即通过遵循如何将函数转换为生成器的规则,费力地手工编写翻译后的函数)或通过 javascript-to-javascript 语言翻译器运行 javascript( !)

实现这样的“野兽”所需的是,您必须使函数能够跳到上次“退出”的位置(通过 yield 语句)。因此,所有变量都必须存储在临时状态(!)中,并相应地更改代码执行,以接受此临时状态信息。其中包括 while 语句、for 循环以及“if”语句。

可以做到...

...但这只是一份工作:您需要有效地编写一个完整的编译器来解析任何 javascript 程序,然后“转换”它,然后输出修改后的 javascript。

l.

于 2011-10-04T20:39:42.143 回答
1

嗯,实际上有一些你可以使用的技术,但我怀疑这些技术有什么真正的价值

(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")
于 2011-03-29T10:20:59.420 回答