是否可以在javascript中的现有对象上分配原型?
如果我有:是否可以在javascript中的现有对象上分配原型?,javascript,inheritance,Javascript,Inheritance,如果我有: function Base (){ this.sayHi = function(){ alert('hi'); } } function Thing (val){ this.value = val; } var bob = new Thing("bob"); 我现在可以说bob继承自Base,这样我就可以调用: bob.sayHi(); 基本上,基类的所有方法和属性都可以在该实例上使用吗 基于CMS帖子的解决方案的更相关示例: 这里的项
function Base (){
this.sayHi = function(){
alert('hi');
}
}
function Thing (val){
this.value = val;
}
var bob = new Thing("bob");
我现在可以说bob继承自Base,这样我就可以调用:
bob.sayHi();
基本上,基类的所有方法和属性都可以在该实例上使用吗
基于CMS帖子的解决方案的更相关示例:
这里的项可以表示服务器返回的数据
var Items = [
{ sku: 123, type:'buggy', title:'This is a title', description: 'this is a description' },
{ sku: 234, type: 'baby-monitor', title: 'This is a title 2', description: 'this is a description 2' }
]
function ItemMethods() {
this.BannerHTML = function () {
return '<div class="banner _item_' + this.type + '_' + this.sku + '"><h2>' +
this.title + '</h2><p>' +
this.description + '</p></div>';
};
}
Items.GetBySKU = function (code) {
for (var i = 0; i < Items.length; i++) {
if (Items[i].sku == code) {
return Items[i];
}
}
};
$.each(Items, function (i, item) {
ItemMethods.apply(item);
});
alert(Items.GetBySKU(234).BannerHTML());
var项目=[
{sku:123,类型:'buggy',标题:'This a title',描述:'This a description'},
{sku:234,键入:'婴儿监视器',标题:'这是标题2',描述:'这是描述2'}
]
函数ItemMethods(){
this.BannerHTML=函数(){
返回“”+
this.title+“”+
此文件名为“”;
};
}
Items.GetBySKU=函数(代码){
对于(变量i=0;i
乐意接受任何进一步的意见或解决方案。。始终对问题的潜在解决方案感兴趣;-) 在javascript中,您可以通过将子类的原型设置为基类的实例来创建另一个的子类:
function BaseClass() {
this.baseFunction = function() {
};
};
function SubClass() {
};
SubClass.prototype = new BaseClass;
SubClass.prototype.someFunction = function() {
};
// create an instance of SubClass
var obj = new SubClass;
// SubClass truly extends BaseClass
obj instanceof BaseClass // true
obj instanceof SubClass // true
// the instance has both methods of BaseClass and SubClass
typeof obj.someFunction // Function
typeof obj.baseFunction // Function
这相当于java中的类子类扩展了基类
如果在此之后还修改了原型
如果将函数和属性添加到对象构造函数的原型中,则函数和属性将在所有实例上可用
以下是一个例子:
function Thing (val){
this.value = val;
}
var bob = new Thing("bob");
console.log(bob.foo); // undefined
Thing.prototype.foo = function() {
console.log('foo!');
};
console.log(bob.foo); // function()
bob.foo(); // foo!
现在,如果要使用Base扩展所有Thing实例,可以这样做:
var base = new Base;
for (var k in base) {
Thing.prototype[k] = base[k];
}
或者,如果您想让Thing实例扩展Base:(即,不要重写Thing中已经存在的方法)
如果只想扩展唯一的对象实例,只需为其指定:
var bob = new Thing("bob");
var base = new Base();
bob.sayHi = base.sayHi;
bob.sayHi();
您还可以在对象的上下文中调用函数,而无需将函数指定给对象:
var base = new Base();
base.sayHi.call(bob);
请注意,您在构造函数中创建的属性与构造函数的原型
无关,它们是您使用new Base()创建的对象的自有属性代码>,它们不是继承的。但是,我认为您希望在新创建的Thing
对象上应用Base
构造函数:
function Base (){
this.sayHi = function(){
alert('hi');
}
}
function Thing (val){
Base.apply(this, arguments);
this.value = val;
}
var bob = new Thing("bob");
bob.sayHi();
请注意,bob
将不会从Base
继承(它将无法访问添加到Base.prototype
)的属性)
否。至少根据规范,无法为现有对象分配不同的[[原型]]。[[prototype]]是在创建新对象时对构造函数prototype
属性进行评估(也称为“包含在”)后生成的对象,以后不能重新分配。(我希望它能被正式更改,但遗憾的是,它是一个不受支持的操作,通常可以通过不同的方法进行模拟。)
某些浏览器/环境可能选择使用非标准方法公开创建后[[prototype]]分配。可以修改[[prototype]]对象(例如,添加到String.prototype),或者可以将单例函数添加到目标对象(参见CMS的答案),或者可以包装现有对象(本质上是一个动态“子类”),具体取决于需求和限制
另外,Javascript中没有“类”:虽然“经典的单继承面向对象类”可以在Javascript中实现,但我发现它仅限于模型或一般使用此类术语。一种语言想要成为它现在的样子
快乐的编码。是的
1) 您可以将Base的构造函数定义直接添加到bob实例中
Base.call(bob);
bob.sayHi(); //hi
2) 或者您可以使用Base的构造函数定义来扩充Thing.prototype。bob实例可以访问其原型的新属性,即使它是在添加它们之前创建的
var bob = new Thing("bob");
Base.call(Thing.prototype);
bob.sayHi(); //hi
但是一点也不像bob.prototype=Base?仅针对该实例?如果只想向该实例添加函数,只需将该函数分配给该实例:bob.sayHi=theFunction
(或var base=new base;bob.sayHi=base.sayHi;
)您也可以在bob
的上下文中调用sayHi:var base=new base;base.sayHi.call(鲍勃)代码>非常方便,谢谢!我将使用CMS提出的Base.apply(bob)方法。您真正想要的只是用东西扩展Base?您可能会欣赏我前几天遇到的这篇文章,你可能想考虑改变这个标题,因为它并不是改变现有的类型,而是出现在谷歌的结果中。我可以在创建bob之后的某个地方执行“Base.apply(bob,arguments);”吗?@gordatron,是的,这是绝对可能的,您可以随时重复使用函数。。。查看本文:非常感谢!很多非常有用的信息和指针。。我以最具表现力的方式组织了我的问题,没有300个字符;-)
Base.call(bob);
bob.sayHi(); //hi
var bob = new Thing("bob");
Base.call(Thing.prototype);
bob.sayHi(); //hi