Is it possible to give javascript partial class behavior like C# or monkey patching like Ruby does?

前端 未结 5 1673
感动是毒
感动是毒 2021-01-01 05:14

The idea behind partial classes is that you can group certain functions together. The best example of this in C# is putting control definitions in one file and the event han

相关标签:
5条回答
  • 2021-01-01 05:51

    I'm expanding upon Raynos' partial classes example. The following is tested and works:

    //  In Car.js
    function Car(domelement, wheels, engine, color) {
        this.domelem = domelement;
    
        //  Wire in partial classes from other files
        for(var i = 0, ii = Car.Partial.length; i < ii; i++) {
             Car.Partial[i].apply(this, arguments);
        }
    }
    Car.Partial = [];  //  Prepare for declaration of additional partial classes
    
    //  In Car.Events.js
    Car.Partial[0] = function Events() {
        //  Create some events on Car with jQuery
        $(this.domelem).click(function() { alert('Car clicked.'); });
    }
    

    You can then use a build tool to combine the files into a single script, or you can simply reference the files in order:

    <script src="Car.js"></script>
    <script src="Car.Events.js"></script>
    <script>
        //  Turn first paragraph into our Car object
        var myCar = new Car($('p').get(0));
    </script>
    
    0 讨论(0)
  • 2021-01-01 06:01

    Redefine the type through inheritance approach like this:

    var Dog = Class.extend({
        init:function(data){
             data = data || {};
             this.name = data.name;
        },
        run:function(){ 
            /*impl*/
        }
    });
    
    /*other js file that require first file */
    var Dog = Dog.extend({
       init:function(data){ 
           this._super(data); 
       },
       bark:function(){ 
           return 'woof';
       }
    });
    

    The only problem in this approach is the dependency management, but it works.

    obs: using John Resing class.js, but could be written in typescript, ES6, AngularJs, ... and many other libraries.

    0 讨论(0)
  • 2021-01-01 06:08

    If such a split makes real sense then you can do this:

    File #1

    function MyObjectType() { this.init(); }
    

    File #2

    MyObjectType.prototype.init = function() { this.one = 1; }
    

    File #3

    MyObjectType.prototype.onClick = function() { if(this.one == 1) alert("I am so alone..."); }
    

    And somewhere else you can use it as:

    var myObject = new MyObjectType();
    myObject.onClick();
    

    Welcome to prototype yet kinda functional programming world!

    0 讨论(0)
  • 2021-01-01 06:12
    // file 1
    
    function augment() {
        this.monkey = "monkey";
    }
    
    // file 2
    
    function augmentMore() {
        this.patch = "patch";
    }
    
    // file 3
    
    var o = {};
    augment.call(o);
    augmentMore.call(o);
    console.log(o.monkey + o.patch);
    

    Monkey patching works. partial classes can work by convention. For example consider this convention.

    // file main
    function SomeObject() {
        for (var i = 0, ii = SomeObject.Partial.length; i < ii; i++) {
             SomeObject.Partial[i].apply(this, arguments);
        }
    }
    
    SomeObject.Partial.SomeName = function() {
       ...
    }
    
    // file extra
    SomeObject.Partial.SomeOtherName = function() {
       ...
    }
    

    JavaScript is surprisingly powerful. Was there a specific example you were looking for?

    0 讨论(0)
  • 2021-01-01 06:13

    Here is one approach using ES6 and compatible with ES5 using Babel:

    In this example I create a MyClass in several files, using three files:

    index.js (this is important so you can import the class just via the folder name)

    symbols.js (this contains the symbols for private members)

    additionalMethods.js (a file that is later attached to the class prototype)

    index.js content

    import symbols from "./symbols";
    
    export default class MyClass {
      [symbols.existentPrivateMethod]() {
        return "this is the result";
      }
    }
    
    import additionalMethod, {anotherAdditionalMethod, additionalPrivateMethod} from "./additionalMethods";
    const additionalMethodsObject = {
      additionalMethod: additionalMethod,
      anotherAdditionalMethod: anotherAdditionalMethod
    };
    additionalMethodsObject[symbols.additionalPrivateMethod] = additionalPrivateMethod;
    
    Object.assign(MyClass.prototype, additionalMethodsObject);
    

    additionalMethods.js contents

    import symbols from "./symbols";
    
    export default function additionalMethod() {
      return this[symbols.existentPrivateMethod]();
    }
    
    export function anotherAdditionalMethod() {
      return this[symbols.additionalPrivateMethod]();
    }
    
    export function additionalPrivateMethod() {
      return "yet another result";
    }
    

    symbols.js content

    const symbols = {
      existentPrivateMethod: Symbol("myPrivateMethod"),
      additionalPrivateMethod: Symbol("additionalPrivateMethod")
    };
    
    export default symbols;
    

    Complete project https://github.com/nicosommi/partialClass

    Complete explanation https://nicosommi.com/2015/08/10/partial-class-approach-for-es6/

    0 讨论(0)
提交回复
热议问题