首页 > typescript中,子类继承父类后,原型中的constructor的enumerable 变成了 true

typescript中,子类继承父类后,原型中的constructor的enumerable 变成了 true

这个是我的代码

class Animal {
    constructor(public name: string){}
}
class Cat extends Animal {
    constructor(public name: string) {
        super(name);
    }
}

它产生的js代码如下

var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var Animal = (function () {
    function Animal(name) {
        this.name = name;
    }
    return Animal;
})();
var Cat = (function (_super) {
    __extends(Cat, _super);
    function Cat(name) {
        _super.call(this, name);
        this.name = name;
    }
    return Cat;
})(Animal);

里面的__extends导致了子类原型中的constructor属性的enumerable为true,该怎么修复这个问题呢?(虽然这不是什么大问题)
我知道如下代码可以修复他,但是我像知道typescript自身有没有办法解决这个问题?

Object.defineProperty(Cat.prototype, 'constructor', {
    enumerable: false
});

把代码代入:

var Animal = (function () {
    function Animal(name) {
        this.name = name;
    }
    return Animal;
})();
var Cat = (function (_super) {
    __extends(Cat, _super);
    function Cat(name) {
        _super.call(this, name);
        this.name = name;
    }
    return Cat;
})(Animal);

function Helper() { this.constructor = Cat; }
Helper.prototype = Animal.prototype;
Cat.prototype = new Helper();

注意Cat.prototype是直接赋值得到了新对象,这个新对象是Helper这个玩意的一个实例,Helper相当于是一个你自定义的而不是JavaScript内部创建的对象,因此constructor这个属性的[[Enumerable]]当然是跟平时你自定义类型的时候一样为true了。
还真没什么好办法避免这件事,TypeScript这么设计是考虑了兼容性因素的。当然如果你确定你不打算支持旧的浏览器的话,完全可以hack进TypeScript里,把Helper函数(也就是__函数)去掉改成使用Object.create来做:
Sub.prototype = Object.create(Parent.prototype, {constructor: {enumerable: false, value: Sub}});

【热门文章】
【热门文章】