你明白寄生构造函数模式了吗

前言

在《JavaScript高级程序设计》面向对象的程序设计中,在关于如何创建对象时,有个章节是介绍寄生构造函数模式,这个模式虽然并不是很常用,但我在第一次在书中读到这部分时,并不是很明白书中提到的 ”Person函数创建了一个新对象,并以相应的属性和方法初始化该对象,然后又返回了这个对象。除了使用new操作符并把使用的包装函数叫做构造函数之外,这个模式跟工厂模式其实是一模一样的。构造函数在不返回值的情况下,默认会返回新对象实例。而通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值。“ 以及 ”有一点需要说明:首先,返回的对象与构造函数或者与构造函数的原型属性之间没有关系;也就是说,构造函数返回的对象与在构造函数外部创建的对象没有什么不同。为此,不能依赖instanceof操作符来确定对象类型。由于存在上述问题,我们建议在可以使用其他模式的情况下,不要使用这种模式。“

当时对这两段话很是困惑,如今再读这本书,突然发现对这两段话已经可以理解了,那么接下来就来说一下我的理解吧。

正文

先附上书中提到的例子:

function Person (name,age,job) {
            var o = new Object();
            o.name = name;
            o.age = age;
            o.job = job;
            o.sayName = function(){
                alert(this.name);
            };
            return o;
        }
        var friend1 = new Person('lisi',29,'Software Engineer');

我们再附上工厂模式:

function person (name,age,job) {
            var o = new Object();
            o.name = name;
            o.age = age;
            o.job = job;
            o.sayName = function(){
                alert(this.name);
            };
            return o;
        }
        var friend2 = person('lisi',29,'Software Engineer')

这里可以比较明显的看出寄生构造函数模式与工厂模式的区别,即寄生构造函数模式使用了new去实例化一个对象即 new Person(),而工厂模式是直接调用函数person(),这两者创建的实例其实都是一个Object的实例,用console.dir(friend1)和console.dir(friend2),

image-20200808110723558

然后是friend2

image-20200808110916921

可以发现friend1和friend2是一样的,那么如果寄生构造函数模式在去掉return之后再去用new实例化对象呢:

function Person (name,age,job) {
            var o = new Object();
            o.name = name;
            o.age = age;
            o.job = job;
            o.sayName = function(){
                alert(this.name);
            };
        }
        var friend1 = new Person('lisi',29,'Software Engineer');

再次用console.dir(friend1)控制台打印friend1:

image-20200808111349160

可以看出这次的friend1就已经是一个Person的实例了,这也就是说在寄生构造函数模式使用return后,会切断实例化对象与构造函数Person的联系。

现在我的只是还不够不能解释为什么在return返回内部实例化的对象后,在使用new操作符就修改了实例化的对象的原型,后面如果我弄懂了会继续补充。

posted @ 2020-08-08 11:45  翻滚吧斑马  阅读(247)  评论(0编辑  收藏  举报