Skip to content

工厂模式、构造函数模式、寄生构造函数模式、稳妥构造函数模式 #54

Open
@TieMuZhen

Description

@TieMuZhen

工厂模式

function createPerson(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.say = function () {
        console.log(this.name + this.age + this.job);
    }

    return o;
}

缺点: 没有解决对象识别问题,即无法判断对象的类型

通过constructor属性和instanceof操作符无法正确获得工厂模式创建的对象类型,她们返回的都是基类Object类型

var person = createPerson("Tom", 26, "SoftWare");

console.log(person instanceof createPerson); // false
console.log(person.constructor == createPerson); // false

console.log(person instanceof Object); // true
console.log(person.constructor == Object); // true

构造函数模式

构造函数在不返回值的情况下,默认会返回新对象实例,构造函数解决了对象类型检测问题

function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.say = function () {
        console.log(this.name + this.age + this.job);
    }
}

var person = new Person("Jerry", 18, "Student");

console.log(person instanceof Person); // true
console.log(person.constructor == Person); // true

寄生构造函数模式

工厂模式 + return + new实例化

function ParasiticPerson(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.say = function () {
         console.log(this.name + this.age + this.job);
    }

    return o; 
}

为什么要用这种模式呢?

如果在其他模式(工厂模式、构造函数模式、原型模式等)都不适合的情况下采用寄生构造函数模式,采用这种模式的一个优势在于它可以返回重写后的对象实例(比如说定制某个方法),而不是返回构造函数默认的对象实例

与工厂模式比较,区别

  • 寄生构造函数模式用new创建新对象实例;
var person = new ParasiticPerson("Nicholas", 29, "SoftWare Engineer");

console.log(person instanceof ParasiticPerson); // false
console.log(person.constructor == ParasiticPerson); // false
console.log(person instanceof Object); // true
console.log(person.constructor == Object); // true

但是,与工厂模式相同的是,寄生构造函数模式的实例也不能正确检测其类型

稳妥构造函数模式

与寄生构造函数模式有些类型,但不同点有二:

  • 构造函数内部不使用this
  • 创建对象实例不使用new

使用稳妥构造函数模式的优点是安全性

function DurablePerson(name, age, job) {
    var o = new Object();
    o.say = function () {
        console.log(name + age +  job); // 注意:不使用this,而使用参数传入的变量
    }

    return o;
}

这种模式创建的实例也不能正确检测其类型

var person = DurablePerson("james", 29, "Ball Star");

console.log(person instanceof DurablePerson); // false
console.log(person.constructor == DurablePerson); // false

console.log(person instanceof Object); // true
console.log(person.constructor == Object); // true

总结

工厂模式、寄生构造函数模式、稳妥构造函数模式创建的实例都不能检测其类型,共同的原因是它们都在构造函数内部返回了另一个对象(末尾都有return语句),而不再是构造函数默认的对象(构造函数在不返回值的情况下,默认会返回新对象实例)。

这时候返回的对象与构造函数或构造函数的原型之间没有关系,这就是不能正确检测其实例对象类型的根本原因。

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions