js创建数组对象的过程有几种特点是什么
发布时间:2025-05-25 04:21:26 发布人:远客网络
一、js创建数组对象的过程有几种特点是什么
js编程中创建对象的几种方式,如原始方法、工厂方法等创建对象。
<script type="text/javascript">
obj.name="Koji";//为对象添加属性
obj.showName= function(){//为对象添加方法
上面的方式通过new关键字生成一个对象,然后根据JS是动态语言的特性添加属性和方法,构造一个对象。其中的this是表示调用该方法的对象。
这种方式的问题是如果需要多次创建对象,则需要重复代码多次,不利于代码的复用。
<script type="text/javascript">
var obj= new Object();//创建对象
这种方式提高了代码重用率,还可以改变工厂方法,传入参数赋值。
<script type="text/javascript">
function createObj(name, age){//构造对象时可以传入初始化参数
var obj= new Object();//创建对象
var obj1= createObj("Koji", 22);
var obj2= createObj("Luo", 21);
上面的方式虽然可以提高代码的复用率,但和面向对象中类的概念相比有一个很大的缺陷。面向对象强调对象的属性私有,而对象的方法是共享的。而上面的工厂方法创建对象的时候要为每个对象创建各自私有的方法。同时由于为每个对象都创建逻辑相同的方法,浪费内存。
<script type="text/javascript">
function createObj(name, age){
var obj= new Object();//创建对象
function showName(){//函数也是一个对象
var obj1= createObj("Koji", 22);
var obj2= createObj("Luo", 21);
上面通过定义连个函数对象,解决了不同对象持有函数对象的私有问题。现在所有对象的方法都持有上面两个函数的引用。但这么一来的话,对象的函数又和对象成了相互独立,不相干的了。这和面向对象中特定方法属于特定类的思想不符合。
<script type="text/javascript">
//定义一个构造函数,用来生成对应的对象,可以类比Java中的构造函数
//当调用new Person的时候,在执行第一行代码前,先生成一个Person对象,并将对象在内存中的
//索引赋值给this关键字,此时可以通过this关键字操作新生成的对象,如下面的添加属性或方法
this.name= name;//this关键字不能少。为当前对象,即this关键字引用的对象的name属性赋值
//,实际相当于为当前对象添加name属性后,再为其name属性赋值。
this.showName= function(){//为当前对象添加方法
//将当前对象返回给赋值符号左边的变量(不必明确使用return)
var obj1= new Person("Koji", 22);//生成一个Person对象
var obj2= new Person("Luo", 21);
构造函数的方式和工厂方式一样,会为每个对象创建独享的函数对象。当然也可以将这些函数
对象定义在构造函数外面,这样又有了对象和方法相互独立的问题。
该方法利用的对象的prototype属性
<script type="text/javascript">
function Person(){}//定义一个空构造函数,且不能传递参数
//将所有的属性的方法都赋予prototype属性
Person.prototype.name="Koji";//添加属性
Person.prototype.showName= function(){//添加方法
Person.prototype.showAge= function(){
var obj1= new Person();//生成一个Person对象
当生成Person对象的时候prototype的属性都赋值给了新的对象。那么属性和方法是共享的。
该方法的问题首先是构造函数不能传参,每个新生成的对象都有默认值。其次,方法共享没有任何问题,但是属性共享就有问题,当属性是可改变状态的对象的时候。
<script type="text/javascript">
function Person(){}//定义一个空构造函数,且不能传递参数
Person.prototype.array= new Array("Koji","Luo");
Person.prototype.showAge= function(){
Person.prototype.showArray= function(){
var obj1= new Person();//生成一个Person对象
obj1.array.push("Kyo");//向obj1的array属性添加一个元素
obj1.showArray();//Koji,Luo,Kyo
obj2.showArray();//Koji,Luo,Kyo
以上代码通过obj1向obj1的属性array添加元素的时候,obj2的arra属性的元素也跟着受到影响,原因就在于obj1和obj2对象的array属性引用的是同一个Array对象,那么改变这个Array对象,另一引用该Array对象的属性自然也会受到影响混合的构造函数/原型方式。
使用构造函数定义对象的属性,使用原型(prototype)定义对象的方法,这样就可以做到属性私有,而方法共享。
<script type="text/javascript">
this.array= new Array("Koji","Luo");
Person.prototype.showName= function(){
Person.prototype.showArray= function(){
var obj1= new Person("Koji", 22);//生成一个Person对象
var obj2= new Person("Luo", 21);
obj1.array.push("Kyo");//向obj1的array属性添加一个元素
obj1.showArray();//Koji,Luo,Kyo
属性私有后,改变各自的属性不会影响别的对象。同时,方法也是由各个对象共享。在语义上,
<script type="text/javascript">
this.array= new Array("Koji","Luo");
//如果Person对象中的_initialized为undefined,表明还没有为Person的原型添加方法
if(typeof Person._initialized=="undefined")
Person.prototype.showName= function(){
Person.prototype.showArray= function(){
Person._initialized= true;//设置为true,不必再为prototype添加方法
var obj1= new Person("Koji", 22);//生成一个Person对象
var obj2= new Person("Luo", 21);
obj1.array.push("Kyo");//向obj1的array属性添加一个元素
obj1.showArray();//Koji,Luo,Kyo
这种方法和构造函数/原型方式大同小异。只是将方法的添加放到了构造函数之中,同时在构造函数Person上添加了一个属性用来保证if语句只能成功执行一次。
在实际应用中采用最广泛的是构造函数/原型方法。动态原型方法也很流行,它在功能上和构造函数/原型方法是等价的,不要单独使用构造函数或原型方法。
二、JS const 数组类对象赋值注意点
1、对于const数组对象a进行赋值给b后,若对b进行修改,则同样会影响a。原因在于数组类型赋值时执行浅拷贝,仅仅将a的栈内存地址复制到b,而非堆上的数据。此时b依然指向堆上的数据,所以b的修改实质上就是对a的修改。为了实现深拷贝,即复制数组的每个元素,需采取特定方法。
2、实现深拷贝的一种常见方法是使用数组的map函数,如下所示:
3、通过map函数,数组a中的每一个元素被独立地复制到新数组b中。这样,b就成为了a的一个独立拷贝,对b的任何修改都不会影响到a。使用这种方法可以确保数组作为对象赋值时执行深拷贝,避免在修改一个对象时影响到另一个。
4、此外,还有一种使用JSON.parse和JSON.stringify进行深拷贝的方法,适用于数组中元素为基本数据类型或者具有可序列化属性的对象。以下是示例代码:
5、let b= JSON.parse(JSON.stringify(a));
6、通过JSON.stringify将数组序列化为JSON字符串,再通过JSON.parse将字符串转换回数组。此方法确保了数组中的每个元素都进行了深拷贝。需要注意的是,这种方法不适用于数组中包含不可序列化对象的情况。
7、总结而言,为了在对const数组对象赋值后实现深拷贝,避免修改一个对象影响到另一个,可以使用数组的map函数或JSON.stringify与JSON.parse相结合的方法。这为在JavaScript中处理数组赋值和深拷贝提供了有效解决方案,确保了数据的独立性和一致性。
三、js 如何动态添加数组
1、在JavaScript中,数组的创建可以通过多种方式实现。使用new Array()可以创建一个数组,如果不传入参数,则数组为空。如果传入一个参数,则该参数表示数组的长度。值得注意的是,尽管可以指定长度,但这只是一个初始长度,数组的长度可以动态调整。例如:
2、var arrayObj= new Array();//创建一个空数组
3、var arrayObj= new Array(5);//创建一个长度为5的数组,但实际存储元素不受长度限制
4、var arrayObj= new Array("元素0","元素1","元素2");//创建并赋值数组
5、数组元素可以通过下标访问,例如:
6、var testGetArrValue= arrayObj[1];//获取数组第二个元素
7、arrayObj[1]="这是新值";//修改数组第二个元素
8、添加元素是通过push()、unshift()和splice()方法实现。push()用于在数组尾部添加一个或多个元素,返回数组的新长度:
9、arrayObj.push("新元素1","新元素2");//在数组尾部添加元素
10、unshift()则是在数组头部添加一个或多个元素,同样返回数组的新长度:
11、arrayObj.unshift("新元素1","新元素2");//在数组头部添加元素
12、splice()方法则更灵活,可以插入或删除数组中的元素:
13、arrayObj.splice(insertPos, 0,"新元素1","新元素2");//在指定位置插入元素
14、删除元素也有多种方式,如pop()、shift()和splice()。pop()和shift()分别移除数组尾部和头部元素,并返回被移除的元素:
15、arrayObj.pop();//移除并返回数组尾部元素
16、arrayObj.shift();//移除并返回数组头部元素
17、splice()方法可以同时移除和插入元素,返回被移除的元素:
18、arrayObj.splice(deletePos, deleteCount);//移除指定位置及其后的元素
19、数组截取和合并功能通过slice()和concat()实现。slice()方法可以获取数组的一部分,返回一个新的数组:
20、arrayObj.slice(start, end);//从start到end-1的数组部分
21、concat()方法可以合并多个数组或字符串,返回一个新的数组:
22、arrayObj.concat("字符串", ["数组元素1","数组元素2"]);//合并数组和字符串
23、数组的拷贝通常使用slice()或concat()方法:
24、arrayObj.slice(0);//返回一个新数组
25、arrayObj.concat();//返回一个新数组
26、数组排序使用reverse()和sort()方法,reverse()反转数组,sort()则对数组进行排序:
27、arrayObj.sort();//对数组进行排序
28、最后,数组元素可以通过join()方法转换为字符串,separator为分隔符:
29、arrayObj.join(separator);//使用separator连接数组元素
30、toString()、toLocaleString()和valueOf()方法可以看作是join()的变体,主要用于特定场景。