繁体   English   中英

重写对象的构造函数的原型不起作用

[英]Rewrite object's constructor's prototype doesn't work

这是我的代码:

function Class() {};

Class.prototype.extend = function () {
    var instance = new Class();
    instance.constructor.prototype = {
        say: function () {
            console.log("Hello");
        }
    }
    console.log(instance); //Class {extend: function}
}

Class.extend = function () {
    this.prototype.extend();
}

Class.extend();

extend方法中,我重写了一个实例的原型instance.constructor.prototype = {..}

但是,当我记录实例时,它不会显示say方法

为什么重写不起作用? 我该怎么办呢?

这是演示

当您分配新的原型对象时,只有新实例化的对象才会拥有新的原型:

function Class() {};

Class.prototype.extend = function () {
    var instance = new Class();
    instance.constructor.prototype = {
        say: function () {
            console.log("Hello");
        }
    }
    console.log(instance);    //Class {extend: function}
    console.log(new Class()); //Class {say: function}
}

Class.extend = function () {
    this.prototype.extend();
}

Class.extend();

这是因为在实例化对象时,会从构造函数的原型中复制对原型对象的引用。 如果要添加到所有现有实例和将来实例的原型,只需修改原型对象,而不是将全新对象分配给构造函数:

function Class() {};

Class.prototype.extend = function () {
    var instance = new Class();
    instance.constructor.prototype.say = function () {
        console.log("Hello");
    }
    delete instance.constructor.prototype.extend;
    console.log(instance); //Class {say: function}
}

Class.extend = function () {
    this.prototype.extend();
}

Class.extend();

您成功更改了Class.prototype ,但您将其更改为完全不同的对象

instance有一个对其原型对象的引用,称为instance.__proto__ 创建新的Class实例时,实例的__proto__指向与Class.prototype相同的对象。

但是,您更改 Class.prototype 所指的内容 这将影响将来实例的__proto__ ,但不影响任何现有实例 instance.__proto__仍然指向Class.prototype用来引用的旧对象。

在构造instance之后,它首先看起来如何:

instance.__proto__ ===> { extend: function } <=== Class.prototype

这是将Class.prototype分配给新对象的方式:

instance.__proto__ ===> { extend: function }
                        { say:    function } <=== Class.prototype

相反 ,您要修改对象Class.prototype指的是:

instance.constructor.prototype.say = function () {
    console.log("Hello");
}

这将为您提供如下最终图片:

instance.__proto__ ===> { extend: function, say: function } <=== Class.prototype

看到Class.prototypeinstance.__proto__仍然指向同一个对象,但对象本身现在有一个额外的属性。

我确实添加了这个功能。 但是您正在更改prototype对象本身,而不是更改其属性:

演示

Class.prototype.extend = function () {
    var instance = new Class();
    instance.constructor.prototype.say =
        function () {
            console.log("Hello");
        }
    console.log(instance);
    // Class {extend: function, say: function}

}

当您尝试访问some_obj.some_field ,JS引擎本身将首先检查对象自己的属性,然后转到some_obj.prototype并查找some_field

通过分配instance.constructor.prototype = {...}您将更改prototype将指向所有新创建的对象的位置,但不会更改已存在的对象。

虽然这是一种非标准方法,但这将有助于您在JS环境中允许您编辑proto内部属性。

function Class() {};

Class.prototype.extend = function () {
    var instance = new Class();
    instance.__proto__ = instance.constructor.prototype = {
        say: function () {
            console.log("Hello");
        }
    }


    console.log(instance); //Class {extend: function}
    console.log(instance.say)
}

Class.extend = function () {
    this.prototype.extend();
}

Class.extend();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM