是否可以在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