【问题标题】:hasOwnProperty is undefinedhasOwnProperty 未定义
【发布时间】:2020-09-21 18:14:34
【问题描述】:

我正在尝试使用lodash-es 包。由于它是一个 ES6 模块,因此 Babel 将其转译为 Jest。

Babel 配置是:

{
    "env": {
        "test": {
            "plugins": [
                "babel-plugin-rewire",
                "@babel/plugin-transform-modules-commonjs",
                "@babel/plugin-transform-runtime"
            ],
            "ignore": [
                "i18n/*.js"
            ]
        }
    }
}

但我已经得到了

Function.prototype.toString 要求 'this' 是 toString 处的函数

我尝试运行测试时出错。

我找到了错误所在的file,看起来像

Object.prototype.hasOwnPropertyundefined

我已经包含了下面代码的特定部分。

var funcProto = Function.prototype, objectProto = Object.prototype;
var funcToString = funcProto.toString;
var hasOwnProperty = objectProto.hasOwnProperty;
var reIsNative = RegExp('^' +
  // here hasOwnProperty is undefined leading to the error
  funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);

这是一个奇怪的错误。我尝试在node 中运行Object.prototype.hasOwnProperty,它工作正常。在这种情况下,我试图弄清楚它对undefined 的评估结果如何。

【问题讨论】:

  • 为什么你认为hasOwnPropertyFunction.prototype.toString 有任何关系?你有没有显示的代码?
  • @appleapple 它是 node_module 中的一个文件。当我执行yarn test 时发生错误。我尝试做console.error(objectProto),但这并没有出现在控制台中。但它不能未定义,因为objectProto.hasOwnProperty 没有导致错误。
  • 哦,我想你的意思是 objectProto.hasOwnPropert 不能是 undefined,对不起。
  • Lodash 代码被编写为无故障。 Function.prototype.toString 和 Object.prototype.hasOwnProperty 应该存在于任何合理的 JS 引擎中。你有这个问题意味着两件事,要么是这些原型被搞砸了,要么代码被 Babel 转换为 objectProto 不是指 Object.prototype 而是其他东西的方式。在这一点上,没有stackoverflow.com/help/mcve 就无法回答这个问题。根据您发布的内容,首先要怀疑的是 plugin-transform-runtime。
  • console.log(eval('Object.prototype') === objectProto) 添加到那个地方,以确保它是否是 Babel 的错。 console.log 是一种低效的调试方式,您可以在 Node 中使用 Chrome 进行调试。这包括 Jest,例如 node --inspect-brk node_modules/jest/bin/jest.js。对于 MCVE,您需要从当前设置派生的最简单的项目,并且仍然可以重现问题。

标签: javascript ecmascript-6 jestjs babeljs


【解决方案1】:

经过大量调试,我发现了问题。

Babel 将下面的 sn-p 从

var funcProto = Function.prototype, objectProto = Object.prototype;
var funcToString = funcProto.toString;
var hasOwnProperty = objectProto.hasOwnProperty;
var reIsNative = RegExp('^' +
  // here hasOwnProperty is undefined leading to the error
  funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);

被转译为以下内容:

var funcProto = Function.prototype, objectProto = Object.prototype;
var funcToString = _get__("funcProto").toString;
var hasOwnProperty = _get__("objectProto").hasOwnProperty;
var reIsNative = RegExp('^' + _get__("funcToString").call(_get__("hasOwnProperty")).replace(_get__("reRegExpChar"), '\\$&').replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$');

罪魁祸首是 Babel 引用它的变量的方式,但更重要的是,Lodash 是如何用属性命名它的变量的。

变量hasOwnProperty 被引用为_get__("hasOwnProperty"),这似乎删除了类似于众所周知的对象属性的变量名称。

所以,_get__("hasOwnProperty")undefined,而如果它被正常访问,如hasOwnProperty,它的功能就可以了。

所以,解决方法:

我刚刚将hasOwnProperty 重命名为hasOwnProp 和宾果游戏!它奏效了。

【讨论】:

  • 您是否为此向 Babel 提交了错误?
  • @Bergi 我刚刚想通了。我会尽快提交一份。
  • 很高兴您解决了这个问题。这似乎纯粹是 babel-plugin-rewire 的错,因为 _get__ 属于它。它不是官方插件,所以 Babel 不对这种混乱负责。而且 FWIW 它可能根本不需要与 Jest 一起使用,Jest 已经处理了模块模拟。
  • @EstusFlask 呃。我会看看没有插件是否构建成功。
  • @Bergi 猜这不是 Babel 相关的,而是一个独立的 Babel 插件。我会在那里归档。
猜你喜欢
  • 1970-01-01
  • 2011-12-30
  • 1970-01-01
  • 2021-12-11
  • 2021-02-28
  • 1970-01-01
  • 1970-01-01
  • 2019-10-30
相关资源
最近更新 更多