【问题标题】:Confirming ES5 support确认 ES5 支持
【发布时间】:2013-12-12 14:01:14
【问题描述】:

在 Javascript (CoffeeScript) 前端应用程序中,通知用户他们的浏览器不受支持,而不是在用户随机点击不受支持的 ES5 功能时让它故障转移的最佳和最简单的方法是什么?比如说,我正在为现代浏览器编写一些东西,我想避免在我的代码使用 ES5 引入的功能的任何地方遇到旧浏览器会遇到的无数故障......通过阻止非兼容 ES5 浏览器?

ES5 引入了一些语法特性,我相信 CoffeeScript 依赖其中的一些特性,如果浏览器不支持 ES5,我希望我的代码能够以某种方式避免执行,而不是调整 shims、使用 Modernizr 或检查每个 CoffeeScript 语法子集,以计算它支持的向后程度。只需 ES5 和一个干净的“我们很抱歉您的浏览器太旧”页面,适用于世界其他地方。

我不希望编写测试每个 ES5 功能的代码,也不一定依赖诸如 http://kangax.github.io/es5-compat-table/ 之类的合规性表来检查浏览器类型和版本(尽管,如果没有更好的选择,我会求助于后者。 .).

【问题讨论】:

  • modernizr 告诉您用户的浏览器必须提供哪些 HTML、CSS 和 JavaScript 功能。

标签: javascript coffeescript ecmascript-5


【解决方案1】:

这里没有神奇的解决方案。

对于每个仅限 ES5 的功能(Object.* 方法或 String.prototype.* 方法或新语法 — getter、setter 等),您有 3 个选项:

  1. 垫片。
  2. 在执行之前测试它是否受支持,如果不支持则退出。
  3. 让它失败(可能使用粗略的全局 try-catch 块)。

为什么?

因为没有“ES5”浏览器之类的东西。

“ES5”不是可以评估的布尔值。正如你所看到的那样。表,ES5 是一个相当大的功能集。这些功能是由不同的浏览器/平台在分块、在不同的时间以及各种合规性实现的。

当然,你总能想出一些巧妙的推理测试:

var isEngineES5Compliant = 'create' in Object && 
                           'isArray' in Array && 
                           'x'[0] === 'x';

但我相信你明白这有多脆弱。

如果浏览器支持一种方法,而您尝试调用另一种方法(该方法可能可用也可能不可用),那么通常不会产生任何好处。会有误报/误报,也会有失败。

您说您只为现代浏览器编写代码,但您究竟如何定义现代浏览器?是完全支持 ES5 的那个吗?或者至少是您的代码正在使用的 ES5 的一个子集?在这种情况下,您需要确切地知道那是什么子集。

话虽如此,如果我们绝对必须提出推理测试来确定完全符合 ES5,我会选择:

(function () { 
  "use strict";
  return Function.prototype.bind && !this;
}());

这将检查对“严格模式”的支持(实际上只是严格模式的一部分,但它可能就足够了)和Function.prototype.bind 的存在。

这两个功能都是浏览器实现的最后一个功能,因此我们正在研究 IE10+、Firefox 4+、Safari 6+、Chrome 13+ 和 Opera 12+。

请注意,甚至其中一些浏览器并不完全符合 ES5 标准(但主要是关于 obscure-ish features)。

现在,如果您想要真正现代浏览器...测试ES6 features 怎么样? :)

【讨论】:

  • 看起来删除strict mode 要求确实很好地放宽了最低要求,坦率地说,无论如何我都必须了解更多它的好处和许多细节。我猜在每个浏览器版本上运行单元测试将是提供更多保护的好方法,但提前知道要定位哪些浏览器肯定会有所帮助。感谢维护that table
【解决方案2】:

我正在考虑使用以下 try catch 来测试 es6 的某些子集。

现在在 chrome 中可以正常工作:

try {
    eval(`
        'use strict';

        class hello {
            get hello() { return 123; }
        }
    `);
} catch(e) {
   console.log('es6 classes are disabled :(')
}

将其转换为 es5 以测试 getter 可能如下所示:

try {
    (function() {
        eval('var dfojdfoj12 = { get hello() { return 123; } }');
    })();
} catch(e) {
   console.log('es5 getters do not exist')
}

【讨论】:

    【解决方案3】:

    为了“优雅地”失败(比如显示正确的解释而不是白页或乱码),我们选择使用Dialog for Unsupported Browsers 中描述的方法删除样式和内容

    测试 CSS 动画支持和 Function.prototype.bind(在加载像 es5-shim 这样的任何脚本之前)工作正常。请注意,如果你想在 PhantomJS 中测试你的东西,你需要加载那个 shim

    【讨论】:

    • 不支持的浏览器的链接对话框谈论的最重要的事情是 OP 的重点:如何确定我们是否'是在谈论旧的浏览器,不一定是检测之后的技术,而这正是本文真正要讨论的......
    猜你喜欢
    • 2018-09-18
    • 2020-03-21
    • 1970-01-01
    • 2017-04-29
    • 2019-04-18
    • 2016-08-20
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    相关资源
    最近更新 更多