工厂模式、寄生构造函数模式、稳妥构造函数模式比较

//工厂模式:
function createPerson(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.say = function () {
        document.write("Hello,I'm " + this.name + "," + this.age + " years old,i'm a " + this.job+"。<br/>");
    }

    return o;
}
//工厂模式的缺点是没有解决对象识别问题,即判断对象的类型:
var person1 = createPerson("wede.zhao", 29, "SoftWare");
document.write(person1 instanceof createPerson); //false
document.write(" --- ");
document.write(person1.constructor == createPerson); //false
document.write("<br/>");
//通过constructor属性和instanceof操作符无法正确获得工厂模式创建的对象类型,她们返回的都是基类Object类型:
document.write(person1 instanceof Object); //true
document.write(" --- ");
document.write(person1.constructor == Object); //true
document.write("<br/>");

//构造函数模式(构造函数在不返回值的情况下,默认会返回新对象实例。):
function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.say = function () {
        document.write("Hello,I'm " + this.name + "," + this.age + " years old,i'm a " + this.job + "。<br/>");
    }
}
//构造函数解决了对象类型检测问题:
var person2 = new Person("kitty", 18, "Student");
document.write(person2 instanceof Person); //true
document.write(" --- ");
document.write(person2.constructor == Person); //true
document.write("<br/>");

//寄生构造函数模式
function ParasiticPerson(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.say = function () {
        document.write("Hello,I'm " + this.name + "," + this.age + " years old,i'm a " + this.job + "。<br/>");
    }

    return o;
}
//为什么要用这种模式呢?答案是:如果在其他模式(工厂模式、构造函数模式、原型模式等)都不适合的情况下采用寄生构造函数模式- _ -!!!《高三》P160
//个人觉得,采用这种模式的一个优势在于它可以返回重写后的对象实例(比如说定制某个方法),而不是返回构造函数默认的对象实例。P161
//与工厂模式比较,区别:1,寄生构造函数模式用new创建新对象实例;2,寄生构造函数模式的包装函数叫做构造函数,而不叫工厂;P160
var person3 = new ParasiticPerson("Nicholas", 29, "SoftWare Engineer");
//但是,与工厂模式相同的是,寄生构造函数模式的实例也不能正确检测其类型:P161
document.write(person3 instanceof ParasiticPerson); //false
document.write(" --- ");
document.write(person3.constructor == ParasiticPerson); //false
document.write("<br/>");

document.write(person3 instanceof Object); //true
document.write(" --- ");
document.write(person3.constructor == Object); //true
document.write("<br/>");

//稳妥构造函数模式
function DurablePerson(name, age, job) {
    var o = new Object();
    o.say = function () {
        document.write("Hello,I'm " + name + "," + age + " years old,i'm a " + job + "。<br/>"); //注意:不使用this,而使用参数传入的变量
    }

    return o;
}
//与寄生构造函数模式有些类型,但不同点有二:1,构造函数内部不使用this;2,创建对象实例不使用new
var person4 = DurablePerson("james", 29, "Ball Star");
//使用稳妥构造函数模式的优点是安全性。P161
//这种模式创建的实例也不能正确检测其类型:
document.write(person4 instanceof DurablePerson); //false
document.write(" --- ");
document.write(person4.constructor == DurablePerson); //false
document.write("<br/>");

document.write(person4 instanceof Object); //true
document.write(" --- ");
document.write(person4.constructor == Object); //true
document.write("<br/>");

//总结:工厂模式、寄生构造函数模式、稳妥构造函数模式创建的实例都不能检测其类型,共同的原因是它们都在构造函数内部返回了另一个对象(末尾都有return语句),
//而不再是构造函数默认的对象(构造函数在不返回值的情况下,默认会返回新对象实例)。
//这时候返回的对象与构造函数或构造函数的原型之间没有关系,也就是说,通过构造函数返回的对象与在构造函数外部创建的对象一样,
//这就是不能正确检测其实例对象类型的根本原因。

posted @ 2018-10-08 15:05  skybirdzw  阅读(685)  评论(0编辑  收藏  举报