dojo1.7翻译 定义类(Classy JavaScript with dojo/_base/declare)

原文地址:http://dojotoolkit.org/documentation/tutorials/1.7/declare/

 

dojo/_base/declare模块是一个创建类的基础模块。他可以用来通过多继承创建灵活的类。dojo,dijit,和dojox都是使用了decalre。

 

开始

请确保你已经了解了模块的相关知识。

 

通过dojo创建基本的类

declare功能是在dojo/_base/declare模块中定义的。它接收三个参数className,superClass,properties

 

ClassName

这个属性声明了一个类名,声明后,名子将被放入到全局范围。className可以使用继承类声明。

 

有名子的类

// Create a new class named "mynamespace.MyClass"
declare("mynamespace.MyClass", null, {
 
    // Custom properties and methods here
 
});
 

 

被声明为mynamespace.MyClass 的类名已经被放到全局的范围了。

如果一个类要被dojo来解析使用则必需要有类名,另一种类是可以不需要类名的。

 

匿名类

// Create a scoped, anonymous class
var MyClass = declare(null, {
     
    // Custom properties and methods here
     
});
 

MyClass现在能在给定的范围域类使用了

 

父类

一个类的父类可以是null,一个已经存在的类,也可以是多个已经存在的类。如果有多个父类,则第一个父类将会成为基础类,别的父类将会使用"混合"方式组合。

 

没有父类

var MyClass = declare(null, {
 
    // Custom properties and methods here
 
});
 

null就表示了这个类没有父类

 

有一个父类

var MySubClass = declare(MyClass, {
 
    // MySubClass now has all of MyClass's properties and methods
    // These properties and methods override parent's
 
});
 

MySubClass将会继承于MyClass的属性和方法。父类中的属性和方法可以被重写。

 

有多个父类

var MyMultiSubClass = declare([
    MySubClass,
    MyOtherClass,
    MyMixinClass
],{
 
    // MyMultiSubClass now has all of the properties and methods from:
    // MySubClass, MyOtherClass, and MyMixinClass
 
});
 

数组就表示这个类有多个父类。从左至右将一个个的继承其父类的属性和方法。第一个类做为基础类,别的类将使用"混合"方法继承。

 

如果一个属性可方法在多个父类中都存在。那么它将使用最后一个父类的属性或方法。

 

属性和方法

一个对象可以拥有属性和方法。如果有父类中相同的属性或方法名,则将会重写其属性。

 

属性和方法示例

// Class with custom properties and methods
var MyClass = declare(MyParentClass, {
    // Any property
    myProperty1: 12,
    // Another
    myOtherProperty: "Hello",
    // A method
    myMethod: function(){
 
        // Perform any functionality here
 
        return result;
    }
});
 

示例:类的创建和继承

下面的代码中我们将要创建一个从dijit/form/Button模块继承的类

define([
    "dojo/_base/declare",
    "dijit/form/Button"
], function(declare, Button){
    return declare("mynamespace.Button", Button, {
        label: "My Button",
        onClick: function(evt){
            console.log("I was clicked!");
            this.inherited(arguments);
        }
    });
});
 

从上面的代码中,我们可以简单的推断出

  • 类名是mynamespace.Button
  • 通过模块的return功能,mynamespace.Button这个类可以在全局范围内被引用
  • 这个类继承于dijit/form/Button和这个Button类的依赖类。
  • 这个类有几个定制的属性和方法。

 

构造方法

如果类的方法名叫constructor ,这个方法将会在类初始化时被调用。就意味着this这个字将引用到当前实例而不是原类。constructor 方法也可以接收参数。

// Create a new class
var Twitter = declare(null, {
    // The default username
    username: "defaultUser",
     
    // The constructor
    constructor: function(args){
        declare.safeMixin(this,args);
    }
});
 

下面的代码是创建一个类实例

var myInstance = new Twitter();
 

在实例中,username如果没有被赋值将会使用默认的"defaultUser"值。通过使用safeMixin 方法可以设置username的值。

var myInstance = new Twitter({
    username: "sitepen"
});
 

现在实例的username已经被设置成"sitepen"了

 

declare.safeMixin在创建和继承类中是很有作用的。在API中是这么介绍的。

 

"此功能有点像lang._mixin功能,但它将被用于构造函数中。 this.inherited()与declare.safeMixin混在功能,可以像使用正常的方法一样,它可以在构造方法中使用this.inherited()"

 

declare.safeMixin是创建类时赋参数值的一个好方法。

 

继承

就像上面所说的,类的继承是从左至右的,并且属性和方法可能会被覆盖

// Define class A
var A = declare(null, {
    // A few properties...
    propertyA: "Yes",
    propertyB: 2
});
 
// Define class B
var B = declare(A, {
    // A few properties...
    propertyA: "Maybe",
    propertyB: 1,
    propertyC: true
});
 
// Define class C
var C = declare([mynamespace.A, mynamespace.B], {
    // A few properties...
    propertyA: "No",
    propertyB: 99,
    propertyD: false
});
 

上面继承类的结果

// Create an instance
var instance = new C();
 
// instance.propertyA = "No" // overridden by B, then by C
// instance.propertyB = 99 // overridden by B, then by C
// instance.propertyC = true // kept from B
// instance.propertyD = false // created by C
 

this.inherted

全部的重写父类的方法当然是可行的,但有的时候在构造函数中使用继承链可以有效的保护原有的功能。这也就是this.iinherited(XXX)这个方法的作用。这个方法调用了父类中的同名的方法

// Define class A
var A = declare(null, {
    myMethod: function(){
        console.log("Hello!");
    }
});
 
// Define class B
var B = declare(A, {
    myMethod: function(){
        // Call A's myMethod
        this.inherited(arguments); // arguments provided to A's myMethod
        console.log("World!");
    }
});
 
// Create an instance of B
var myB = new B();
myB.myMethod();
 
 
// Would output:
//      Hello! 
//      World!
 

this.inheried方法可以在子类中的任何时候进行调用。

 

结论

declare是创建模块所需要的非常重要的方法。重用declare可以重创建出更多更复杂的模块结构。

你可能感兴趣的:(JavaScript)