无法继承内置String对象

时间:2016-01-05 06:04:45

标签: javascript ecmascript-6 subclassing built-in es2015

我一直在尝试使用Node 5.3.0对ES2015中的内置String对象进行子类化。我使用一堆和声标志来运行未经传输的代码。这是完整的命令: node --harmony --harmony_modules --harmony_destructuring --harmony_rest_parameters --harmony_arrow_functions --harmony_spreadcalls --harmony_object --harmony_default_parameters --harmony_new_target --harmony_reflect --harmony_modules ~/t.js

鉴于规范明确指出String对象是可子类化的(参见21.1.1 The String Constructor部分),我很难理解这是我做错了还是一个bug在Node或甚至是V8。

重现问题的代码如下:

'use strict';

class Str extends String {
  capitalize() {
    return `${this.slice(0, 1).toUpperCase()}${this.slice(1)}`;
  }
}

var s = new Str('asdf');

console.log(s.constructor);
//[Function: String]

console.log(s.__proto__)
//[String: '']

console.log(s.capitalize());
//TypeError: s.capitalize is not a function

上面的代码表明原型链没有按照我的预期进行设置。但是,如果我使用下面的代码手动修复__proto__,则一切正常。



'use strict';

class Str extends String {
  constructor(...args) {
    super(...args);
    Object.setPrototypeOf(this, new.target.prototype);
  }

  capitalize() {
    return `${this.slice(0, 1).toUpperCase()}${this.slice(1)}`;
  }
}

var s = new Str('asdf');
console.log(s.constructor);
//[Function: Str]

console.log(s.__proto__);
//Str {}

console.log(s.capitalize());
//Asdf




我真的好奇地知道为什么继承没有像我期望的那样发挥作用。

1 个答案:

答案 0 :(得分:1)

我还没有找到问题的确切答案,但我的快速而肮脏的解决方案目前一直在努力,所以我会把它作为遇到同样问题的人的答案。

您可以使用constructor()中的以下行继承String内置时修复原型链:

Object.setPrototypeOf(this, new.target.prototype);

new.target.prototype位确保如果您继承自己的类型,原型链将继续正确。