[英]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?
我该怎么办呢?
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.prototype
和instance.__proto__
仍然指向同一个对象,但对象本身现在有一个额外的属性。
I does add this function. 我确实添加了这个功能。 But you are changing the
prototype
object itself, rather than changing its properties: 但是您正在更改
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}
}
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.