1.工厂模式

//工厂模式
function createPerson(name,age,job){
var o=new Object();
o.name=name;
o.age=age;
o.job=job;
o.sayName=function(){


function Blog(name, url) {
    this.name = name;
    this.url = url;
    this.alertUrl = function() {
        alert(this.url);
    }
}

var blog = new Blog('wuyuchang', 'http://www.cnblogs.com/wuyuchang/');
console.log(blog instanceof Blog);    // true, 判断blog是否是Blog的实例,即解决了工厂模式中不能

 

 

 


alert(this.name);
};
return o;
}
var person1=createPerson('shanshan',22,'teacher');
var person2=createPerson('sendie',18,'student');

2.构造函数模式

//构造函数模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var person1 = new Person('Nike',29,'teacher');
var person2 = new Person('Arvin',20,'student');

工厂模式与构造函数模式的区别:

1.没有显示地创建对象
 
2.直接将属性和方法赋给了this对象
 
3.没有return语句
 
4.终于可以识别的对象的类型。对于检测对象类型,我们应该使用instanceof操作符,

5.函数手写字母要大写
构造函数虽然好用,但也并非没有缺点,使用构造函数的最大的问题在于每次创建实例的时候都要重新创建一次方法(理论上每次创建对象的时候对象的属性均不同,而对象的方法是相同的),然而创建两次完全相同的方法是没有必要的,因此,我们可以将函数移到对象外面

 

3.原型模式

function Person(){
              Person.prototype.name="shanshan";
              Person.prototype.age=22;
              Person.prototype.job="teacher";
              Person.prototype.sayName=function(){
                  alert(this.name);
              };
              var person1= new Person();
              var person2= new Person();
              person1.name='sisi';
              alert(person1.name);
              alert(person2.name);
          }

4.混合构造函数模式,与原型模式

function Person(name,age,job){ 

this.name =name;
this.age = age;
this.job = job;
}
Person.prototype = {
constructor:Person, sayName: function(){ alert(this.name); };}var person1 = new Person('Nike',20,'teacher');
function Blog(name, url, friend) {
    this.name = name;
    this.url = url;
    this.friend = friend;
}

Blog.prototype.alertInfo = function() {
    alert(this.name + this.url + this.friend);
}

var blog = new Blog('wuyuchang', 'http://www.cnblogs.com/wuyuchang/', ['fr1', 'fr2', 'fr3']),
    blog2 = new Blog('wyc', 'http://**.com', ['a', 'b']);

blog.friend.pop();
blog.alertInfo();    // wuyuchanghttp://www.cnblogs.com/wuyuchang/fr1,fr2
blog2.alertInfo();    // wychttp://**.coma,b
混合模式中构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性。每个实例都会有自己的一份实例属性,但同时又共享着方法,最大限度的节省了内存。另外这种模式还支持传递初始参数。优点甚多。这种模式在ECMAScript中是使用最广泛、认同度最高的一种创建自定义对象的方法。

 

 

 

5.动态原型模式

动态原型模式将所有信息封装在了构造函数中,而通过构造函数中初始化原型(仅第一个对象实例化时初始化原型),这个可以通过判断该方法是否有效而选择是否需要初始化原型。

 

function Blog(name, url) {
    this.name = name;
    this.url = url;

    if (typeof this.alertInfo != 'function') {
        // 这段代码只执行了一次
        alert('exe time');
        Blog.prototype.alertInfo = function() {
            alert(thia.name + this.url);
        }
    }
}

var blog = new Blog('wuyuchang', 'http://www.cnblogs.com/wuyuchang'),
    blog2 = new Blog('wyc', 'http:***.com');

 

6.寄生构造函数模式

 当你需要创建一个自定义类型的时候,当前面的随笔中的模式都不适用的情况下,可以使用寄生构造函数模式。这种模式的基本思想是创建一个函数,该函数的作用仅仅是封装创建对象的代码。

代码如下:

