Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【js框架系列笔记】浅谈prototype.js的面向对象 #8

Open
EchoFUN opened this issue Oct 29, 2013 · 0 comments
Open

【js框架系列笔记】浅谈prototype.js的面向对象 #8

EchoFUN opened this issue Oct 29, 2013 · 0 comments

Comments

@EchoFUN
Copy link
Owner

EchoFUN commented Oct 29, 2013

本文假定你有了一定的javascript面向对象的基础了,就不过多的关于javascript面向对象基础的介绍。
首先,让我们来举个例子,做个传统意义上的javascript的继承。

/**
 * @description 新建个“人类”的类,拥有三个初始的属性,姓名,年龄,性别。
 * 在其构造方法中,我们可以对这些属性做一个初始化的工作。
 *
 * @param {string} name 
 * @param {number} age
 * @param {string} gender
 */
function Humen(name, age, gender) {
  this.age = 0 || age;
  this.name = '' || name;
  this.gender = '' || gender;
}
Humen.prototype.eat = function() {}
Humen.prototype.sleep = function() {}

/**
 * @description 新建个“超人”的类,拥有三个初始的属性,姓名,年龄,性别。
 * 在完成了和人类相同的属性的同时,他比人类还多了一个属性“power”,能量值。
 *
 * @param {string} name 
 * @param {number} age
 * @param {string} gender
 * @param {number} power
 */
function SuperMen(name, age, gender, power) {
  this.age = 0 || age;
  this.name = '' || name;
  this.gender = '' || gender;
  this.power = '' || power;
}
SuperMen.prototype = new Humen;
SuperMen.prototype.constructor = SuperMen;
SuperMen.prototype.eat = function() {}
SuperMen.prototype.fly = function() {}

OK, 初步完成了一个“人类”和一个“超人”的基本结构了,下面让我们看下这段对“人类”的描述代码,在结构上究竟有什么不足呢?

  1. SuperMen在继承的过程中出现了代码的冗余,this.xxx重复的调用了。
  2. 在“超人”中,同样拥有了“人类”吃的属性,但是超人可能“吃”的具体行为和“人类”不一样。“超人”需要在拥有了“人类”吃的全部属性的同时,增加一些新的特点,比如喝喝汽油,吃吃燃料啥的。在代码中的具体表现,就是突发调动父类的方法。导致了代码会冗余。
  3. 结构不够优雅(好吧,这个就见仁见智了,要是你说这样的代码很漂亮,那… … 他就很漂亮吧~)

下面让我们看下prototype.js对这段代码的重新定义

var Humen = Class.create({
  initialize: function(name, age, gender) {
    this.age = age;
    this.name = name;
    this.gender = gender;
  },
  eat: function() {
    console.log('I eat normal food !');
  },
  sleep: function() {}
});

var SuperMen = Class.create(Humen, {
  initialize: function($super, name, age, gender, power) {
    $super(name, age, gender, power);
  },
  eat: function($super) {
    $super();
    console.log('I am ' + this.name + ', I still can eat gasoil, can you ?');
  }
})

var sm = new SuperMen('supermen');
sm.eat();

结果如下:
I eat normal food ! general.js:9
I am supermen, I still can eat gasoil, can you ?

嗯,让我们现在再来做个对比,看看prototype.js中OOP的继承部分的大概结构。
prototype.js定义类的方法很简单,比起原始的js用function来定义而言,引入了Class类别。具体可以看这里。
initialize方法定义了这个类的构造函数,初始化类的基本数据。这里,值得关注的是构造方法中的第一个参数$super,如果父类中有同样的方法,$super则表示父类中同名的函数。这样一来,是不是就可以调用父类的方法了呢。而不至于造成代码的冗余。

在prototype.js的类中,有两个比较特别的参数superclasses,subclasses。分别表示了当前类的所有的子类,或者是所有的父类。这样一来,在当前的类中,我们就不不止可以操作父类中的方法,而且祖宗八倍的方法都可以调用了
是不是很棒!?

prototype.js异于jQuery的最明显的区别,就在于设计的理念不一样了,jQuery崇尚的是select and do,而在Prototype.js里,体现的更多的是一切皆是对象的思想。
prototype.js胜于jQuery的一步就在于它在定义了一些工具类方法,屏蔽了浏览器差异的同时,也为灵活的js规定了一套编程的规范,代码的规整,类的封装等等。使用这套框架的开发人员都按照这样的规则去写,代码就不至于显得太凌乱。
转载请注明出处
botobe.net
本文Github链接

2012.08.13
一切安好。
Merci !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant