JavaScript学习——进阶(续3:数组)

混江龙づ霸主 提交于 2019-11-29 16:31:10

数组

  • 对象的几种创建方式:
    字面量
    系统自带的构造函数
    自定义构造函数
    Object.create()
  • 数组的创建方式:
    数组字面量 var arr = [];
    系统提供的数组的构造函数 var arr = new Array();

基本介绍

<script type = "text/javascript">
	//下面两语句等价:
	var arr = [1, 2, 3];
	var arr = new Array(1, 2, 3);
	
	//两种构造方式的仅有唯一区别:
	var arr = [10];//表示arr仅有一个元素
	var arr = new Array(10);//表示arr有10个元素(目前都为undefined)		
</script>

需要注意:在JS中,数组没有越界这一说,如果“越界”的引用了某一元素,则会显示undefined,而不是报错。“可以溢出读,也可以溢出写”:

<script type = "text/javascript">
	var arr = [1, 2, 3];
</script>

在这里插入图片描述
在这里插入图片描述

数组操作

数组是引用值,能够调用方法。对数组的操作的常用方法可以简单地分为以下两类:

  1. 操作后使原数组改变:
  • push:在数组最后添加若干指定元素,返回添加后数组长度
    在这里插入图片描述

push()方法的实现:

 Array.prototype.push = function() {
	for(var i = 0; i < arguments.length; i++) {
		this[this.length] = arguments[i];
	}
	return this.length;
}
  • pop:删除数组里最后一个元素,返回这一被删除的元素
  • shift:删除数组里最前面一个元素,返回这一被删除的元素
  • unshift:在数组最前面添加若干指定元素,返回添加后数组长度
    在这里插入图片描述
  • reverse:数组元素的顺序逆转了
  • sort:按ASCII码升序排序
    在这里插入图片描述

如果希望按照数字大小进行排序:sort()函数提供了编程接口,使得我们可以按照希望的形式进行排序。该编程接口具有两个规则,具体如下:

<script type = "text/javascript">
	var arr = [1, 2, 0, 9, 11, 22];
	arr.sort(function(a, b) { 
	//规则1:必须有两个形参,表示将要进行比较的数组中的两元素.
	//如第一轮a=1,b=2;第二轮a=1,b=0;第三轮a=0,b=9......
		if(a > b) {
			return 1;
		} else if(a < b) {
			return -1;
		} else {
			return 0;
		}	//规则2:返回值——
	}); 	//	返回值为正数时,表示a>b,a将置于b前
			//	返回值为负数时,表示a<b,b将置于a前
			//	返回值为0时,表示a=b,a、b位置不变

	//上面的一组代码等价于下面的形式:
	//arr.sort(test(a, b));
	//function test(a, b) {};
</script>

说明:上面程序sort()的编程接口类似于“冒泡排序法”。

  • 上面的升序接口可以进行如下的改进:
	arr.sort(function(a, b) { 
			return a - b;
	}); 
  • 若降序排列,则:
	arr.sort(function(a, b) { 
			return b - a;
	}); 
  • 给一个有序的数组,使其乱序:
	arr.sort(function(a, b) { 
			return Math.random() - 0.5;
	}); 

【说明:Math.random()函数返回(0, 1)之间的小数。Math.random() - 0.5则时正时负,不由两比较的元素决定,所以每两个数进行比较时,是否交换位置以及如何交换位置都是随机的,所以最终结果是乱序。注意,该函数被调用了很多次的!并不是一次就全部排好的。】

练习:按照字符串的字节长度将数组中的元素重新排列位置。

<script type = "text/javascript">
	var arr = ['es你','tggh','aryhobkv','a你','bb'];

	function retBytes(str) {
		var num = str.length;
		for(var i = 0; i < str.length; i++) {
			if (str.charCodeAt(i) > 255) {//汉字占两个字节,所以num在str.length的基础上加1操作
				num++;
			}
		}
		return num;
	}
	arr.sort(function(a, b) { // 始终要注意:a,b量参数表示数组中的元素
		return retBytes(a) - retBytes(b);	
	}); 		
</script>
  • splice:截除数组中的某段数据,返回被截除掉的元素(下面第一张图);该函数还可以在截除的同时,在截除的位置上添加若干元素(“若干”指:除了前两个参数,后面的参数都代表将要添加的元素)(下面第二张图)。利用该函数可以在指定位置添加元素(下面第三张图)。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  1. 操作后原数组不变:
  • concat:
    arr.concat(arr1):返回一个前半部分是arr,后半部分是arr1的新数组(arr、arr1都未改变)。
    在这里插入图片描述
  • join:join()函数的参数必须为字符串形式,表示按照指定字符将数组中的各元素连接起来。返回值为字符串类型。如果省略参数,则默认以“,”进行连接。
    在这里插入图片描述
    在这里插入图片描述
  • split:split()函数的参数必须为字符串形式,表示按照指定字符将字符串进行拆分。返回值为数组
    在这里插入图片描述
    在这里插入图片描述
  • toString:将数组变成字符串输出
    在这里插入图片描述
  • slice:
    • slice(a, b)表示从索引a处开始,截取到索引b处。
    • slice(a)表示从a处截取到最后。
    • slice()表示全部截取。
    • 返回截取到的部分,原数组不变。

类数组

类数组是一种特殊的对象,它具有以下特征属性名应该为数字(可以直接写成数字,也可以写成字符串类型的数字),用来表示相应的索引;必须有length属性;最好加上push属性,这样才能使用真正数组的push()方法,否则就不能对该类数组使用push()方法。【arguments就是一个类数组。】

通过一道题更好的认识其内部原理:

<script type = "text/javascript">
	var obj = {
		2 : 'b',//或者写成'2' : 'b',
		3 : 'c',
		length : 2,
		push : Array.prototype.push,
		splice : Array.prototype.splice
	}

	obj.push('d');
	obj.push('e');
</script>

问:程序执行完后,obj的内容是什么样的?


要想知道此问题,首先要知道push()函数的内部执行情况:

 Array.prototype.push() = function(target) {
  	obj[obj.length] = target;
  	obj.length ++;
 }

因此,对于obj.push('d');,将放在obj[2]处,即obj[2]处原来的b将变成d!然后length变成3,故对于obj.push('e');,将使obj[3]处原来的c将变成e


此外,可以看看如下输出:
在这里插入图片描述

类数组有很多应用,它本身是个对象,且同时具有了数组的一些特性,所以存储的内容更加强大,后面将经常使用到。

实例:数组去重

利用对象的特性:同一个属性名,不可能存在多次。下面unique()函数的原理就是:把要去重的数组的元素试图作为temp对象里的属性名放入temp里,然后随便对其赋上一个值(这里是“abc”);判断下一元素是否与前面某一元素重复时,只需判断是否存在以该元素为名称的属性?如何判断呢?那么我们就看其对应的值是undefined还是我们指定的那个值。如果是undefined,说明没有这样的属性名,也就没有对应的值,即undefined。代码如下(注意if语句):

<script type = "text/javascript">
	Array.prototype.unique = function() {
		var temp = {},
			arr = [],
			len = this.length;//将这种东西用变量保存下来,以免每次都要计算一下this.length!

		for(var j = 0; j < len; j++) {
			if(!temp[this[j]]) { //temp[this[j]]为undefined时
				temp[this[j]] = 'abc';
				arr.push(this[j]);
			}
		}
		return arr;
	}

	var target = [1,1,0,0,0,'a','a'];
	var arr = target.unique();
</script>

temp对象最终的样子:

	temp = {
		"1" : "abc",
		"0" : "abc",
		"a" : "abc"
	}

测试结果:
在这里插入图片描述

我的做法是(没用用到对象的特性…):

Array.prototype.unique = function() {
	var arr = [],
		len = this.length;//将this.length用变量保存下来,以免每次都要计算一下!
		
	for(var j = 0; j < len; j++) {
		if(arr.length == 0) {
			arr.push(this[j]);
		} else {
			for(var i = 0; i < arr.length; i++) {
				if (this[j] != arr[i] && i == arr.length - 1) {
					arr.push(this[j]);
				}
			}				
		}
	}
	return arr;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!