Function.prototype.method =
function
(name, func) {
//在Function的原型上增长一个函数叫作“method”。该方法会在“类”的原型上增长指定函数名的函数。
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(原型扩展)的方式来实现“类”的继承,如,酷猫 > 继承 > 猫 > 继承 > 哺乳动物。javascript
而下面采用了另一种思路:使用工厂模式来建立对象,不是经过复用原型。而是拆分零部件。每一个部件都是可拆卸,可组装的方式,来达到另外一种代码复用的效果。java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
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的精妙之处。app
在面向对象语言中:dom
采用了类继承的方式,实现代码复用。函数
在javascript中,并无真正的类。而是用“function”来表明一种类型,学习
好比:this
1
|
function
Person(){};
|
咱们能够认为,Person就是所谓的javascript中的“类”的概念。咱们能够这样spa
1
2
3
|
var
p =
new
Person();
alert(p
instanceof
Person);
//结果是true,由于p就是Person类型的一个实例。
alert(p
instanceof
Object);
//结果也是true,由于全部实例终归都是Object。
|
而每一个类型是若是扩展本身的新方法的呢?就是经过类型的prototype这个属性。prototype
只有function才有prototype属性。code
好比:
1
2
3
4
5
6
|
function
Person(){}
Person.prototype.say =
function
(){alert(
'hello'
);};
//人这种类型有打招呼的方法
var
p1 =
new
Person();
var
p2 =
new
Person();
p1.say();
//hello
p2.say();
//hello
|
这样,全部实例就均可以用打招呼的方法了。
当咱们建立一个新的类型“男人”。想要继承Person的话。就像下面这样:
1
2
3
4
5
6
7
8
9
10
11
|
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.这就是传说中的一句话说不上来就开打。。。
|
原型继承的核心就是这样的。
而另一种思路就是工厂模式。
小汽车厂
轮子厂
里程计厂
卡车厂
小汽车厂须要轮子和里程计,分别向“轮子厂”和“里程计厂”要来了两个现成的产品,直接安装好,就完成了一辆小汽车。
卡车长也是同样的。因此这种方式也是一种很好的代码结构。