【问题标题】:Javascript check yield supportJavascript 检查产量支持
【发布时间】:2011-01-18 19:56:06
【问题描述】:

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

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

【问题讨论】:

    标签: javascript keyword yield yield-keyword


    【解决方案1】:

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

    var can_yield = (function(){ 
        try { 
            return eval("!!Function('yield true;')().next()"); 
        } 
        catch(e) { 
            return false; 
        } 
    })();
    

    【讨论】:

    • ahhhh 喜欢 JavaScript :)) +1 给你!
    【解决方案2】:

    yield 为 JavaScript 引入了新语法。您将无法使用yield,除非您通过在script type 属性(*) 中包含版本号来指定您需要新的JavaScript 语法。

    当您指定脚本版本时,只有支持给定版本的浏览器才会执行该块。所以只有 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 被完全忽略。 )

    【讨论】:

    • 遗憾的是,这无法检测 Chrome 是否打开了 Experimental JavaScript 标志,该标志从 31.x 版本开始在该浏览器中启用 yield。不过在 Firefox 中效果很好。
    【解决方案3】:

    这是我对原生 yield 支持的看法。

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

    Modernizr 测试

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

    性能 http://jsperf.com/yield-support

    【讨论】:

      【解决方案4】:

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

      This site 列出了哪些版本的浏览器支持哪些版本的 Javascript。

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

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

      【讨论】:

      • 那么没有浏览器嗅探就没有办法检查吗?
      • 这个答案已经过时了,因为已经发布了对 Google Chrome 的yield 支持。
      【解决方案5】:

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

      在启用了实验性 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”函数创建生成器的方法:Chrome 中的new Function('', '{yield 5;}');。如果你知道怎么做,请在下方留言。

      为了在 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 有效
      • Chrome 31 与实验性 JS 开启yield 有效
      • Chrome 31 带有实验性 JS 关闭yield 不起作用
      • IE10yield 不起作用

      【讨论】:

        【解决方案6】:

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

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

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

        可以完成...

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

        l.

        【讨论】:

        • C# 就是这么干的
        【解决方案7】:

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

        (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-05-06
          • 2010-10-12
          • 2014-12-25
          • 2016-09-02
          • 2012-10-28
          • 2015-03-15
          • 2014-04-12
          • 2010-11-23
          • 2011-07-29
          相关资源
          最近更新 更多