简体   繁体   English

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

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

Here is my code: 这是我的代码:

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

In the extend method, I rewrite an instance's prototype instance.constructor.prototype = {..} , extend方法中,我重写了一个实例的原型instance.constructor.prototype = {..}

however, when I log the instance, it doesn't show the say method 但是,当我记录实例时,它不会显示say方法

Why the rewrite doesn't work? 为什么重写不起作用? How can I let it work? 我该怎么办呢?

Here is the demo 这是演示

When you assign a new prototype object only newly instantiated objects will have the new prototype: 当您分配新的原型对象时,只有新实例化的对象才会拥有新的原型:

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

This is because the reference to the prototype object is copied from the constructor's prototype at the time the object is instantiated. 这是因为在实例化对象时,会从构造函数的原型中复制对原型对象的引用。 If you want to add to the prototype of all existing instances and future instance you can just modify the prototype object rather than assigning a whole new object to the constructor: 如果要添加到所有现有实例和将来实例的原型,只需修改原型对象,而不是将全新对象分配给构造函数:

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

You successfully changed Class.prototype , but you changed it to a totally different object . 您成功更改了Class.prototype ,但您将其更改为完全不同的对象

instance has a reference to its prototype object, called instance.__proto__ . instance有一个对其原型对象的引用,称为instance.__proto__ When a new Class instance is created, the __proto__ of the instance points to the same object as Class.prototype . 创建新的Class实例时,实例的__proto__指向与Class.prototype相同的对象。

However, your change what Class.prototype refers to . 但是,您更改 Class.prototype 所指的内容 This will affect the __proto__ of future instances, but not of any existing instances . 这将影响将来实例的__proto__ ,但不影响任何现有实例 instance.__proto__ still points to the old object that Class.prototype used to refer to. instance.__proto__仍然指向Class.prototype用来引用的旧对象。

This is how it looks at first, after instance is constructed: 在构造instance之后,它首先看起来如何:

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

This is how it looks after assignment of Class.prototype to a new object: 这是将Class.prototype分配给新对象的方式:

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

Instead , you want to modify the object Class.prototype refers to: 相反 ,您要修改对象Class.prototype指的是:

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

That will get you a final picture like this: 这将为您提供如下最终图片:

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

See that Class.prototype and instance.__proto__ still point to the same object, but the object itself now has an additional property. 看到Class.prototypeinstance.__proto__仍然指向同一个对象,但对象本身现在有一个额外的属性。

I does add this function. 我确实添加了这个功能。 But you are changing the prototype object itself, rather than changing its properties: 但是您正在更改prototype对象本身,而不是更改其属性:

Demo 演示

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

}

When you're trying to access some_obj.some_field the JS engine itself will first check objects own properties and then will go to some_obj.prototype and look for some_field . 当您尝试访问some_obj.some_field ,JS引擎本身将首先检查对象自己的属性,然后转到some_obj.prototype并查找some_field

By assigning instance.constructor.prototype = {...} you are changing where prototype will point for all newly created objects, but not for already existing ones. 通过分配instance.constructor.prototype = {...}您将更改prototype将指向所有新创建的对象的位置,但不会更改已存在的对象。

Though a non-standard approach, this will help you incase the JS environment allows you to edit proto internal property. 虽然这是一种非标准方法,但这将有助于您在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.

相关问题 在对象上调用构造函数原型时新添加的功能不起作用 - Newly added function to the prototype of the constructor doesn't work when it's called on objects 为什么MDN的`Object.create` polyfill没有设置`prototype.constructor`? - Why doesn't MDN's `Object.create` polyfill set `prototype.constructor`? 函数原型方法中的&#39;e&#39;参数不起作用 - The 'e' parameter in function's prototype method doesn't work Javascript:如果该构造函数已在另一个对象的原型上定义,则如何追加到该构造函数的原型 - Javascript: how to append to a constructor's prototype, if that constructor is already defined on another object's prototype Object.prototype.method 不起作用 - Object.prototype.method doesn't work 为什么不能在该构造函数中指定构造函数的原型? JavaScript - Why can't specify the constructor's prototype inside that constructor? JavaScript 为什么prototype的构造函数不指向Object函数? - Why doesn't constructor of prototype point Object function? 无法访问对象原型上的方法 - Can't access methods on object's prototype Javascript:如何获取对象的原型链构造函数名称列表? - Javascript: How to get a list of an object's prototype chain constructor names? 对于构造函数的原型属性未设置为 object 的实例,这是默认行为吗? - Is this default behaviour for instances whose constructor's prototype property is not set to an object?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM