非常荣幸的你能看前面三篇,接这一篇进入正题了,在对之前几篇的介绍也看出来了基本模式,工厂模式,构造模式,原型模式的不足,那么这篇再来说一下两者的结合 — 构造模式和原型模式的结合。这也是目前使用最多,也是最为常见的创建对象的方法,这种方法的概念就是:用构造函数来定义是所有的非函数属性,用原型链来定义对象的函数属性(方法)。结果是所有的函数就创建一次,而每个对象都具有自己的对象属性实例。此外,这种方法还解决了原型链不能传递参数。
在我们所知的 JS 库中,jQuery类型的封装就是使用的原型链和构造模式一起实现的。
下面看实例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
<script>
function Monster(){}
Monster.prototype = {
constructor : Monster, //此处强制的将对象指回构造函数 Monster
name : '小明', //原型字面量方式会将对象的constructor变为Object
age : '21',
job : ['看电视','听音乐'],
run : function(){
return this.name + '的年龄是' + this.age
}
};
var monsterA = new Monster();
alert(monsterA.run());
//构造函数和原型组合模式
function Monster(name,skill){
constructor : Monster;
this.name = name;
this.skill = skill;
}
Monster.prototype = {
run : function(){
return this.name + '会的技能有' + this.skill
}
};
var zhangsan = new Monster('张三',['唱歌','跳舞','画画']);
var lisi = new Monster('李四',['唱歌','跳舞','编程']);
alert(zhangsan.run());
alert(lisi.run());
</script>
</html>
为了让大家很好的区分两个有什么不一样,我把之前原型链模式的代码也放到了上面对照。在我分别弹出两个实例时,并没有覆盖之前的内容,而是两个都顺利的输出了。所以上节课困扰我们的问题也解决了,不同的实例既可以共享 Prototype 里面的方法,也可以有它自己独有的属性。针对之前所出现的所有问题都有解决,在我们工作中也会用到这个比较多,但是说到这不并不是说结合模式是完美的,其实也有一点小小的瑕疵,就是在使用结合模式时对象定义类和方法的时候,属性写一个函数,方法写一个函数,这两个是分离开的,独立的,这样没有像其他的语言一样体现的封装性,但也并不影响我们去使用它。说说下一个动态原型模式,解决了结合模式的封装性。
6、JavaScript 创建对象的动态原型模式。
动态原型放的基本想法与混合构造函数原型方式相同,即在构造函数内定义非函数属性,而函数属性则利用原型属性定义。组合模式中实例属性与共享方法(由原型定义)是分离的,这与纯面向对象语言不一致;动态原型链模式将所有的构造信息都封装在构造函数中,又保持了组合模式的优点。其原理就是通过判断构造函数的原型中是否已经定义了共享的方法或者属性,如果没有则定义,否则不再执行定义过程。该方式指原型上方法或属性只定义一次,且将所有构造过程都封装在构造函数中,对原型所做的修改能立即体现所有实例。
function creatObj(name,age){
this.name = name;
this.age = age;
if(typeof this.run != 'function'){
creatObj.prototype.run = function(){
return this.name + '正在' + this.age
}
}
}
var wangwu = new creatObj('王五',['看电视','打电话','玩手机']);
alert(s1.run());
到这里面向对象的知识都讲完了,下篇说一下使用面向对象的例子。