_base/declare

dojo/_base/declare

Summary

Create a feature-rich constructor from compact notation.

Create a constructor using a compact notation for inheritance and prototype extension.

Mixin ancestors provide a type of multiple inheritance. Prototypes of mixin ancestors are copied to the new class: changes to mixin prototypes will not affect classes to which they have been mixed in.

Ancestors can be compound classes created by this version of declare(). In complex cases all base classes are going to be linearized according to C3 MRO algorithm (see http://www.python.org/download/releases/2.3/mro/ for more details).

"className" is cached in "declaredClass" property of the new class, if it was supplied. The immediate super class will be cached in "superclass" property of the new class.

Methods in "props" will be copied and modified: "nom" property (the declared name of the method) will be added to all copied functions to help identify them for the internal machinery. Be very careful, while reusing methods: if you use the same function under different names, it can produce errors in some cases.

It is possible to use constructors created "manually" (without declare()) as bases. They will be called as usual during the creation of an instance, their methods will be chained, and even called by "this.inherited()".

Special property "-chains-" governs how to chain methods. It is a dictionary, which uses method names as keys, and hint strings as values. If a hint string is "after", this method will be called after methods of its base classes. If a hint string is "before", this method will be called before methods of its base classes.

If "constructor" is not mentioned in "-chains-" property, it will be chained using the legacy mode: using "after" chaining, calling preamble() method before each constructor, if available, and calling postscript() after all constructors were executed. If the hint is "after", it is chained as a regular method, but postscript() will be called after the chain of constructors. "constructor" cannot be chained "before", but it allows a special hint string: "manual", which means that constructors are not going to be chained in any way, and programmer will call them manually using this.inherited(). In the latter case postscript() will be called after the construction.

All chaining hints are "inherited" from base classes and potentially can be overridden. Be very careful when overriding hints! Make sure that all chained methods can work in a proposed manner of chaining.

Once a method was chained, it is impossible to unchain it. The only exception is "constructor". You don't need to define a method in order to supply a chaining hint.

If a method is chained, it cannot use this.inherited() because all other methods in the hierarchy will be called automatically.

Usually constructors and initializers of any kind are chained using "after" and destructors of any kind are chained as "before". Note that chaining assumes that chained methods do not return any value: any returned value will be discarded.

Usage

declare(className,superclass,props);
Parameter Type Description
className String
Optional

The optional name of the constructor (loosely, a "class") stored in the "declaredClass" property in the created prototype. It will be used as a global name for a created constructor.

superclass Function | Function[]

May be null, a Function, or an Array of Functions. This argument specifies a list of bases (the left-most one is the most deepest base).

props Object

An object whose properties are copied to the created prototype. Add an instance-initialization function by making it a property named "constructor".

Returns: dojo/_base/declare.__DeclareCreatedObject | undefined

New constructor function.

See the dojo/_base/declare reference documentation for more information.

Examples

Example 1

declare("my.classes.bar", my.classes.foo, {
    // properties to be added to the class prototype
    someValue: 2,
    // initialization function
    constructor: function(){
        this.myComplicatedObject = new ReallyComplicatedObject();
    },
    // other functions
    someMethod: function(){
        doStuff();
    }
});

Example 2

var MyBase = declare(null, {
    // constructor, properties, and methods go here
    // ...
});
var MyClass1 = declare(MyBase, {
    // constructor, properties, and methods go here
    // ...
});
var MyClass2 = declare(MyBase, {
    // constructor, properties, and methods go here
    // ...
});
var MyDiamond = declare([MyClass1, MyClass2], {
    // constructor, properties, and methods go here
    // ...
});

Example 3

var F = function(){ console.log("raw constructor"); };
F.prototype.method = function(){
    console.log("raw method");
};
var A = declare(F, {
    constructor: function(){
        console.log("A.constructor");
    },
    method: function(){
        console.log("before calling F.method...");
        this.inherited(arguments);
        console.log("...back in A");
    }
});
new A().method();
// will print:
// raw constructor
// A.constructor
// before calling F.method...
// raw method
// ...back in A

Example 4

var A = declare(null, {
    "-chains-": {
        destroy: "before"
    }
});
var B = declare(A, {
    constructor: function(){
        console.log("B.constructor");
    },
    destroy: function(){
        console.log("B.destroy");
    }
});
var C = declare(B, {
    constructor: function(){
        console.log("C.constructor");
    },
    destroy: function(){
        console.log("C.destroy");
    }
});
new C().destroy();
// prints:
// B.constructor
// C.constructor
// C.destroy
// B.destroy

Example 5

var A = declare(null, {
    "-chains-": {
        constructor: "manual"
    }
});
var B = declare(A, {
    constructor: function(){
        // ...
        // call the base constructor with new parameters
        this.inherited(arguments, [1, 2, 3]);
        // ...
    }
});

Example 6

var A = declare(null, {
    "-chains-": {
        m1: "before"
    },
    m1: function(){
        console.log("A.m1");
    },
    m2: function(){
        console.log("A.m2");
    }
});
var B = declare(A, {
    "-chains-": {
        m2: "after"
    },
    m1: function(){
        console.log("B.m1");
    },
    m2: function(){
        console.log("B.m2");
    }
});
var x = new B();
x.m1();
// prints:
// B.m1
// A.m1
x.m2();
// prints:
// A.m2
// B.m2

Properties

Methods

safeMixin(target,source)

Defined by dojo/_base/declare

Mix in properties skipping a constructor and decorating functions like it is done by declare().

This function is used to mix in properties like lang.mixin does, but it skips a constructor property and decorates functions like declare() does.

It is meant to be used with classes and objects produced with declare. Functions mixed in with dojo.safeMixin can use this.inherited() like normal methods.

This function is used to implement extend() method of a constructor produced with declare().

Parameter Type Description
target Object

Target object to accept new properties.

source Object

Source object for new properties.

Returns: Object

Target object to accept new properties.

Examples

Example 1

var A = declare(null, {
    m1: function(){
        console.log("A.m1");
    },
    m2: function(){
        console.log("A.m2");
    }
});
var B = declare(A, {
    m1: function(){
        this.inherited(arguments);
        console.log("B.m1");
    }
});
B.extend({
    m2: function(){
        this.inherited(arguments);
        console.log("B.m2");
    }
});
var x = new B();
dojo.safeMixin(x, {
    m1: function(){
        this.inherited(arguments);
        console.log("X.m1");
    },
    m2: function(){
        this.inherited(arguments);
        console.log("X.m2");
    }
});
x.m2();
// prints:
// A.m1
// B.m1
// X.m1

© 2005–2015 The Dojo Foundation
Licensed under the AFL 2.1 and BSD 3-Clause licenses.
http://dojotoolkit.org/api/1.10/dojo/_base/declare.html

在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号

意见反馈
返回顶部