首页 > 代码库 > JavaScript之面向对象学习七(动态原型模式和寄生构造函数模式创建自定义类型)
JavaScript之面向对象学习七(动态原型模式和寄生构造函数模式创建自定义类型)
一、动态原型模式
在面向对象学习六中的随笔中,了解到组合构造函数模式和原型模式创建的自定义类型可能最完善的!但是人无完人,代码亦是如此!
有其他oo语言经验的开发人员在看到独立的构造函数和原型时,很可能会感到非常困惑。因为对象在其他oo语言中往往是封装在一块的,而构造函数确是和原型分开的,所以并没有真正意义上的封装,所以动态原型模式正是致力与解决这一问题的一个方案!
动态原型模式将所有的信息都封装在构造函数中(包括原型和实例属性),通过在构造函数中实例化原型(仅在必要的情况下)实现封装,又保持了同时使用构造函数和原型的优点。
function Person(name,age,job){ this.name=name; this.age=age; this.job=job; this.friends=["小超","大超"]; if(typeof this.sayName!="function") {//这段判断语句的作用是限制Person.prototype属性(原型属性对象)只生成一次,要不然每次实例化一个Person对象都会去写一遍原型对象 Person.prototype.sayName = function () { alert(this.name); } Person.prototype.sayHello=function(){ alert("Hello"); } } } var person=new Person("张三",22,"coder"); person.sayName();
注意:typeof this.sayName!="function" 中的this,因为创建Person构造函数时,会创建一个prototype属性,该属性实际上就是Person.prototype的原型对象,prototype属性是一个指针,指向Person.prototype的原型对象,所以构造函数拥有所有Person.prototype的原型对象的属性和方法,而创建Person.prototype圆形对象时,会生成一个constructor属性,该属性也是一个指针,指向Person构造函数,用于判断对象实例的类型!
因为Person构造函数够拥有Person.prototype的原型对象的所有属性和方法,所以可以用this判断原型中是否存在该方法!
当第一次实例化Person对象的时候,原型就已经完成初始化,所以当第二次实例化的时候,原型就不会初始化,而且if语句检查的可以是原型的任意属性和方法,不需要每一个都检查,只需要检查其中一个,对于采用这种模式创建的自定义类型,可以同时使用constructor和instanceof来检查他们的类型,代码如下:
function Person(name,age,job){ this.name=name; this.age=age; this.job=job; this.friends=["小超","大超"]; if(typeof this.sayName!="function") { //这段判断语句的作用是限制Person.prototype属性(原型属性对象)只生成一次,要不然每次实例化一个Person对象都会去写一遍原型对象 Person.prototype.sayName = function () { alert(this.name); } Person.prototype.sayHello=function(){ alert("Hello"); } } } var person=new Person("张三",22,"coder"); var person1=new Person("李四",22,"coder"); alert(person.constructor); //输出: Person构造函数所对应的方法体 alert(person instanceof Person); //输出:true 说明person是Person对象的实例 alert(person.constructor==person1.constructor); //输出:true 说明两个实例的原型对象的constructor属性都指向Person构造函数即他们是同一类型
二、寄生构造函数模式
JavaScript之面向对象学习七(动态原型模式和寄生构造函数模式创建自定义类型)