【问题标题】:JS: Array has no method 'keys' (Cordova, Android)JS:数组没有方法“键”(Cordova,Android)
【发布时间】:2018-04-28 23:23:57
【问题描述】:

我正在从一个可映射函数初始化一个新数组:

let data = Array.from(Array(20).keys(), new_datum);

它将 webpack'd (v 3.5.5) 用于:

var data = Array.from(Array(20).keys(), new_datum);

为了完整起见,这里是那个函数,虽然我怀疑它是否相关:

function new_datum() {
  return {
    name: Math.floor((Date.now() - START_TIME) / 1000),
    Temperature: Math.random() * 100
  }
}

这在我桌面上的 Chrome 浏览器中运行良好。但是,当使用 Cordova (v 7.1.0) 和 Android (26) 将其编译为 SDK 并在我的手机上运行时(kitkat 4.4.4、Chrome 56.0.2924.87),我得到以下信息:

Uncaught TypeError: Object [object Array] has no method 'keys' 

我的直觉是,“一些 ECMA6 的东西”,因为 Array.keys() 方法很新,但是由于我对 JS 还是很陌生,所以我很难过。

编辑:另外,查看应用程序的 userAgent:

5.0 (Linux; Android 4.4.4; XT1080 Build/SU6-7.7) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36 

我看到 Cordova 出于某种奇怪的原因使用 Chrome 33。这很可能是问题所在。

附录:

由于我确认 Cordova 应用程序确实在使用 Chrome 33,这可能是 Array 方法无法正常工作的原因。

看起来有一些 limitations with respect to WebView 和 Cordova chrome 版本。有workarounds,但我怀疑最简单的方法就是为 Chrome 33 开发应用程序。

【问题讨论】:

  • FWIW 如果有帮助,我会从 let data = Array.from(Array(20), new_datum); 获得与 let data = Array.from(Array(20).keys(), new_datum); 相同的输出。
  • “这是否意味着 Cordova 实际上在使用 Chrome 33?” 我会这么说,是的。 Chrome 56 绝对支持Array.prototype.keys(以及之前的许多版本。)

标签: javascript android arrays cordova


【解决方案1】:

你是对的,错误告诉你运行该代码的平台使用了一个不提供 Array.prototype.keys 的 JavaScript 引擎,这是 ES2015 的新功能(所以,并不是真的那么新)。 Chrome 早在 v56 之前就有了,因此您运行该代码的环境不是 Chrome 56。我认为您的代码由 Chrome 33 运行可能是对的。

您唯一的选择是升级平台或不在代码中使用Array.prototype.keys。如果你走后一条路线,我会对 ES2015 中的许多其他新事物持怀疑态度。


作为Andy points out,无论如何都没有理由在那里使用Array#keys。只是

let data = Array.from(Array(20), new_datum);

let data = Array.from({length:20}, new_datum);

足够了(前提是平台支持letArray.from)。

【讨论】:

  • 解决了.keys(),但现在它抱怨Array.from()。粗糙的。我只需要 20 个项目,所以我只是手动粘贴。我认为问题是 Chrome 33。必须在 Cordova 中更新它。
  • @DeusXMachina:是的,我认为(“下一个”问题)会发生。 :-)
  • 将此标记为答案,因为您忠实地回答了我的“主要”问题。但是,就 Cordova 的 Chrome version 而言,我确实看起来像 somewhat hamstrung,所以我必须在开发时牢记这一点。
【解决方案2】:

Cordova 没有使用任何特定版本的 chrome,甚至可能根本没有使用 chrome。

让我解释一下:cordova 所做的是它使用 Webview 组件将您的 html 捆绑到本机应用程序中。

对于 Android,根据您使用的设备,webview 组件的引擎会有所不同。它可能基于旧的 android 浏览器、设备制造商的浏览器或使用高于 4.4 chrome 的 android 的设备。而且对于大多数设备,webview 无法更新。

所以每个设备的应用行为是不同的:html5支持,css支持,严格模式,js版本,是否需要配置Content-Security-Policy...

每次用户在新设备上使用您的应用时,您可能会对 cordova 感到惊讶。

您必须使用您所针对的最旧平台版本支持的javascript / css / html(您可以参考canIuse),同时符合最新要求(如强制启动的内容安全策略)安卓 4.4)。

从 Android 5.0 开始,webview(基于 chrome)在 apk 中并且可以更新,因此在 android 5 设备上运行的 cordova 应用程序将能够使用最新的 html5 功能。

如果您想确保您的应用在所有设备上都以相同的方式运行(屏幕大小除外),我认为目前最好的选择是使用Crosswalk

Crosswalk 是基于最新版本 Chromium 的 web 视图。

如果您将 Crosswalk Cordova plugin 添加到您的应用程序,cordova 将使用人行横道引擎而不是系统 webview,因此您的应用程序将在所有设备上使用相同的引擎,并且您不会再对在设备上运行的 javascript 行感到惊讶但不是其他人。

使用 Crosswalk 的唯一缺点是您将 Chromium 引擎嵌入到您的 apk 中,这使它变得更大(apk 增加 17Mb,安装应用后设备增加 50Mb)。

编辑:很遗憾听到官方 Crosswalk 项目的 EOL。 2.3 版在 Cordova 插件中完美运行,希望以后有人更新。

【讨论】:

  • 我明白了。如果我真的想要所有 HTML5/ECMA6 功能,我会走这条路。然而,Crosswalk 的 EOL 让我对它的依赖感到紧张。考虑到我的平台来编写对我来说很容易(我认为我不会在 4.4 之前支持。iOS 将是……一种有趣的体验,我敢肯定)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-16
  • 1970-01-01
  • 2017-03-22
相关资源
最近更新 更多