azo*_*ria 1 javascript compatibility function cross-browser spread-syntax
对于那些不知道的人来说,扩展语法是将不确定数量的参数传递到函数中的一种便捷方法,类似于此示例:
function debug (mode, string, ...params) {
if (debug_enabled && window.console) {
console.log(mode+": "+string+"(",...params,");");
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,Internet Explorer 和其他旧版本的浏览器不支持此功能。这里有关于扩展语法和浏览器支持的更多信息。
我没有将扩展语法用于任何关键的事情,但是将其出现在网站上会导致 JavaScript 在那些较旧的浏览器上完全失败。
一种选择是我可以为旧版浏览器提供单独的脚本版本,然后根据用户代理传递此脚本。但是,我想避免这种情况,因为维护这两个文件和作为一般浏览器都很痛苦如果使用其他功能,这可能会变得更加复杂。此外,还存在对用户浏览器进行错误分类的风险。
另一种选择是找到一种方法来完全避免在所有功能中使用扩展语法。然而,这可能会增加开发时间并创建更难以理解和使用的代码。这似乎不是一个避免使用新功能的好策略,因为只有极少数的观众无法使用它们。
我希望有人可能拥有或知道一种聪明的方法来检测扩展语法的支持,并在用户浏览器不支持扩展语法的情况下排除部分脚本。通过这种方式,我可以为使用旧版浏览器的用户提供仍然可用的体验,并且只错过一些功能。我一直在网上搜索,但找不到任何执行此操作的代码。我认为这可能是不可能的,因为它是核心语法修改,但是我也找不到任何东西来完全确认这种情况。
在检查浏览器是否支持 spread 然后加载适当的脚本是可能的时,有一个更简单的选择:将像 Babel 这样的工具集成到您的构建过程中,以自动将 ES6+ 语法中的代码自动转译为 ES5。例如,如果将以下内容插入Babel中:
function debug (mode, string, ...params) {
if (debug_enabled && window.console) {
console.log(mode+": "+string+"(",...params,");");
}
}
Run Code Online (Sandbox Code Playgroud)
你得到
"use strict";
function debug(mode, string) {
if (debug_enabled && window.console) {
var _console;
for (var _len = arguments.length, params = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
params[_key - 2] = arguments[_key];
}
(_console = console).log.apply(_console, [mode + ": " + string + "("].concat(params, [");"]));
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在这里尝试演示。
这允许您使用该语言的最新和最好的版本进行编写、读取和调试,同时仍然允许过时的浏览器理解您的脚本的语法。
当然,Babel 不仅限于转译扩展语法 - 它可以将所有现代语法转译为 ES5(例如解构、对象扩展、求幂 ( **) 等等)。
也就是说,请注意语法的转译与新的内置函数不同。例如,Array.prototype.includes是一个 ES6 功能,但因为它是一个新函数,而不是新语法,所以它不会被转译 - 为了让旧浏览器也理解新函数,请使用 polyfill,例如polyfill.io。
如果您确实希望能够动态确定当前客户端是否支持扩展语法,您可以使用new Function来查看语法是否正确解析:
function debug (mode, string, ...params) {
if (debug_enabled && window.console) {
console.log(mode+": "+string+"(",...params,");");
}
}
Run Code Online (Sandbox Code Playgroud)
(但确实没有任何充分的理由这样做)