如何在Babel中扩展Array类?

时间:2016-10-30 01:20:22

标签: javascript babeljs

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

以下适用于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;
    }
  }

3 个答案:

答案 0 :(得分:2)

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

如果Babel失败了你,你可以随时做到#34; classic"方式:

// 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();

答案 1 :(得分:0)

您可以使用此插件(Babel 6): https://www.npmjs.com/package/babel-plugin-transform-builtin-extend

该插件描述了IE <= 10的一些限制。

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

答案 2 :(得分:0)

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

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