首页 > 代码库 > 有关js模式的重要回答

有关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.这就是传说中的一句话说不上来就开打。。。

 

原型继承的核心就是这样的。

 

而另外一种思路就是工厂模式。

小汽车厂

轮子厂

里程计厂

卡车厂

 

小汽车厂需要轮子和里程计,分别向“轮子厂”和“里程计厂”要来了两个现成的产品,直接安装好,就完成了一辆小汽车。

 

卡车长也是一样的。所以这种方式也是一种很好的代码结构。

有关js模式的重要回答