在Javascript中模拟子类 - 检查我是如何做到的?

时间:2012-06-24 23:58:48

标签: javascript subclass

我正在编写一些javascript,它是GNOME javascript,它或多或少是spidermonkey。可以把它看作是蜘蛛侠代码,从不在spidermonkey之外运行,因此无需担心跨浏览器兼容性等。

基本上我有一个不是子类的类Folks.Individual,但是我想通过修补它来模拟子类化,为它添加一些getter。 (对于那些感兴趣的人,它是通过gobject内省得到的GObject,在我的GJS版本中你不能继承GObject)。

注意:

  • contactSys.get_individual(contactID)返回Folks.Individual我正在修补
  • 我添加了一些返回一些值的getter emailaliasTextonline
  • 我通过let contact = new Contact(id);使用此课程,只想使用contact,就像它是Folks.Individual一样,加上我补丁的额外属性。
  • 如果我想修补的属性不是动态的,我会这样做:

    let contact = contactSys.get_individual(contactID);
    contact.email = ....;
    contact.aliasText = ....;
    contact.online = ....;
    

我只是想要一个关于上述内容的便利功能,以便我可以致电let contact = new Contact(contactID),它会返回contactemailaliasTextonline修补后的属性(尽管有吸气剂)。

这就是我现在这样做的方式。我的问题是,这是“正确”的方式吗?我应该在this内使用contact代替Contact()吗?我应该使用Folks.Individual.prototype做某事并将其称为Contact吗?

function Contact (contactID) {                                                  
    let contactSys = Shell.ContactSystem.get_default(),                         
        contact    = contactSys.get_individual(contactID); // <-- this is a Folks.Individual
    contact._contactSys = contactSys;                                           

    /* these are defined as getters in case the underlying values change */     
    Object.defineProperty(contact, 'email', {get: function () {                 
        return contact._contactSys.get_email_for_display(this);                 
    }});                                                                        
    Object.defineProperty(contact, 'aliasText', {get: function () {             
        return contact.alias     ||                                             
               contact.full_name ||                                             
               contact.nickname  ||                                             
               contact.email     ||                                             
               _("Unknown");                                                    
    }});                                                                        
    Object.defineProperty(contact, 'online', {get: function () {                
        return contact.presence_type === Folks.PresenceType.AVAILABLE ||        
               contact.presence_type === Folks.PresenceType.AWAY ||             
               contact.presence_type === Folks.PresenceType.EXTENDED_AWAY ||    
               contact.presence_type === Folks.PresenceType.BUSY;               
    }});                                                                        
    return contact;                                                             
}                 

请记住 - 我不能将Folks.Individual 子类化,所以我决定使用包装函数new Contact(contactID)修补它的实例,以便我可以像对待它一样对待它一个子类。我只是想知道是否有一种标准的方法。

喝彩!

1 个答案:

答案 0 :(得分:1)

至少你可以更简洁有效地“在线”:

var ONLINE = Folks.PresenceType.AVAILABLE |
              Folks.PresenceType.AWAY |
              Folks.PresenceType.EXTENDED_AWAY |
              Folks.PresenceType.BUSY;

Object.defineProperty(contact, 'online', {
  get: function(){ return (this.presence_type & ONLINE) > 0 }
});