有关js模式的重要回答
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(原型扩展)的方式来实现“类”的继承,如,酷猫 > 继承 > 猫 > 继承 > 哺乳动物。
而下面采用了另外一种思路:使用工厂模式来创建对象,不是通过复用原型。而是拆分零部件。每个部件都是可拆卸,可组装的方式,来达到另一种代码复用的效果。
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的精妙之处。
在面向对象语言中:
采用了类继承的方式,实现代码复用。
在javascript中,并没有真正的类。而是用“function”来代表一种类型,
比如:
1
|
function Person(){}; |
我们可以认为,Person就是所谓的javascript中的“类”的概念。我们可以这样
1
2
3
|
var p = new Person(); alert(p instanceof Person); //结果是true,因为p就是Person类型的一个实例。 alert(p instanceof Object); //结果也是true,因为所有实例终归都是Object。 |
而每个类型是如果扩展自己的新方法的呢?就是通过类型的prototype这个属性。
只有function才有prototype属性。
比如:
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.这就是传说中的一句话说不上来就开打。。。 |
原型继承的核心就是这样的。
而另外一种思路就是工厂模式。
小汽车厂
轮子厂
里程计厂
卡车厂
小汽车厂需要轮子和里程计,分别向“轮子厂”和“里程计厂”要来了两个现成的产品,直接安装好,就完成了一辆小汽车。
卡车长也是一样的。所以这种方式也是一种很好的代码结构。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。