我阅读了 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
当您指定脚本版本时,只有支持给定版本的浏览器才会执行该块。因此,只有 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
不幸的是,脚本的 ' 完全被忽略了。)
这是我对检查本机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);
});
严格来说,只有 Mozilla 浏览器支持 JavaScript。所有浏览器都应该支持 ECMAScript,旧版本的 JavaScript 是 ECMAScript 的实现。
该站点列出了哪些版本的浏览器支持哪些版本的 Javascript。
MSIE 使用 JScript。JScript 中没有 yield。因此,使用 yield 会限制浏览器对您的页面的支持。
尝试https://developer.mozilla.org/en/New_in_JavaScript_1.7获取有关使用 JavaScript 1.7 的信息
我最近花了很多时间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>
测试:
yield
有效yield
有效yield
不起作用yield
不起作用我们实际上在“纯javascript”中以编程方式实现了“yield”,即不使用Firefox“yield”,用于睡衣,注意到skulpt也做了同样的事情。
从理论上讲,完全相同的事情可以手动完成(即通过遵循如何将函数转换为生成器的规则,费力地手工编写翻译后的函数)或通过 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")