关于js的设计模式(简单工厂模式,构造函数模式,原型模式,混合模式,动态模式)

关于js的各大模式,还有不少东西没有了解到,接触的越多,愈加以为这东西颇有用。javascript

<1>工厂模式php

简单来讲就是封装后的代码,简单的工厂模式是很好理解的,关于它的做用,就是利用面向对象的方法,把一些对象封装,使一些占用空间多的,重复的代码封装起来。实现方法很是简单,也就是在函数内建立一个对象,给对象赋予属性以及方法再将对象返回便可。html

function creatper(name,age){  html5

var per=new Object(); //原料java

//加工node

 per.name=name;mysql

 per.age=age;  sql

per.sayHi=function(){oracle

  console.log(per.name+''+per.age);  }  函数

return per; //出厂

}

var me=creatper('katherine',22);

me.sayHi();

console.log(me.name);

能够看出,使用工厂模式,能够重复调用这个per函数来生成不一样属性值得对象,这就像工厂同样,批量生产,里面的原料,加工,出厂都很清晰。可是你会发现工厂模式是没法识别对象的类型,由于全都是object,不像Date,Array等,可是构造函数就不是了。这还只是简单的工厂模式,复杂的工厂模式(抽象模式)等之后再回来详细了解。

<2>构造函数模式

ECMAScript中构造函数能够用来建立特定对象,相似于Array,Date等原生的js对象

function Student(name,age,classa){
 this.name=name;
 this.age=age;
 this.classa=classa;
 this.sayHello=function(){
  console.log(this.name,this.age,this.classa);
 }
}
var me=new Student("xiaoai",22,"大三");
console.log(me.classa);
me.sayHello();
console.log(me instanceof Student);//true

由代码能够看出,于工厂模式除了函数名不一样之外,还要注意:构造函数名的首字母大写(不过好像没有严格规定)。构造函数也没有显示建立的对象,使用了this,直接把属性和方法赋值给了this对象。没有return语句,实例化的时候要使用new,并且它可以识别对象(这正是构造函数模式胜于工厂模式的地方)。

构造函数虽然好用,但也有很大的缺点,就是每次建立实例的时候都要从新建立一次方法,实际应用中,每次建立对象的时候属性值不一样,而对象的方法倒是相同的,因此建立两次彻底相同的方法是没有必要的,所以有人会说能够把函数方法放到对象外面。以下:

function Student(name,age,classa){
 this.name=name;
 this.age=age;
 this.classa=classa;
 
}
function sayHello(){
  console.log(this.name,this.age,this.classa);
 }
var me=new Student("xiaoai",22,"大三");
console.log(me.classa);
me.sayHello();
console.log(me instanceof Student);

这样一改,就把sayhello函数设置成了全局函数,这样一来Student的每个实例访问的都是同一个函数,但是,在全局做用域中定义一个只供student使用的函数,就显得有些过度了,若是在全局做用域中定义许多这样仅供特定对象使用的方法,那就太浪费空间了,显然也失去了面向对象所注重的封装性了,所以彻底可使用原型解决这个问题。

 

<3>原型模式

js规定每个建立的函数都有prototype(原型)属性,这个属性是指针,指向一个对象,而这个对象的用途是包含由特定类型的全部实例所共享的属性和方法,使用原型对象就可让全部实例对象均包含这些属性及方法。

function per(){}

per.prototype.name='xiaoai';

per.prototype.age=22;

per.prototype.course=['php','javascript','java','C#'];

per.prototype.say=function(){

 console.log(this.name+this.age+this.course);

}

var per1=new per();

var per2=new per();

per1.name='katherine';

per1.course.push('Html5');

per1.say();

per2.say();

per2.course.pop();

关于原型模式的缺点,我想也是很明显的,它省略了构造函数传递初始化参数这一环节,结果全部实例均在默认状况下取得了相同的属性值,虽然你能够在后来作出更改,但一点都不方便,这样还不是最大的问题,原型模式最大的问题是在于共享的本性所致使的,因为共享,所以一个实例修改了引用,另外一个也随之更改了属性。所以通常不会单独使用原型模式。

<4>混合模式(原型模式+构造函数)

function per(name,age,course){

this.name=name;

this.age=age;

this.course=course;

}

per.prototype.say=function(){

 console.log(this.name+this.age+this.course);

}

var per1=new per('katherine',22,['C#','java','PHP','Javascript']);

var per2=new per ('xiaoai',21,['oracle','mysql','nodejs','html5']);

per1.say();

per2.say();

per1.course.pop();

per1.say();

per2.say();

由代码能够看出混合模式的分工:构造函数用于定义实例的属性,而原型模式用于定义方法和一些共享的属性。每一个实例都会有本身的属性,但同时又共享着方法,最大限度的节省了内存。另外这种模式还支持传递初始参数。使用最普遍。

<5>动态模式

function per(name,age,course){  

this.name=name;

 this.age=age;

 this.course=course;

 if(typeof this.say!='function'){  

       per.prototype.say=function(){  

          console.log(this.name+this.age+this.course);

         }

  }

}

var per1=new per('katherine',22,['C#','java','PHP','Javascript']);

 var per2=new per('xiaoai',22,['oracle','mysql','nodejs','html5']);

 per1.say();

 per2.say();  

per1.course.pop();  

per1.say();

 per2.say();

 

动态原型模式将全部的信息都封装进了构造函数中,经过构造函数中初始化原型,仅第一个对象实例实例化时初始化,经过判断该方法是否有效存在而选择是否须要初始化。大白话就是:若是去掉if的话,每new一次(即每当一个实例对象生产时),都会从新定义一个新的函数,而后挂到per.prototype.say上,而实际上,只须要定义一次就够了,由于全部的实例都会共享此属性的,因此若是去掉if的话,会形成没有必要的时间和空间的浪费,而加上if后,只在new第一次实例化时会定义say方法,以后都不会再定义了。能够看出对于这种模式建立的对象,是最好的了。

 

 

 

 

 

 

 

本文章参考了http://www.jb51.net/article/53823.htm,只供本人学习笔记使用。

相关文章
相关标签/搜索