dojo中的类
Posted 左直拳
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dojo中的类相关的知识,希望对你有一定的参考价值。
使用arcgis api for js 4.*进行地图的web前端开发,就不得不与dojo打交道。dojo是一个框架,自成体系,比如它对类的支持,有自己的一套。众所周知,js不是面向对象语言,没有类这一说,都是用函数来模拟类。
那么dojo里的类是怎么样的呢?
1、定义(声明)类
用declare。
declare(基类,类定义)
第一个参数是基类,单个基类或多个基类组成的数组,如果没有基类,则以null或空数组“[ ]”代替。比如下面:
var A = declare(null,
constructor: function(name, age, residence)
this.name = name;
this.age = age;
this.residence = residence;
);
var a = new A("孙悟空",48000,"花果山水帘洞");
类定义,总体上看是一个json。构造函数,各种方法,都是json元素。
constructor,顾名思义,是构造函数。注意name、age、residence并没有声明,直接使用,作为实例的属性。这样不管new多少个A实例,实例之间的属性都不会互相影响。
但我之前不懂,将变量声明在declare之外,new出来的实例,变量居然是共用的。看上去,变量放在declare外部,就相当于全局静态变量。
注:图中的代码,是dojo比较老旧的版本,所以declare有三个参数。
2、继承
//员工类
define(["dojo/_base/declare", "my/Person"], function(declare, Person)
return declare(Person,
constructor: function(name, age, residence, salary)
// The "constructor" method is special: the parent class (Person)
// constructor is called automatically before this one.
this.salary = salary;
,
askForRaise: function()
return this.salary * 0.02;
);
);
//领导类
define(["dojo/_base/declare", 'my/Employee'], function(declare, Employee)
return declare(Employee,
askForRaise: function()
return this.salary * 0.25;
);
);
//使用员工类和领导类
require(["my/Employee", "my/Boss"], function(Employee, Boss)
var kathryn = new Boss("Kathryn", 26, "Minnesota", 9000),
matt = new Employee("Matt", 33, "California", 1000);
console.log(kathryn.askForRaise(), matt.askForRaise()); // 2250, 20
);
3、类的链式初始化
就是从最老的祖宗开始,一代接一代的初始化。
require(["dojo/_base/declare"], function(declare)
var A = declare(null,
constructor: function() console.log("A");
);
var B = declare(A,
constructor: function() console.log("B");
);
var C = declare(B,
constructor: function() console.log("C");
);
new C();
);
// prints:
// A
// B
// C
如果想打断这种链式初始化,如:
require(["dojo/_base/declare"], function(declare)
var A = declare(null,
constructor: function()
console.log("A");
);
var B = declare(A,
"-chains-": //声明链式初始化为手动模式,其实就是打断了链式传播。好滑稽的方法
constructor: "manual"
,
constructor: function()
console.log("B");
);
var C = declare(B,
constructor: function()
console.log("C - 1");
this.inherited(arguments);//显式调用父类初始化,爷爷或更老的祖宗就不必了
console.log("C - 2");
);
var x = new C();
);
// prints:
// C - 1
// B
// C - 2
4、扩展类
如果要扩展一个类,可以用 类.extend(扩展部分定义)。注意扩展部分是扩展,不是完全覆盖。只有重复部分才会被覆盖,原先没有的,则新增到类里。所谓有则改之,无则增加。类修改后,所有的实例都受到影响。
extend返回扩展后的类。
示例如下:
require(["dojo/_base/declare"], function(declare)
var A = declare(null,
m1: function()
// ...
);
A.extend(
m1: function()
// this method will replace the original method
// ...
,
m2: function()
// ...
);
var x = new A();
a.m1();
a.m2();
);
5、派生类
多说无益,直接看代码
require(["dojo/_base/declare"], function(declare)
var A = declare(null,
m1: function(),
s1: "bar"
);
var B = declare(null,
m2: function(),
s2: "foo"
);
var C = declare(null, );
);
对于上述代码,下面2种方法的效果是一样的:
1)方式一
var D1 = A.createSubclass([B, C],
m1: function(),
d1: 42
);
var d1 = new D1();
2)方式二
var D1 = declare([A, B, C],
m1: function(),
d1: 42
);
var d1 = new D1();
其中方式一就使用了createSubclass。由A派生,同时继承B和C。等同于同时继承A、B、C。
createSubclass有两个参数,参数一为基类,参数二为注入新类的定义。所谓注入,即有则改之,无则增加,参考 4、扩展类。
createSubclass与extend的区别,在于extend只是对现有类进行扩展,而createSubclass是继承并派生出一个新类。
6、调用父类方法
inherited()
这个方法十分令人费解。它最多有三个参数。
第一个参数是方法名,可选。不指定,调用的是父类的当前方法的同名方法(?)
第二个参数是arguments,是个伪变量,不用声明。据说用于“内省(introspection)”,不知道是什么意思。反正名字不能改把它当作保留字看待。
第三个参数是传递的参数,如果没有指定,第二个参数arguments就发挥作用。但如果为[“true”],则返回父类方法的定义,而不执行。
如果没有父类方法,则返回undefined。
require(["dojo/_base/lang", "dojo/_base/declare"], function(lang, declare)
var A = declare(null,
m1: function()
// ...
,
m2: function()
// ...
,
m3: function()
// ...
,
m4: function()
// ...
,
m5: function()
// ...
);
var B = declare(A,
m1: function()
// simple super call with the same arguments
this.inherited(arguments);
// super call with new arguments
this.inherited(arguments, [1, 2, 3]);
);
// extend B using extend()
B.extend(
m2: function()
// this method is going to be properly annotated =>
// we can use the same form of this.inherited() as
// normal methods:
// simple super call with the same arguments
this.inherited(arguments);
// super call with new arguments
this.inherited(arguments, ["a"]);
);
// extend B using lang.extend()
lang.extend(B,
m3: function()
// this method is not annotated =>
// we should supply its name when calling
// a superclass:
// simple super call with the same arguments
this.inherited("m3", arguments);
// super call with new arguments
this.inherited("m3", arguments, ["a"]);
);
// let's create an instance
var x = new B();
x.m1();
x.m2();
x.m3();
x.m4(); // A.m4() is called
x.m5(); // A.m5() is called
// add a method on the fly using declare.safeMixin()
declare.safeMixin(x,
m4: function()
// this method is going to be properly annotated =>
// we can use the same form of this.inherited() as
// normal methods:
// simple super call with the same arguments
this.inherited(arguments);
// super call with new arguments
this.inherited(arguments, ["a"]);
);
// add a method on the fly
x.m5 = function()
// this method is not annotated =>
// we should supply its name when calling
// a superclass:
// simple super call with the same arguments
this.inherited("m5", arguments);
// super call with new arguments
this.inherited("m5", arguments, ["a"]);
;
x.m4(); // our instance-specific method is called
x.m5(); // our instance-specific method is called
);
7、在arcgis api for js中的应用
示例
define([
"dojo/_base/declare",
"esri/geometry/support/webMercatorUtils",
"./WebGlLayer",
], function (declare, webMercatorUtils, WebGlLayer)
return declare(null,
constructor: function (mapView)
this.core = new Core(mapView);
,
draw: function (data, options)
this.core.load(data, options);
,
clear: function ()
this.core.clear();
,
);
function Core(mapView)
。。。
);
以上仅为dojo类定义及操作的部分内容。dojo只是一个框架,对类的定义和实现自成一家,有些地方十分有趣。因为前端要用到arcgis api for js,依赖dojo,了解即可,不作深究。dojo有关类的完整阐述,见参考文章。
参考文章:
https://dojotoolkit.org/reference-guide/1.9/dojo/_base/declare.html
以上是关于dojo中的类的主要内容,如果未能解决你的问题,请参考以下文章