[英]Newly added function to the prototype of the constructor doesn't work when it's called on objects
[英]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.prototype
和instance.__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.