javascript中创建对象的几种方式

it2023-05-24  65

javascript中对象的创建方式(优缺点分析)

1.工厂模式

定义:

这种模式抽象了创建具体对象的过程,由于ES6之前无法创建类,我们以函数封装的形式进行实现。 代码如下:每次调用dog_2这个函数,都直接新建一个对象,然后为该对象添加属性和方法。

function dog_2(name,weight){ let o=new Object(); o.name=name; o.weight=weight; o.bark=function(){ console.log(this.name+"体重为"+this.weight+"kg"); console.log("汪汪汪"); } return o; } dog2=dog_2("yangxuan",10); dog2.bark(); console.log(dog1 instanceof dog_2); //false console.log(dog1.constructor==dog_2); //false
缺点:从上面最后两行代码可以看出,通过这种方式创建的对象无法识别。
优点:代码复用,相比于每创建一个对象就以对象字面量的方式进行创建实现了代码的复用。

2.构造函数模式

定义:

这种模式对于学过cpp、java的同学来说应该很好理解。js中也可以通过创建特定的构造函数来创建对象,类似于Array等的原生构造函数,我们可以自定义一个构造函数,在其中定义对象的属性和方法。 代码如下:

function Dog(name,weight){ this.name=name; this.weight=weight; this.bark=function(){ console.log(this.name+"体重为"+this.weight+"kg"); console.log("汪汪汪"); } } dog1=new Dog("yangxuan",10); dog1.bark(); console.log(dog1 instanceDof dog); //true console.log(dog1.constructor==dog); //true
注意:一般构造函数函数名首字母大写,无return语句,需要通过new进行调用。(建议查看一下new的执行过程)
缺点:通过上面的代码可以发现,所有对象公有方法的bark()在每次实例化的时候都创建了一遍。在js中,函数也是一个对象,就相当于你每次创建一个dog对象就附带着创建了另外一个对象。这个问题的解决方法就是对于公有的方法,仅仅实现一份,然后大家伙一起使用这个方法。(类似于cpp中的static 修饰的属性)
优点:可以进行对象识别,这是它比工厂模式强的地方。

3.原型模式

定义:

我们创建的每个函数都有一个prototype属性----原型。它本身是一个指针,指向某一个对象。这个对象的作用就是可以包含所有实例共享的属性和方法。可以理解为,这个对象(原型对象)的属性和方法可以被通过这个构造函数实例化出来的其他对象共享。通过这种方式,可以解决方法2中所说的问题。 代码如下:每次调用pig这个函数,都直接新建一个对象,然后为该对象添加属性和方法。

function pig(){ } pig.prototype={ constructor:pig, this.name='佩奇'; this.age=10; this.weight=110; sayname:function(){ console.log(this.name); //如果使用箭头函数的this指向会出现问题(?) } } let peiqi=new pig(); peiqi.sayname();
缺点:又不是所有的属性都会共享,一旦一个实例修改了数据其他实例的访问也会受到影响,所以单纯的这个模式意义不大,应该结合方法2使用。
优点:主要是共享。

4.原型模式和构造函数模式的组合使用

看过上面方法二与方法三之后,理解了他们各自的优缺点,话不多说,我们直接看代码 代码如下:

function pig(name,age,weight){ this.name=name; this.age=age; this.weight=weight; } pig.prototype={ constructor:pig, sayname:function(){ console.log(this.name); //如果使用箭头函数的this指向会出现问题(?) } } let peiqi=new pig("peiqi",10,100); peiqi.sayname();
缺点:待更新。
优点:每个实例都有自己的一份实例属性的副本,然后又共享着公有方法的引用,节约了内存,同时还支持向构造函数传参,就很牛。

5.动态原型模式

定义:方法四的基础上加以修改

将上述方法的原型模式封装在构造函数之中,通过判断某个方法是否存在来决定要不要需要初始化原型对象。 代码如下:

function pig(name,age,weight){ this.name=name; this.age=age; this.weight=weight; if (typeof this.sayname!="function"){ console.log(this.name); //如果使用箭头函数的this指向会出现问题(?) } } let peiqi=new pig("peiqi",10,100); peiqi.sayname();

6.寄生构造函数模式

定义:

在上述方法不使用的情况下使用寄生构造函数的形式。 这种模式的基本思想就是创建一个构造函数,该函数的作用仅仅是封装创建对象的代码,然后返回新创建的对象,但是表面上看这个函数又像是一个典型的构造函数。 代码如下:

function pig(name,age,weight){ let o=new object(); o.name=name; o.age=age; o.weight=weight; o.sayname=function{ console.log(this.name); //如果使用箭头函数的this指向会出现问题(?) }; return o; } let peiqi=new pig("peiqi",10,100); peiqi.sayname();
注意:构造函数在不返回值的情况下,默认返回新对象的实例,在末尾有return语句的情况下,可以重写调用构造函数时返回的值。
最新回复(0)