对象创建模式|青训营

176 阅读5分钟

对象创建模式

一、Object构造函数模式

 var p = new Object()
        p.name = '小鸟游星野'
        p.age = 16
        p.setName = function (name) {
            this.name = name
        }
	    console.log(p.name, p.age);
        p.setName('黑见芹香')
        console.log(p.name, p.age);

这里我们先创建了一个p的空对象,在给对象添加了属性和方法,在这里我们创建了setName方法可以进行姓名的交换。如上代码所示会优先写出星野,其次才是芹香

image-20230819142928205转存失败,建议直接上传图片文件

套路:先创建空的object对象,再动态添加属性/方法;

使用场景:起始时不确定对象内部数据;

当然这种方法也存在问题:语句太多。

二、对象字面量模式

 var p = {
            name:'黑见芹香',
            age:17,
            setName:function(name){
                this.name=name;
            }
         }

         console.log(p.name,p.age);
         p.setName('小鸟游星野');
         console.log(p.name,p.age);

现在这种方式对比上面哪一种会发现我们是优先创建对象且将对象中的属性/方法一并定义出来。

image-20230819143354962转存失败,建议直接上传图片文件

但此时如果我们还要再定义一个叫p2的对象我们还要再次去对上面的代码进行重复很麻烦。我们都知道在一个项目中代码越少性能会越好。

套路:使用{}创建对象,同时指定属性/方法;

使用场景:起始时对象内部数据是确定的;

问题:如果创建多个对象,会有大量的重复代码。

三、工厂模式

  function createPerson(name,age){ //返回一个对象的函数==>工厂函数
            var obj={
                name:name,
                age:age,
                setName:function(name){
                    this.name=name
                }
            }
            return obj;
        }

我们创建一个creatPerson的函数在函数中我们创建一个对象进行接收且在函数执行完前进行返回这就是工厂函数。

然后可以创建对象传参进行即可进行复制。

var p1 = createPerson('心奈',11);
var p2 = createPerson('砂狼白子',17);

我们这时进行判断p1的原型是否是createPerson的原型链身上

console.log(p1 instanceof createPerson);

image-20230819144806122转存失败,建议直接上传图片文件

这时会发现我们使用这个方法在我们理解中是属于人这个方面的,但如果我们需要构造出其他方面的对象,需要我们再进行函数构建

 function createDog(name,age){
            var obj={
                name:name,
                age:age,
            }
            return obj;
        }

套路:通过工厂函数动态创建对象并返回;

使用场景:需要创建多个对象;

问题:对象没有一个具体的类型,都是object类型。

四、自定义构造函数模式

 function CreatePerson(name,age){
            this.name=name
            this.age=age
            this.setName = function(name){
                this.name=name
            }
        }

我们可以使用Array、Object等来构造函数来创建我们需要的对象,我们也可以自定义一构造函数来创建一个子定义类型的对象。构造函数并不是什么特殊的函数,任何函数使用new关键字调用都能作为构造函数,只是有一个惯例,构造函数的函数名始终以大写字母开头

var  p1 = new CreatePerson('心奈',12);
   console.log(p1.name,p1.age);
   console.log(p1 instanceof CreatePerson);

image-20230819145754288转存失败,建议直接上传图片文件

套路:自定义构造函数,通过new创建对象;

使用场景:需要创建多个类型确定的对象;

问题:每个对象都有相同的数据,浪费内存。

五、构造函数+原型的组合模式

  function CreatePerson(name, age) {
            this.name = name
            this.age = age
        }
CreatePerson.prototype.setName=function(name){
            this.name=name
        }

先创建一个构造函数,在构造函数中只初始化一般的属性,然后在通过原型添加需要的方法去调用。

 var p1 = new CreatePerson('黑见芹香',16)
 var p2 = new CreatePerson('小鸟游星野',17)
 p1.setName("心奈")
 console.log(p1,p2);

先new出两个对象他们身上都包含着我们前面添加进行的setName的方法可以直接进行调用。

image-20230819150352818转存失败,建议直接上传图片文件

套路:自定义构造函数,属性在函数中初始化,方法添加道原型上;

使用场景:需要创建多个类型确定的对象。 随着 ES6 的发布,类与工厂模式之间曾经存在的几点差异消失了。现在,工厂模式和类都能够强制实现真正的私有数据:

  • 工厂模式通过闭包实现
  • 类通过 weak map 实现

两者都能实现多重继承——工厂模式可以将其他属性混入自己的对象,类也可以将其他属性混入自己的原型,或者通过类工厂,通过代理也能实现。工厂函数和类也都可以在需要的时候返回任意对象,语法也都很简单。

考虑到所有事情,对 JavaScript 对象创建的偏好是使用类语法。它是标准的,它简单而干净,速度快,并且它提供了曾经只有工厂模式才能提供的所有功能 这里只是提供一些好用的模式,当然在合适的适合用合适的方法,方法是死的人是活的需要合理的运用才是最好的。