if (!this.prototype[name]) {
this.prototype[name] = func
}
}
Object.method('superior', function (name) {//增加一个超级方法。该方法保存它从原型上继承来方法。用来模拟面向对象中的super关键字。
var that = this,
method = that[name]
return function ( ) {
return method.apply(that, arguments)
}
})
var mammal = function (spec) {//定义一个哺乳动物类型。
var that = {}
that.get_name = function ( ) {//获取动物名字。
return spec.name
}
that.says = function ( ) {//动物打招呼的方法。
return spec.saying || ''
}
return that
}
//var myMammal = mammal({name: 'Herb'})//创建一个哺乳动物的实例。
var cat = function (spec) {//定义一个“猫”的类型。
spec.saying = spec.saying || 'meow'//为这个类型指定一个“叫声”,这里是“喵”
var that = mammal(spec)//创建一个哺乳动物实例。
that.purr = function (n) {//为这个哺乳动物创建一个猫的咕噜咕噜声音的方法“purr”
var i, s = ''
for (i = 0 i < n i += 1) {
if (s) {
s += '-'
}
s += 'r'
}
return s
}
that.get_name = function ( ) {//获取“猫”的名字。猫的叫声(meow) + 猫的名字 + 猫的叫声(meow)
return that.says( ) + ' ' + spec.name +
' ' + that.says( )
}
return that
}
var myCat = cat({name: 'Henrietta'})//创建一只猫的实例。名字叫Henrietta
var coolcat = function (spec) {//创建一个“酷猫”的类型
var that = cat(spec),//创建一只普通猫。
super_get_name = that.superior('get_name')//保存普通猫的“获取名字”的方法。
that.get_name = function (n) {//酷猫有自己的“获取名字”的方法,“like” + 普通猫的“获取名字方法” + “baby”
return 'like ' + super_get_name( ) + ' baby'
}
return that
}
var myCoolCat = coolcat({name: 'Bix'})//创建一只酷猫。
var name = myCoolCat.get_name( )//酷猫的名字是like meow Bix meow baby
// 'like meow Bix meow baby'
上面采用prototype(原型扩展)的方式来实现“类”的继承,如,酷猫 >继承 >猫 >继承 >哺乳动物。
而下面采用了另外一种思路:使用工厂模式来创建对象,不是通过复用原型。而是拆分零部件。每个部件都是可拆卸,可组装的方式,来达到另一种代码复用的效果。
function createCar(numberOfDoors){//造车厂,指定门的数量,并制造一辆汽车。var numberOfWheels = 4//轮子的数量是4.
function describe(){//描述一下车辆。
return "I have " + numberOfWheels + " wheels and " + numberOfDoors + " doors."
}
return {//返回制造完成的汽车。
describe: describe
}
}
function createOdometer(){//加工车载里程计。
var mileage = 0
function increment(numberOfMiles){ mileage += numberOfMiles}//里程计跑表的方法
function report(){ return mileage }//报告当前的里程数
return {//返回制造完成的里程计
increment: increment,
report: report
}
}
function createCarWithOdometer(numberOfDoors){//制造带有里程计的汽车
var odometer = createOdometer()//制造一个里程计
var car = createCar(numberOfDoors)//制造一辆车
car.drive = function(numberOfMiles){//将里程计安装到汽车上,当汽车行驶的过程中,调用里程计的跑表方法。
odometer.increment(numberOfMiles)
}
car.mileage = function(){//报告汽车的里程,通过已安装的里程计的报告方法,获取里程。
return "car has driven " + odometer.report() + " miles"
}
return car//返回制造并组装完毕的汽车。
}
var twoFn=createCarWithOdometer(100)//创造一辆带有100个门的汽车(当然不可能。。Σ( ° △ °|||)︴)
console.log(twoFn)
上述两种方式,体现了javascript的精妙之处。
在面向对象语言中:
采用了类继承的方式,实现代码复用。
在javascript中,并没有真正的类。而是用“function”来代表一种类型,
比如:
function Person(){}我们可以认为,Person就是所谓的javascript中的“类”的概念。我们可以这样
var p = new Person()alert(p instanceof Person)//结果是true,因为p就是Person类型的一个实例。
alert(p instanceof Object)//结果也是true,因为所有实例终归都是Object。
而每个类型是如果扩展自己的新方法的呢?就是通过类型的prototype这个属性。
只有function才有prototype属性。
比如:
function Person(){}Person.prototype.say = function(){alert('hello')}//人这种类型有打招呼的方法
var p1 = new Person()
var p2 = new Person()
p1.say()//hello
p2.say()//hello
这样,所有实例就都可以用打招呼的方法了。
当我们创建一个新的类型“男人”。想要继承Person的话。就像下面这样:
function Man(){}var proto = Man.prototype = new Person()//男人也是人啊,男人的原型就是以一个普通人为标准来参考的,所以我们创建一个人类,赋值给男人,让男人来学习,参考人的特性。
proto.fight = function(){//男人比起人来,脾气大,因此有个打架的方法。
alert('I\'ll kick your ass!!')
}
var m = new Man()
m.say()//hello
m.fight()//I'll kick your ass.这就是传说中的一句话说不上来就开打。。。
原型继承的核心就是这样的。
而另外一种思路就是工厂模式。
小汽车厂
轮子厂
里程计厂
卡车厂
小汽车厂需要轮子和里程计,分别向“轮子厂”和“里程计厂”要来了两个现成的产品,直接安装好,就完成了一辆小汽车。
卡车长也是一样的。所以这种方式也是一种很好的代码结构。