这是我的代码:
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
方法
为什么重写不起作用?我怎么能让它发挥作用?
以下是demo
答案 0 :(得分:1)
当您分配新的原型对象时,只有新实例化的对象才会拥有新的原型:
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();
这是因为在实例化对象时,会从构造函数的原型中复制对原型对象的引用。如果要添加到所有现有实例和future实例的原型,只需修改原型对象,而不是将全新对象分配给构造函数:
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();
答案 1 :(得分:1)
您成功更改了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__
仍指向同一个对象,但对象本身现在还有一个属性。
答案 2 :(得分:0)
我确实添加了这个功能。但是您正在更改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
指向所有新创建的对象的位置,但不会更改已存在的对象。
答案 3 :(得分:0)
虽然这是一种非标准方法,但这对您有所帮助 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();