-->

Best practices for static methods and variables wi

2020-06-03 07:44发布

问题:

Are there any best practices or common solutions to adding support for "static" methods and variables to MooTools-generated classes?

In particular, is there any solution that ensures that static initialization takes place before the instance initialize method is called?

回答1:

Caveat: Never used MooTools. I've used Prototype a fair bit, though, which has a similar Class system (MooTools is either "inspired by" or a fork of Prototype, depending on who you ask).

Just add them as properties on the resulting "class":

var MyClass = new Class(properties);
MyClass.staticMethod = function() {
    // ...
};

(The first line above is from the docs; the remainder is my addition.)

You know that will happen prior to initialize on any new instance because you're not leaving an opportunity for creating a new instance prior to attaching your static methods (or properties).



回答2:

I know this post is old, but I wanted to give a better answer than was already stated.
I recommend the following syntax for static methods:

var MyClass = new Class({
    initialize: function() {
        this.method();
        MyClass.staticMethod();
    }
    ,
    method: function() {}
}).extend({
    staticMethod: function() {}
});

The .extend({}) method is the standard way to add static methods on a Class.

The only thing I don't like is the MyClass.staticMethod(); syntax, but there aren't many better options.



回答3:

Appitizer...

Static methods in JavaScript are properties of the Object which references them. They are not added to the prototype of the Object.

There are two ways to add a function to an object in JavaScript. Below, I am adding methods to an imaginary object called, "MyObject".

  1. Property

    MyObject.staticMethod = new function() {};
    
    MyObject.staticMethod(); // Call static method.
    
  2. Method

    MyObject.prototype.instanceMethod = new function() {};
    
    new MyObject().instanceMethod(); // Call instance method.
    

Main Course...

There are three (3) ways to add static methods to a class. The code below is derived from "Pro JavaScript with MooTools" by Mark Obcena.

I included some more information which was lacking from Arcabard's answer.

1. As an Object property

var Person = new Class({
    // Instance Variables
    name: '',
    age: 0,
    // Constructor
    initialize: function(name, age) {
        this.name = name;
        this.age = age;
    },
    // Instance Methods
    log: function() {
        console.log(this.name + ', ' + this.age);
    }
});

// Static Property
Person.count: 0;
// Static Methods
Person.addPerson: function() {
    this.count += 1;
};
Person.getCount: function() {
    console.log('Person count : ' + this.count);
};

2. Using the extend()

var Person = new Class({
    // Instance Variables
    name: '',
    age: 0,
    // Constructor
    initialize: function(name, age) {
        this.name = name;
        this.age = age;
    },
    // Instance Methods
    log: function() {
        console.log(this.name + ', ' + this.age);
    }
});

Person.extend({
    // Static Property
    count: 0,
    // Static Methods
    addPerson: function() {
        this.count += 1;
    },
    getCount: function() {
        console.log('Person count : ' + this.count);
    }
});

3. Adding a new mutator to Class.Mutators

// This will create a shortcut for `extend()`.
Class.Mutators.Static = function(members) {
    this.extend(members);
};

var Person = new Class({
    Static: {
        // Static Property
        count: 0,
        // Static Method
        addPerson: function() {
            this.count += 1;
        },
        getCount: function() {
            console.log('Person count : ' + this.count);
        }
    },
    // Instance Variables
    name: '',
    age: 0,
    // Constructor
    initialize: function(name, age) {
        this.name = name;
        this.age = age;
    },
    // Instance Methods
    log: function() {
        console.log(this.name + ', ' + this.age);
    }
});

Example using the static methods.

// Creating a new Person instance
var mark = new Person('Mark', 23);
mark.log();

// Accessing the static method
Person.addPerson();
Person.getCount() // 'Person count: 1'


回答4:

Excerpt from "Pro Javascript with Mootools":

The extend method is declared via Function.prototype and is inherited by all functions. Because a MooTools class is in essence a function, we could use the extend method for classes too. The method is similar to the implement method in that it takes an object argument with keys and values referring to members that will be added. Unlike implement, though, extend does not add the members to the prototype of the class, but to the class object itself.

// You can implement a `Static` mutator for creating static methods and variables:
Class.Mutators.Static = function(members) {
    this.extend(members);
}

// Using the Static mutator above
var Person = new Class({
    Static: {
        // Static Property
        count: 0,
        // Static Method
        addPerson: function() {
            this.count += 1;
        },
        getCount: function(){
            console.log('Person count: ' + this.count);
        }
    }
});

See MooTools: Types > Function > extend() for more information.