//寄生构造函数模式
function Person(age,name) {
    var o=new Object();
    o.age=age;
    o.name=name;
    o.sayName=function(){
        alert(this.name);
    }
    return o;
}
var person=new Person(22,"张三");
    person.sayName();

//工厂模式
    function createPeron(name,age,job){
        var object=new Object();
        object.name=name;
        object.age=age;
        object.job=job;
        object.sayName=function(){
            alert(this.name);
        }
        object.sayForm=function(){
            alert(typeof this);
        }
        return object;
    }
    var person=createPeron("姗姗",20,"teacher");
    person.sayName();
    person.sayForm();
在上面寄生模式的例子中,Person函数创建了一个新对象,并以相应的属性和方法初始化该对象,然后又返回这个对象。

然后分析其与工厂模式的区别:

1、寄生模式创建对象时使用了New关键字

2、寄生模式的外部包装函数是一个构造函数

除了上面这2个区别寄生模式和工厂模式几乎一样,构造函数在不返回值的情况下,默认返回对象的新实例。而通过在构造函数的末尾添加一个return 语句,可以重写调用构造函数是返回的值

 

作用:寄生模式可以在特殊的情况下为对象来创建构造函数,原因在于我们可以通过构造函数重写对象的值,并通过return返回  重写调用构造函数(创建的对象的实例)之后的对象实例的新的值。

假设我们想创建一个具有额外方法的特殊数组。由于不能直接修改Array构造函数,所以我们可以使用寄生模式。代码如下:

复制代码
function SpecialArray() {
    //创建数组
    var array=new Array();
    //添加值  arguments获取的是实参,不是形参,所以SpecialArray()并没有形参接收传递过来的参数
    array.push.apply(array,arguments);
    array.toPipedString=function(){
        return this.join("|");
    }
    return array;
}
var colors=new SpecialArray("red","blue","black");
alert(colors.toPipedString());  //输出:red|blue|black
复制代码
我们利用寄生构造函数模式,在不修改Array构造函数的情况下,通过为Array对象创建构造函数达到修改Array对象的目地;

在分析上面的代码:

1var array=new Array();创建了一个Array对象

2return array;在经过一系列的修改之后返回修改之后的Array对象

3var colors=new SpecialArray("red","blue","black"); 创建了一个SpecialArray对象,接收的确是修改之后的Array对象的实例值

所以return array;返回的对象是Array类型,而且colors接收了这个返回的对象,所以colors并不是SpecialArray构造函数的实例,而是Array的实例,下面的代码可以说明:

alert(colors instanceof SpecialArray); //输出:false
alert(colors instanceof Array); //输出:true
所以,由于存在上述问题,如果能使用其他的模式的情况下,建议不要使用这种模式.

7.

稳妥构造函数模式

道格拉斯 *  克罗克福德 发明了JavaScript中的稳妥对象这个概念.所谓稳妥对象,指的是没有公共属性,而且其方法也不引用this的对象。稳妥对象最适合用在一些安全的环境中(这些环境会禁止使用new和this),或者防止数据被其他的应用改动。

稳妥构造函数与寄生构造函数模式类似,但是也有两点区别:

1、稳妥模式不使用new操作符调用构造函数

2、新创建对象的实例方法不引用this

其代码如下:


function Person(name,age) {
    //创建要返回的对象
    var o=new Object();
    //可以在这里定义私有变量和函数
    //添加方法
    o.sayName=function(){
        alert(name);
    }
    //返回对象
    return o;
}
var person=Person("姗姗",20);
    person.sayName();  //使用稳妥构造函数模式只能通过其构造函数内部的方法来获取里面的属性值

上面的代码定义了一个person变量,里面保存的是一个稳妥对象,而除了吊用他的sayName()方法外,没有别的方法可以访问其数据成员。即使有其他的代码会给这个对象添加方法和数据成员,但也不可能有别的方法访问到传入到构造函数中的原始数据。稳妥构造函数模式提供的这种安全性。是的它非常适合在某些安全执行环境中。