【问题标题】:How can I extend the Array class in Babel?如何在 Babel 中扩展 Array 类?
【发布时间】:2016-10-30 01:20:21
【问题描述】:

我想定义一个检查堆栈末端的快捷方法。

以下在 Firefox 中有效:

const Stack = class extends Array {
  last() {
    return this[this.length - 1];
  }
}

但是,用 Babel 编译后,它不起作用:

var Stack = function (_Array) {
  _inherits(Stack, _Array);

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

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

  _createClass(Stack, [{
    key: 'last',
    value: function last() {
      return this[this.length - 1];
    }
  }]);

  return Stack;
}(Array);


console.log(Stack.prototype.last); // works
console.log((new Stack()).last); // doesn't work
Array.prototype.last = Stack.prototype.last;
console.log((new Stack()).last); // works

出于某种原因,我可以将函数添加到新原型中,但除非它们直接插入到 Array 原型中,否则它们将不可用于该原型的实例(由于潜在的副作用,这显然是不好的做法) .


更新:可能有几种方法可以解决这个问题(包括代理对象,或者手动扩展原型而不是使用extends),但因为我的Stack 并没有真正需要大部分 Array 方法,我现在只是使用包装器。

  const Stack = class {
    constructor(...x) {
      this.arr = [...x];
    }
    pop() {
      return this.arr.pop();
    }
    push(...x) {
      return this.arr.push(...x);
    }
    top() {
      return this.arr[this.arr.length - 1];
    }
    size() {
      return this.arr.length;
    }
  }

【问题讨论】:

标签: javascript babeljs


【解决方案1】:

我不确定 Babel 是否支持,但 node.js 从版本 4.3.2 开始支持(部分)Array 子类化,并在版本 6.8.1 (http://node.green/#Array-is-subclassable) 中实现了完整的子类化支持。因此,如果您使用的是节点 6,Array 子类化应该可以工作。

如果 Babel 失败了,你总是可以用“经典”的方式来做:

// Code tested and works in 6.3.1:
function Stack = () {};
Stack.prototype = Object.create(Array.prototype);
Stack.prototype.last = function () {
    return this[this.length - 1];
}

var s = new Stack();

【讨论】:

  • “经典”方式的问题不是返回新数组的数组方法(如.slice())不返回您的派生类型吗?
  • @jfriend00:这不是原型继承或类继承的问题。毕竟,ES6 规范使类只是原型之上的语法糖——它们是同一回事。问题是对子类化的支持。 ES6 规定 Array 可以被子类化。大多数浏览器尚不支持此功能,但 node.js 从 4.3.2 开始支持。我在我的一个项目中使用过它,它的工作方式与您期望的数组完全一样 - 直到 x[y] 语法在您的子类数组上正常工作
  • 谢谢,问题确实出在 Babel 上(在更新 NodeJS 以完全可以运行未转译的文件之后)。我现在使用一个包装类并显式传递 push()/pop() 方法。
【解决方案2】:

你可能会使用这个插件(Babel 6): https://www.npmjs.com/package/babel-plugin-transform-builtin-extend

该插件描述了 IE

更新:但是 Babel 7 甚至不需要这个插件。

【讨论】:

  • 嘿,你能详细说明一下这个更新吗?我正在使用 Babel 7,但在扩展 Map 类时遇到问题。我应该如何设置它?
  • 我不记得具体细节,但我会提出一个新问题,说明您遇到的错误(如果是在编译期间或当您尝试使用生成的编译代码时)在特定环境中)以及您尝试过的任何插件。
  • 升级到 Babel 7 是我唯一可行的选择
【解决方案3】:

这就是我的解决方案。现在 myArray 对象被视为 myArray 而不是 Array 类类型

class myArray extends Array
{
    constructor(...args) {
        super(...args);
    
        this.constructor = myArray;
        this.__proto__ = myArray.prototype;
    };
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-19
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    • 2016-05-13
    相关资源
    最近更新 更多