项目作者: wizard04wsu

项目描述 :
A JavaScript class implementation with protected members
高级语言: JavaScript
项目地址: git://github.com/wizard04wsu/Class.git
创建时间: 2014-01-02T18:35:44Z
项目社区:https://github.com/wizard04wsu/Class

开源协议:MIT License

下载


JavaScript Class Implementation

This implementation adds the capability for a class to have protected members that can be accessed by derivative class constructors.

This is a JavaScript module. It can be imported into your script like so: import Class from "Class.mjs"

Class.extend()

Creates a child class. This is a static method of Class and its derivative classes.

Syntax

  1. Class.extend(init)
  2. Class.extend(init, call)

Parameters

init
An initializer function that is called as part of the child class’s constructor. The name of the initializer is used as the name of the class.

call optional
A handler function for when the class is called without using the new keyword. Default behavior is to throw a TypeError.

Return value

The new class constructor. It has its own static copy of the extend method.

Initializer

The signature of an initializer function is expected to be:

  1. function MyClassName($super, ...args){
  2. //... code that does not include `this`
  3. const protectedMembers = $super(arg1, arg2, ...);
  4. //... code that may include `this`
  5. }

$super
A Proxy to the parent class’s constructor, bound as the first argument of the initializer. It is to be used like the super keyword. It must be called exactly once during the execution of the initializer, before any reference to this.


protectedMembers
An object whose members are shared among all the initializers that are executed when a new instance of the class is created. This allows a protected value defined in the initializer of a class to be accessed and modified within the initializer of a derivative class directly, without needing static getters and setters.

Examples

Create a new class

  1. const MyClass = Class.extend(function Rectangle($super, width, height){
  2. $super();
  3. this.dimensions = ()=>width+" x "+height;
  4. });
  5. let r = new MyClass(2, 3);
  6. console.log(MyClass.name); // Rectangle
  7. console.log(r.toString()); // [object Rectangle]
  8. console.log(r.dimensions()); // 2 x 3

Use a call handler

  1. const Rectangle = Class.extend(
  2. function Rectangle($super, width, height){
  3. $super();
  4. this.dimensions = ()=>width+" x "+height;
  5. },
  6. (width, height)=>"area is "+(width*height)+" square units" //handler for when Rectangle() is called without using `new`
  7. );
  8. console.log(Rectangle(2, 3)); // area is 6 square units

Inherit from a superclass

  1. const Rectangle = Class.extend(function Rectangle($super, width, height){
  2. $super();
  3. this.dimensions = ()=>width+" x "+height;
  4. });
  5. const Square = Rectangle.extend(function Square($super, width){
  6. $super(width, width);
  7. //this.dimensions() is inherited from Rectangle
  8. });
  9. let s = new Square(2);
  10. console.log(s.dimensions()); // 2 x 2

Use static methods of the parent class

  1. const Rectangle = Class.extend(function Rectangle($super, width, height){
  2. $super();
  3. this.dimensions = ()=>width+" x "+height;
  4. });
  5. Rectangle.area = function (width, height){ return width * height; };
  6. const Square = Rectangle.extend(function Square($super, width){
  7. $super(width, width);
  8. this.area = function (){
  9. return $super.area(width, width); //here, using `$super` as an object is equivalent to using `Rectangle`
  10. };
  11. });
  12. let s = new Square(2);
  13. console.log(Rectangle.area(2, 2)); // 4
  14. console.log(s.area()); // 4

Use protected members

  1. const Rectangle = Class.extend(function Rectangle($super, width, height){
  2. const prot = $super();
  3. prot.width = width;
  4. prot.height = height;
  5. Object.defineProperty(this, "width", {
  6. enumerable: true, configurable: true,
  7. get(){ return prot.width; },
  8. set(width){ return prot.width = width; }
  9. });
  10. Object.defineProperty(this, "height", {
  11. enumerable: true, configurable: true,
  12. get(){ return prot.height; },
  13. set(height){ return prot.height = height; }
  14. });
  15. this.dimensions = ()=>prot.width+" x "+prot.height;
  16. });
  17. const Square = Rectangle.extend(function Square($super, width){
  18. const prot = $super(width, width);
  19. Object.defineProperty(this, "width", {
  20. enumerable: true, configurable: true,
  21. get(){ return prot.width; },
  22. set(width){ return prot.width = prot.height = width; }
  23. });
  24. Object.defineProperty(this, "height", {
  25. enumerable: true, configurable: true,
  26. get(){ return prot.height; },
  27. set(height){ return prot.height = prot.width = height; }
  28. });
  29. });
  30. let s = new Square(2);
  31. console.log(s.dimensions()); // 2 x 2
  32. s.height = 3;
  33. console.log(s.dimensions()); // 3 x 3