Dojo class中跟变量相关的几个问题
Dojo class中跟变量相关的几个问题针对 Java 开发人员的 Dojo 概念是学习dojo不得不读的一篇文章。本文对该文中没有详尽讲述的的跟变量相关的几个问题做一些阐述。 引文中在“复杂的类属性”一节,举例如下: dojo.declare(
"myClass",null,{
globalComplexArg : { val : "foo" },localComplexArg : null,constructor : function() {
this.localComplexArg = { val:"bar" };
}
}
);
// Create instances of myClass A and B...
var A = new myClass();
var B = new myClass();
// Output A's attributes...
console.log("A's global val: " + A.globalComplexArg.val);
console.log("A's local val: " + A.localComplexArg.val);
// Update both of A's attributes...
A.globalComplexArg.val = "updatedFoo";
A.localComplexArg.val = "updatedBar";
// Update B's attributes...
console.log("A's global val: " + B.globalComplexArg.val);
console.log("A's local val: " + B.localComplexArg.val);
引文中谈到,“类属性可以在声明时进行初始化,但是如果使用复杂对象类型(例如 hash 或数组)初始化属性,该属性将类似于 Java 类中的公共静态变量。这意味着任何实例无论在何时更新它,修改将反映到所有其他实例中。为了避免这个问题,应当在构造函数中初始化复杂属性;然而,对于字符串、布尔值等简单属性则不需要这样做。 ”这里需要特别强调的是,上述示例中的localComplexArg是类的属性之一,但当一个“类”实例化以后,这个属性的取值是各个实例自己拥有一份,不会共享。globalComplexArg只是类似于Java类的公共静态变量,但从其调用方法来看,仍然必须通过实例化的对象来调用,所以dojo的本意并非要将其模拟为一个类的静态变量。它的存在,更象是一个不得已的例外。
dojo.declare("my.GrandPa",{
print:function(msg){
console.log("this is grandpa:",msg);
}
});
dojo.declare("my.Parent",[my.GrandPa],{
a : 0,b : [],constructor:function(){
this.c = 110;
this.b.push('Parent()');
},print:function(msg){
console.log("my.Parent.print:a=%s,b = [%s],c=%s ",this.a,this.b,this.c,msg);
}
});
dojo.declare("my.Son",[my.Parent],{
a : 10,constructor:function(){
this.b.push('Son()');
},print:function(msg){
console.log("in my.Son ",msg);
this.inherited(arguments);
}
});
var g1 = new my.GrandPa();
g1.print("from g1");
var f1 = new my.Parent();
f1.print("from f1");
f1.a = 100;
f1.b.push(125);
f1 = null;
var f2 = new my.Parent();
f2.print("from f2");
f2.a = 99;
f2.print("from f2,after a changed");
var s1 = new my.Son();
s1.print("from s1");
g1.print("from g1 again");
运行上例,得到输出如下: this is grandpa: from g1
my.Parent.print:a=0,b = [Parent()],c=110 from f1
my.Parent.print:a=0,b = [Parent(),125,Parent()],c=110 from f2
my.Parent.print:a=99,c=110 from f2,after a changed
in my.Son from s1
my.Parent.print:a=10,Parent(),Son()],c=110 from s1
dojo.xd.js (第 3306 行)
this is grandpa: from g1 again
上述代码首先定义了一个GrandPa类,没有任何属性,只有一个方法。然后定义了Parent类,它有简单属性a和一个数组b,并在构造函数中,将构造函数的名字保存至数组b中。代码第31行比较有趣。此时f1是Parent类的惟一一个实例,通过f1= null我们将其析构。此时f1.a不再可以访问,但数组b仍然保存了我们刚刚push进去的值125,并且在我们实例化对象s1时,可以再次访问这个值。 结论:从上例我们可以发现,
上例中没有揭示当子类覆盖了父类的属性和方法后,是否还可以访问父类的属性和方法?当然,子类覆盖父类的属性,实质是使用不同的值进行初始化,保存父类属性的初始化值并没有意义。而要访问父类的方法,可以使用this.inherited(arguments)。注意,这是个固定的写法,不可以有任何改变。即参数一定是arguments,而且一定要带上。此外,dojo还做了一个有意义的扩展,即调用链。传统语言只在构造函数上有调用链,即当子类实例化时,会优先调用父类的构造函数,然后才是子类的构造函数。但dojo通过声明”-chains-”属性,实现了对其它方法的链式调用,并且可以指明基类函数和派生类函数的先后调用次序。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
