【注】
关于原型对象的更多理解详见下一节——JavaScript的继承机制;
使用原型模式创建对象的优缺点在于:
优点:对于每个实例的共享属性和方法能够较好实现;
缺点:单独采用原型模式将无法区分不同实例的私有属性;
2.5 混合模式
混合模式,就是综合构造函数模式和原型模式的优缺点,构造函数模式部署实例的私有属性,原型模式部署实例的公有属性;
function Person(name,age){ this.name = name; this.age = age; } Person.prototype.greet = function(){ return "hello "+this.name; } var p1 = new Person("Adam",18); var p2 = new Person("Eve",20);
混合模式是目前使用最广泛、认同度最高的一种创建自定义类型(类)的设计模式;
【注】
当然,设计模式不仅仅上述所提到,还有更加精深可以参考《设计模式》一书以及之前小羊写的一篇文章《设计模式梗概》;
3.JavaScript的继承机制
上一节我们通过创建对象的不同模式,隐式引出了原型对象的概念,这一节中我们将详细了解一下原型对象、原型链及其实现的继承机制;
前面,我们从数据特征上看,知道对象是无序属性(键值对)的集合;
现在,我们可以从面向对象的角度看,任何对象都是更为抽象的对象的实例,可以理解为类的概念;
从这个角度理解,我们现在可以重新定义一下对象和类的含义:
对象可以说是对现实事物的抽象,对象封装了属性和方法,属性值指的是对象的状态,方法指的是对象的行为;
类是提供一种模板的‘对象',它是对象的抽象;
举个简单的栗子:
function Person(name,age){ this.name = name; this.age = age; } Person.prototype.greet = function(){ return "hello "+this.name; } var p1 = new Person("Adam",18); var p2 = new Person("Eve",20);
上述代码表明,p1和p2两个实例是对现实Adam和Eve的抽象,而“类”Person又是对2个实例的抽象,为创建相似结构的人提供标准的模板;
[注]ES6之前JavaScript中没有类,在ES6中定义了类;
3.1 原型对象
在上一节的原型模式中,我们提到每个函数都有一个prototype属性,这个属性指向函数的原型对象,可以部署特定类型的实例共享的属性和方法;
更为深入理解prototype原型对象,prototype原型对象不仅可以部署特定类型的实例共享的属性和方法,而且还是实现JavaScript继承的关键;
只要创建一个新函数就会为该函数创建一个prototype属性,每个prototype属性自动获得一个constructor属性,该属性指向prototype属性所在的函数指针;
当使用构造函数创建一个实例时,该实例内部包含一个内部属性__proto__指向构造函数的原型对象;