手机版

在js中创建对象的几种方法

时间:2021-09-06 来源:互联网 编辑:宝哥软件园 浏览:

无论哪一种语言,千变万化都离不开它的血统,只有深刻理解它的本质,才能自由应用。对应js、闭包、原型、函数、对象等。需要花很大的力气去思考和理解。本文穿插了js原型和函数的知识,讨论了几种批量创建对象的方法及其优缺点。

主体

说到创建对象,最容易想到的就是通过对象的字面方式直接定义一个对象,但这种方式只能创建少量独立不相关的对象。如果要批量创建对象,该怎么办?

工厂模式

工厂模式非常直观,将创建对象的过程抽象为一个函数,并将创建对象的细节与函数的特定接口封装在一起。如下图所示:

函数createStudent(姓名、性别、年级){ var o=new Object();o.name=nameo.sex=sexo.grade=gradeo . SayName=function(){ console . log(this . name);}返回o;}var s1=createStudent('Claiyre ',' famale ',1);一般来说,工厂模式是把创建对象的语句放在函数中,通过传入参数来创建特定的对象,最后返回创建的对象。

虽然工厂模式可以创建许多相似的对象,但它不能解决对象识别的问题,即如何知道对象的类型。构造函数模式应运而生。

构造函数模式

构造函数模式是用java语言创建对象的一种常见方式。这两种语言使用构造函数来创建对象的方式略有不同,所以要注意差异。

JavaScript中没有类的概念,所以一个函数就是一等公民。因此,不必显式声明类,只需创建一个构造函数,类的方法和属性在构造函数(或原型对象)中处理。构造函数模式的示例代码如下:

函数学生(姓名、性别、年级){ this.name=namethis.sex=sexthis.grade=等级;this . SayName=function(){ console . log(this . name);}}var s2=新生('孙悟空','男',2);细心的朋友一定发现了,构造函数的函数名首字母大写,而普通函数首字母小写,这是很多OO语言的习惯规则。虽然大部分情况下不会写,也不会报错,但为了代码标准化和可读性,构造函数的首字母要大写,以区别于普通函数。

与工厂模式相比,使用构造模式创建对象有以下区别:

创建一个没有显示的对象,直接给这个对象分配属性和方法,没有return语句。此外,应该注意的是,要创建Student的实例,必须使用新的运算符,并且创建的实例对象将具有指向Person构造函数的构造函数属性。调用构造函数来创建对象经历了以下过程:

创建一个新对象,将构造函数的范围分配给新对象(因此这指向这个新对象),并执行构造函数中的代码来返回新对象(不需要显式返回)。虽然构造函数很容易使用,但也不是没有缺点。使用构造函数的主要问题是每个方法必须在每个实例上创建一次。在ECMAScript中,函数是一个对象,所以每次定义函数时,都会实例化一个对象。下面的例子证明了这个缺点。

Var s3=新生('唐僧','男',3);Var s4=新生('白','女',4);S3 . SayName();S4 . SayName();console . log(S3 . SayNAmE==S4 . SayNAmE);运行结果:

也就是说,通过构造函数实例化多个对象的方法是不同的方法,但是它们的内部代码和实现的函数是一样的,造成了一定的资源浪费。

幸运的是,这个问题可以通过原型模式来解决。

原型模式

在js中,每个函数都有一个prototype属性,它是一个指向名为prototype object的对象的指针。原型对象包含可由特定类型的所有实例对象共享的属性和方法。此外,这个对象有一个固有的属性构造函数,它指向创建对象的构造方法。

使用原型模式可以使所有实例共享原型对象中的属性和方法,即不再需要在构造函数中定义对象实例的信息。它用代码表示如下:

函数Student _ 1(){ } Student _ 1 . prototype . name=' Claiyre ';Student_1.prototype.sex='女';学生_ 1 . prototype . class=5;student _ 1 . prototype . SayName=function(){ console . log(this . name);} var S5=new Student _ 1();S5 . SayName();//claiyevar S6=new Student _ 1();s 6 . SayName();//Claiyre一张图片胜过千言万语。下图清楚地说明了每个对象和原型对象之间的关系:

理解原型之后,您可以继续向实例对象添加属性或方法:

名字=约翰;s 6 . SayName();//John,当您想要读取对象的属性时,您将执行搜索。搜索从对象实例本身开始。如果在实例中找到此属性,则搜索结束,并返回实例属性值。如果在实例上找不到,请继续扩展到对象的原型对象,并搜索对象的原型对象。如果在原型对象上找到,则返回原型上相应属性的值;如果没有找到,返回undefined。因此,实例对象属性覆盖了原型对象上同名的属性,因此上面的第二行代码输出了John。

方法Object.getPrototypeOf(对象)返回参数对象的原型对象。方法返回对象的类枚举的实例属性。原型中的所有属性都由所有实例共享。这种共享非常适合函数,对于包含基本值的属性来说是合理的(实例属性会覆盖与原型同名的属性),但是对于那些包含引用类型的属性来说就麻烦大了

student _ 1 . prototype . friends=[' aa ',' bb '];Console.log('s6的朋友的S6 . friends);S5 . friends . push(' cc ');console . log(' S5 ' S5 . friends);Console.log('s6的朋友的S6 . friends);运行结果:

问题是我们只想要改变s5的好友列表,但是由于原型模式的共享性质,s6的好友列表也随之改变。

因此,原型模式很少单独使用。

将构造函数与原型模式结合起来

构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性。这种混合模式不仅支持将参数传递给构造函数,而且最大限度地节省了内存,可以说是两种模式的结合。示例代码如下:

函数学生(姓名、性别、年级){ this.name=namethis.sex=sexthis.grade=等级;} student . prototype . say name=function(){ console . log(this . name);} student . prototype . school=' Joooh school ';其他模式

除了上述常见模式之外,还有几种批量创建对象的方法

动态原型模式:只有在第一次调用构造函数时,方法才被分配给原型对象的相应属性。其他示例的处理方式与构造函数模式相同,后者寄生于构造函数模式:仅封装用于创建对象的代码,然后返回新创建的对象。新的运算符仍然用于调用安全构造函数模式:没有公共属性,只有私有变量和方法,还有一些get/set方法来处理私有变量。标签

每种模式各有利弊,需要结合实际场景深入理解,灵活应用。

以上就是本文的全部内容。希望本文的内容能给大家的学习或工作带来一些帮助,也希望多多支持我们!

版权声明:在js中创建对象的几种方法是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。