JavaScript inheritance and the constructor property

前端 未结 3 1103
庸人自扰
庸人自扰 2020-11-22 01:19

Consider the following code.

function a() {}
function b() {}
function c() {}

b.prototype = new a();
c.prototype = new b();

console.log((new a()).constructo         


        
3条回答
  •  鱼传尺愫
    2020-11-22 02:14

    constructor is a regular, non-enumerable property of the default value of the prototype property of function objects. Thus, assigning to prototype will lose the property.

    instanceof will still work as it does not use constructor, but rather scans the prototype chain of the object for the (current) value of the function's prototype property, ie foo instanceof Foo is equivalent to

    var proto = Object.getPrototypeOf(foo);
    for(; proto !== null; proto = Object.getPrototypeOf(proto)) {
        if(proto === Foo.prototype)
            return true;
    }
    return false;
    

    In ECMAScript3, there's no way to set a constructor property which behaves identically to the built-in one as user-defined properties are always enumerable (ie visible to for..in).

    This changed with ECMAScript5. However, even if you set constructor manually, your code still has issues: In particular, it is a bad idea to set prototype to an instance of the parent-'class' - the parent constructor should not be called when the child-'class' is defined, but rather when child-instances are created.

    Here's some ECMAScript5 example code for how it should be done:

    function Pet(name) {
        this.name = name;
    }
    
    Pet.prototype.feed = function(food) {
        return this.name + ' ate ' + food + '.';
    };
    
    function Cat(name) {
        Pet.call(this, name);
    }
    
    Cat.prototype = Object.create(Pet.prototype, {
        constructor : {
            value : Cat,
            writable : true,
            enumerable : false,
            configurable : true
        }
    });
    
    Cat.prototype.caress = function() {
        return this.name + ' purrs.';
    };
    

    If you're stuck with ECMAScript3, you'll need to use a custom clone() function instead of Object.create() and won't be able to make constructor non-enumerable:

    Cat.prototype = clone(Pet.prototype);
    Cat.prototype.constructor = Cat;
    

提交回复
热议问题