给javascript加上 final 和 private 定义吧
前一段时间为了把backbone这个未完工的脚手架加工成一个全尺寸的框架,设计了一个叫做Stemcell的框架。但是javascript的灵活性,让框架的使用者在使用的过程中总会心惊胆颤,不知道什么时候会触碰了框架的底线(专业术语叫做G Spot),从而让系统处于“楼即将脆脆”的状态。
于是在实现Stemcell的过程中愈加感觉其他面向类的语言(面向类的语言不是面向对象的语言)中的种种呆板的特性现在竟然有点天然呆的可爱,所以昨天下午花了3个小时实现了一个小的基于javascript对象的 对象模型: Class.Model.js
它定义了如下几个特性:
- 一个BasicClass,认为所有从它派生出来的类都是继承自它
- 一个extend方法,便于继承
- 一个final字段的定义
- 一个private字段的定义
var Car = Class.new({
speed : null,
color : null,
initialize : function(args){
this.speed = args.speed;
this.color = args.color;
this.distance = args.distance;
},
getHours : function(){
}
})var car = Car.new({
speed : "220KM",
color : "black",
distance : "128320KM"
});var Car = Class.new({
speed : null,
color : null,
initialize : function(args){
this.speed = args.speed;
this.color = args.color;
this.distance = args.distance;
},
getHours : function(){
}
}) var Car = Class.new({
speed : null,
color : null,
initialize : function(args){
this.speed = args.speed;
this.color = args.color;
this.distance = args.distance;
},
getHours : function(){
this.hours();
}
private : {
hours : function(){
var distance = parseInt(this.distance);
var speed = parseInt(this.speed);
var hours = distance / speed;
alert("I have been driven for " + hours + " hours");
}
}
})var car = Car.new({
speed : "220KM",
color : "black",
distance : "128320KM"
});
car.hours(); // 会抛出一个“找不到方法”的错误var RaceCar = Car.extend({
brand : null
});Car.find = function(){
alert("looking for sth")
}
// 为Car类定义了一个类方法 find
RaceCar.find() // -> 会弹出“looking for sth” Car类有一个名为find的类方法,继承自Car的RaceCar 同样可以调用find方法。
final的定义
有时候我们希望框架的使用者在使用我们的框架时,不要因为继承而复写了我们父类中的方法,导致框架不可用,这时候非常需要javascript有类似final关键字,可以阻止这一惨剧的发生。
下面来看看Class.Model.js中final方法的定义,定义方法和private方法的定义类似,比如我们要给Car加上名为buzz的final方法,这个方法规定了车怎样鸣嘀,我们不希望不一样的车会有不同的鸣嘀方式,比如复写为“什么样的歌声才是最开怀”:
var Car = Class.new({
speed : null,
color : null,
initialize : function(args){
this.speed = args.speed;
this.color = args.color;
this.distance = args.distance;
},
getHours : function(){
this.hours();
},
final : {
buzz : function(){
alert("i can speed up to " + this.speed + " , and I'm " + this.color);
}
},
private : {
hours : function(){
var distance = parseInt(this.distance);
var speed = parseInt(this.speed);
var hours = distance / speed;
alert("I have been driven for " + hours + " hours");
}
}
}) 将buzz方法的定义放在final字段中欧你,这样buzz方法就不能被子类复写了。
var RaceCar = Car.extend({
brand : null
});var car = Car.new({
speed : "220KM",
color : "black",
distance : "128320KM"
});car.buzz() // --> 将会弹出框显示 “i can speed up to 220KM , and I'm black”
var raceCar = RaceCar.new({
speed : "280KM",
color : "red",
distance: "311983KM"
})raceCar.buzz() // -> 会弹出类似的alert框
但是如果我们不小心在子类的定义中复写了buzz方法会怎么样呢?来看代码:
var RaceCar = Car.extend({
brand : null,
buzz : function(){
alert("什么样的歌声才是最开怀!!!")
}
});上面的RaceCar定义中重新定义了buzz方法,那么在js runtime运行到这个地方的时候会抛出一个异常:
如此,就可以保证父类中的final字段下定义的方法不会被子类复写了。
Class.Model.js定义的对象模型就是这样的,只提供了几个简单的特性,如果对这个东西感兴趣,可以到
https://gist.github.com/4441106
找到Class.Model.js的代码。
欢迎fork欢迎使用欢迎提出意见北京欢迎您