当前位置: 首页 > 面试题库 >

为什么instanceof在babel-node下的Error子类的实例上不起作用?

华煜祺
2023-03-14
问题内容

我看到在OS X的babel-node版本6.1.18 /
Node版本5.1.0
下运行时,该instanceof运算符不适用于Error子类的实例。这是为什么?相同的代码在浏览器中效果很好,请尝试我的小提琴作为示例

以下代码true在浏览器中输出,而在babel-node下为false:

class Sub extends Error {
}

let s = new Sub()
console.log(`The variable 's' is an instance of Sub: ${s instanceof Sub}`)

我只能想象这是由于babel-node中的错误所致,因为它instanceof适用于以外的其他基类Error

.babelrc

{
  "presets": ["es2015"]
}

编译输出

这是babel 6.1.18编译的JavaScript:

'use strict';

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Sub = (function (_Error) {
  _inherits(Sub, _Error);

  function Sub() {
    _classCallCheck(this, Sub);

    return _possibleConstructorReturn(this, Object.getPrototypeOf(Sub).apply(this, arguments));
  }

  return Sub;
})(Error);

var s = new Sub();
console.log('The variable \'s\' is an instance of Sub: ' + (s instanceof Sub));

问题答案:

tl; dr如果您使用的是Babel 6,则可以使用https://www.npmjs.com/package/babel-plugin-
transform-b​​uiltin-extend

Babel从未支持扩展诸如Arrayand
Error等这样的内置类型。它在真实的ES6环境中完全有效,但是存在使其难以与旧版浏览器兼容的方式进行转换的要求。它在Babel
5中“起作用”是因为它没有引发错误,但是从扩展子类实例化的对象却无法像预期的那样起作用,例如:

class MyError extends Error {}

var e1 = new MyError();
var e2 = new Error();

console.log('e1', 'stack' in e1);
console.log('e2', 'stack' in e2);

结果是

e1 false
e2 true

虽然没有出错,但子类却无法正确获得“堆栈”,就像应该错误一样。类似地,如果要扩展,Array它的行为可能有点像数组,并且具有数组方法,但它的行为却并不完全像数组。

Babel 5文档专门将其称为需要注意的类的边缘情况。

在Babel 6中,对类进行了更改,使其在处理子类时更加符合规范,其副作用是现在上面的代码 仍然
无法工作,但是将无法以不同于以往的方式工作。这已在https://phabricator.babeljs.io/T3083中进行了介绍,但在此我将详细介绍一个潜在的解决方案。

要返回Babel 5的子类化行为(记住,仍然不正确或不建议这样做),您可以将内置的构造函数包装在自己的临时类中,例如

function ExtendableBuiltin(cls){
    function ExtendableBuiltin(){
        cls.apply(this, arguments);
    }
    ExtendableBuiltin.prototype = Object.create(cls.prototype);
    Object.setPrototypeOf(ExtendableBuiltin, cls);

    return ExtendableBuiltin;
}

有了这个帮手,而不是做

class MyError extends Error {}

class MyError extends ExtendableBuiltin(Error) {}

但是,在您的特定情况下,您已经说过您在Node
5.x上。节点5支持本机ES6类,无需进行编译。我建议您通过删除es2015预设来使用它们,而改用来node5获得本机类,等等。在这种情况下,

class MyError extends Error {}

将以您期望的方式工作。

对于不是使用Node
4/5或仅使用最新Chrome的用户,您可能需要考虑使用https://www.npmjs.com/package/error之类的东西。您还可以浏览https://www.npmjs.com/package/babel-
plugin-transform-b​​uiltin-extend。在approximate从该选项是从巴贝尔相同的行为5.谨防非approximate行为肯定是边缘凯西,不得以的情况下100%的工作。



 类似资料:
  • Q、 给定整数数组nums,返回最长严格递增子序列的长度。 子序列是一个序列,可以通过删除一些元素或不删除任何元素而从数组中派生,而不改变其余元素的顺序。例如,[3,6,2,7]是数组[0,3,1,6,2,2,7]的子序列。 示例1: 输入:nums=[10,9,2,5,3,7,101,18] 输出:4 说明:最长的递增子序列为[2,3,7101],因此长度为4。 答案: 我的递归代码工作正常,但

  • 我的源XML文档 根据元素内容的模式,在元素中的元素中,我希望添加一个新的元素。元素是前导信息。因此,首先,我必须创建一个新的元素及其和内容。之后,我必须创建一个相应的元素,该元素具有相同的内容和特定的内容。 这是我的目标XML文档的示例(添加param03): 我的XSLT文档 结果XML文档错误 我遇到的问题: > 使用不会按预期更改节点上下文。新的元素将在最后一个位置添加到元素中,而不是按照

  • 问题内容: 我想在chromedp上使用代理,但是代理似乎不起作用,尝试了chromedp.ProxyServer 使用代理后,我得到了公共IPeven。无错误/警告 问题答案: 试试这个:

  • 我想了两个小时,为什么这段代码不能产生预期的结果。如果我输入3个整数,比如3、4和5,它应该给出所有27个可能的和(假设数字可以是正的、负的或零) 因此,它应该产生以下内容: -3-4-5=-12 -3-4 0 = -7 -4-4 5=3 等等

  • Stage.close()对我不起作用。 我查看了:JavaFX2.0:关闭一个舞台(窗口) 这是我的代码: 下面是调用消息框类的代码:

  • 问题内容: 我正在尝试将一个或元素垂直居中放置在另一个元素中。但是当我放进去时,什么也没发生。我尝试更改两个元素的属性,但似乎没有任何效果。 这是我当前在网页中执行的操作: 问题答案: 锁定了 160天。目前,此答案的内容已解决存在争议。它当前不接受新的交互。 这似乎是最好的方法-自我的原始文章以来已经过去了一段时间,现在应该这样做: