前面几篇文章讲了那么多,但是还没有讲到主题,那就是如何去构建一个对象。
在js中因为可以用函数来模拟类,所以构建对象的常用方式就是用函数来模拟类,然后用熟悉的new操作符来构建对象。如下代码:
<script type="text/javascript">
function Person(name) {
this.name = name;
}
Person.prototype.say = function() {
alert( this.name );
}
var p = new Person('koma');
p.say();
</script>
上面代码展示的就是基本的js面向对象实现,此时Person函数既是类同时也是类的构造方法。
那通常情况下我们会把类的成员属性在构造函数中进行初始化和定义,而类的成员方法则通过prototype原型来扩展,这样以便达到方法共享的目的。
类中的方法共享是针对继承来说的,那么在js中继承是怎么实现的呢,请看下面的代码:
<script type="text/javascript">
function Person(name) {
this.name = name;
}
Person.prototype.say = function() {
alert( this.name );
}
function koma(name, age) {
Person.call(this, name);
this.age = age;
}
koma.prototype = new Person();
koma.prototype.printage = function() {
alert( this.age );
}
var k = new koma('koma', 21);
k.say();
k.printage();
</script>
上面代码展示的是使用原型方式实现的继承,也就是js中的原型继承。
那原型继承实现的本质就在于:call 与 prototype。首先在子类中(koma)中使用call函数来调用父类(Person)函数,同时动态的改变父类中的this指向,采用这种方式来初始化子类的成员属性。
然后把子类的prototype属性所对应的prototype对象指向为父类的实例(koma.prototype = new Person()),采用这种方式来使得子类可以访问到父类原型上的方法。
通过上面两个步骤就实现了js中的原型继承。
这种是不是很简单呢,通过这种方式实现的js面向对象编程是比较简单的一种方式,像我们熟知的jQuery的本质就是采用这种方式来构建的。
但是有时候我们没有放下“类”的时候,对于上面的定义类的方式是比较难以接受的。那一种比较好的接受方式就是采用js中特有的JSON方式来定义类,如下:
<script type="text/javascript">
var Person = {
name : 'koma',
say : function() {
alert( this.name );
}
};
Person.say();
</script>
采用上面这种方式类定义类,是不是会感觉没那么别扭了呢,但是这种方式又会出现一个问题,就是Person是一个JSON对象,那它是不具有prototype属性的,而且又不是函数所以是不能够通过call方法调用的,这样就不能像上面的方式一样实现继承,但是这种方式真的很好看,很优雅啊,难道不能想个方法来既可以用这种方式来定义类同时又能够实现继承吗?答案是可以的,就是用一种称为“甘露模型”的东西。
那关于甘露模型呢,大家可以去搜李战大哥的书籍《悟透javascript》去详细的理解,我们这里就留到下篇文章来简单的描述一下啦。