tnhu / jsface

Small, fast, elegant, powerful, and cross platform JavaScript OOP library. Support main(), singleton, super call, private, mixins, plugins, AOP and more.
MIT License
301 stars 46 forks source link

how to call $superp without a variable assigned? #10

Closed pocesar closed 11 years ago

pocesar commented 11 years ago

suppose I have two classes (in different files, in Node):

factory('Core', {
  /* my stuff */
  mystuff: function(){
    /*do*/
  }
});

now in a second file I do:

factory('MyClass', 'Core', {
  newstuff: function(){
    this.$superp.mystuff(); // this is {} and has no $superp
  }
});

I want the user to drop the need to use variables, and define a class without having to assign it, because I'm using a repository pattern, when factory is called, a new class is instantiated inside a private repository object automatically. factory is merely a wrapper:

global.factory = (function(){
   var repository = {};
   return function(name, obj, opt){
     if (_.isString(obj) && obj in repository) {
       return repository[name] = jsface.Class(repository[obj], opt || {});
     } else if (_.isUndefined(opt)) {
       return repository[name] = jsface.Class(obj);
     } else {
       return repository[name] = jsface.Class(obj, opt);
     }
   }
})();

How can I go around this? How can I make it so the "this" points to the current class?

tnhu commented 11 years ago

Hi Paulo,

Apology for the late reply. Possibly you found some workaround. I implemented this.$super() before (you can find in previous version like at https://github.com/tnhu/jsface/blob/v2.0.2/jsface.js). It was convenient but fact is to keep track of the inheritance, it's a huge performance lost.

Not exact a solution but I use to declare classes under a namespace, which helps to avoid introducing globals. In order to add classes in the factory's repo, I use $ready plugin. For example:

PL = {};

PL.Factory = Class(function() {
  var repository = {};

  return {
    $ready: function(clazz, parent, api) {
      var name;

      // clazz is a sub-class
      if (this !== clazz) {
        name = api.name;
        if (name && jsface.isString(name) && !repository[name]) {
          repository[name] = clazz;
        }
      }
    }
  };
});

PL.Core = Class(PL.Factory, {
  name: 'Core',

  mystuff: function(){
  }
});

PL.MyClass = Class(PL.Factory, {
  name: 'MyClass',

  mystuff: function(){
    PL.MyClass.$superp.mystuff.call(this);
  }
});