如果我有:
function Base (){
this.sayHi = function(){
alert('hi');
}
}
function Thing (val){
this.value = val;
}
var bob = new Thing("bob");
有没有什么方法我现在可以说bob继承自Base,以便我可以调用:
bob.sayHi();
基本上可以在该实例上使用Base类的所有方法和属性吗?
基于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());
任何进一步的评论或解决方案都很乐意接受..总是对问题的潜在解决方案感兴趣; - )
答案 0 :(得分:6)
否。至少根据规范,无法为现有对象分配不同的 [[prototype]] 。 [[prototype]] 是在新对象创建时构造函数prototype
property 的评估(也称为“包含在”)中产生的对象以后不能重新分配。 (我希望它可以正式更改,但是它是一个不受支持的操作,并且通常可以通过不同的方法进行模拟。)
某些浏览器/环境可能会选择使用非标准方法公开创建后的 [[prototype]] 。可以修改 [[prototype]]对象(例如添加到String.prototype),或者可以将单例函数添加到目标对象(请参阅CMS的答案),或者现有对象可以是包装(基本上是一个动态的“子类”) - 取决于要求和限制。
此外,Javascript中没有“类”:虽然“经典的单继承对象定向类”可以在Javascript中实现,但我发现限制自己限制模型或使用这样的术语。语言希望成为现实。
快乐的编码。
答案 1 :(得分:2)
在javascript中,您可以通过将子类'prototype设置为基类的实例来创建另一个的子类:
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中的class SubClass extends BaseClass
。
如果你之后也修改了原型。
如果将函数和属性添加到对象构造函数的原型中,则函数和属性将在所有实例上可用。
以下是一个例子:
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 :(即不要覆盖已经存在的东西的方法)
var base = new Base;
for (var k in base) {
if (Thing.prototype[k]) continue;
Thing.prototype[k] = base[k];
}
如果您只想扩展一个唯一的对象实例,只需指定它:
var bob = new Thing("bob");
var base = new Base();
bob.sayHi = base.sayHi;
bob.sayHi();
您也可以在对象的上下文中调用函数,甚至不将函数赋值给对象:
var base = new Base();
base.sayHi.call(bob);
答案 2 :(得分:1)
请注意,您在构造函数中创建的属性与构造函数的prototype
无关,它们是您使用new Base();
创建的对象的自己的属性,他们不是遗传的。但是,我认为您要在Base
新创建的对象上应用 {/ 1}}构造函数来执行此操作:
Thing
请注意,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
答案 3 :(得分:1)
是。
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