
零.此文动机
用了一段时间的Lua,用惯了Java C++等有Class关键字的语言,一直对Lua的中的面向对象技术感到费解,一个开源的objectlua更是看了n遍也没理解其中的原理,直到看到了Prototype-based programming
一.什么是基于原型的编程
基于原型的编程是面向对象编程的一种形式,通过复制已经存在的原型对象来实现面向对象,无与基于类的编程较大的区别是没有Class关键字,但是有类的概念。基于原型的编程也可以理解成基于实例的编程。
基于原型的系统可以在程序运行时对原型进行修改,基于类(Java, C+)的语言则很难实现这一点。这么说比较抽象,下面会对比基于原型的类(JavaScript)和基于类的编程区别。
二.JavaScript中的类继承
一.java中的类
java实现类有现成的关键字class,用java实现一个动物类,并实现一个人类来继承动物类。
class Animal {
public Animal() {
name = "Animal";
}
public String eat() {
return "eat!";
}
public String name;
} class People extends Animal {
public People() {
super();
name = "people";
}
}
二.JavaScript中的类
JavaScript定义了少数的数据类型:null,undefined,Boolean,Number,Function,Object(对象)。每个对象都有类属性,但是不能通过.class来访问,只能通过.toString方法来访问。但是很多对象继承的toString()方法重写了,所以要调用Function.call()方法。
object.prototype.toString.call("")
//[object String]
object.prototype.toString.call(1)
//[object Number]
object.prototype.toString.call([])
//[object Array]
function f(){}
object.prototype.toString.call(new f())
//[object Object]
每个对象除了有类属性外,还有原型属性(__proto__),这个属性便是用来继承的,对对象属性的查询,若没有此属性,便到其原型中继续查找。比如有对象A和对象B,A.__proto__ = B,执行代码A.b,若A.b == null, 再查找B.b,若找到则作为A.b的返回,若没有找到则继续到B的原型中找,直到找到或原型(Ojbect.prototype.__proto__)为空。JavaScript中的面向对象需要写一整篇博文来捋顺,下面只写最基本的对象继承。同样是上面人继承动物的例子,JavaScript这么搞:
var Animal = {
name : "Animal",
eat : function() {
return "eat!"
}
}; var People = {
name : "People"
} People.__proto__ = Animal; People.eat()
// "eat!"
People.name
// "People"
People.__proto__ = Animal,便是让People的原型为Animal,实现People对Animal的继承,People.eat()返回“eat!”.
这种原型的继承有什么优点呢?我理解到的是可以进行运行中的类修改,比如下面的代码,程序运行中在想在基类中添加属性或方法,java就不能做到。
//继续上面代码
Animal.run = function () {
return "Animal run";
}
People.run()
// "Animal run"
三.其他基于原型的语言
C++中的类只是对象的布局的定义,其肯定不是基于原型的语言。
那Java呢,Java中的类也是对象,那Java是不是基于原型的语言呢?不是!简单的判断Java提供了Class关键字……更关键的是Java是一种强类型语言,所以其不具有动态扩展性。
个人觉得记忆原型的语言必须具备下面2个特点:
- 弱类型
- 动态可扩展
具备这两个特点的语言看着那么像脚本语言呢,是的,Lua,Tcl,Perl【1】都是基于对象的语言。Python比较特殊,其语言级别提供了Class关键字,但是它又满足弱类型与动态可扩展,这时就不要纠结它是不是面向原型的语言了,个人愿意认为它是基于类的语言,毕竟提供了Class关键字…… 这个貌似是让python看起来像是基于原型语言的东东。
参考
- https://en.wikipedia.org/wiki/Prototype-based_programming
- http://www.cnblogs.com/winter-cn/archive/2008/06/02/1212167.html
- JavaScript权威指南第六版