从题目提及,之因此是不彻底,是由于有些东西好比数组的方法怎么用这个我都不打算讲,由于那个看一下都会,下面讲的都是我以为重要的,只关于数组对象自己。另外,因为个人Javascript实战经验很少,因此可能有些东西没涉及到,有些内容说的有误,请发现问题的同窗不吝指教。java
首先,Javascript(下称js)的数组定义,这不是重点,简单说下,下面两句都是建立一个空的数组:python
var arr = []; var arr2 = new Array(); // 不写new也能够。
在建立以后,你就能够随时往数组里添加元素。数组的大小是不固定的,能够像a[0] = 1
这样随意添加。c#
而后到重点了,关于往数组里添加元素这件事。首先,你要知道数组是一个对象,而对象是一个键值对的集合(相似于java里面的map,python里面的dict,c#里面的Dictionary),对象能够有属性,对象的函数叫方法,对象的属性或方法可使用方括号或点号的方式访问,其中使用方括号引用要加引号,点号的使用只有在属性名称是一个合法的变量名称的时候才可使用,也就是属性不包含任何空格连字符而且不以数字开头时才能够,看个例子:数组
var person = {}; person.age = 22; person.sayhi = function(){console.log('hi');}; person.age; // 22 person['age']; // 22 person.sayhi(); // hi person['sayhi'](); // hi
嗯,这就是对象,好像也没什么特别的(除了用方括号取值外),不过对象说些就够了,后面开始说数组。浏览器
对于上面的这些,数组全能够作到,也就是说,下面这段代码也能够正常运行(只有第一行跟上面的不同):函数
var person = []; person.age = 22; person.sayhi = function(){console.log('hi');}; person.age; // 22 person['age']; // 22 person.sayhi(); // hi person['sayhi'](); // hi
由于数组就是对象,这里不要把方括号的字符串索引和一般讲的数字索引弄混了,还没开始说(立刻说)数字索引呢。spa
和普通的对象不一样,数组对象的元素有数字索引,或者说特殊的键(前面说了对象是键值对),这和咱们在其余语言好比java、c#等语言中的见到的数组是同样的。在js中,这个键有一些特殊的要求,它能够是数字,也能够是能转换成数字的字符串,而合理的数字,须要是范围在0到4294967295(2^32-1)的整数(事实上,这个索引在词法分析的时候都是当作字符串的,js把这个字符串转换成32位的整数,而后再把32位的整数转换成字符串跟原字符串比较,若是相同的话,则说明这个索引值是合法的数字,不然就是一个普通的字符串键)。简单举个例子:firefox
a = [1, 3, 5, 7]; console.log(a[0]); // 1 console.log(a['0']); // 1 a['2'] = 12; console.log(a[2]); // 12
上面的代码都是能够在浏览器里运行的,注释是输出值。这和咱们在其余语言中见到的数组好像没啥区别。这个a['2'] = 12;
由于'2'
被转换成整数再转换成字符串仍是'2'
,因此跟a[2]
同样。不过其余语言里,咱们使用数组都是定义一个固定大小数组的对不对?这里好像不是哈,并且这里还说了数组的索引范围。因此,为何?简单点回答就是这里的数组是对象,是js中的对象。这一点和其余语言(python等函数式的除外)不一样,具体哪里不一样,我没深刻研究,也说不太清楚,我理解的是,c/java等语言定义数组的时候,是在内存中划分了一块固定大小的区域,有一个指针存储着这块区域的首地址。而js中好像不是这样的,就像前面说的同样,数组是对象,键值对结构,因此我以为js中的数组都是用hash的方式存储元素的,元素之间的内存不必定是连续的。不过我如今没找到查看js变量内存地址的方法,因此无法肯定这件事。不过这不是本文要讲的重点。指针
咱们把重点放到索引上,前面说了索引的范围,不过有同窗可能试了,就是a[-1] = 2;
或是a[4294967296] = 10;
这种语句也没有问题。对的,这并非错误,这是正常的语句,固然不会有问题。可是问题是前面不是说了索引必须是0到4294967295的整数么?对,是的,这也没错。那疑问出在哪里呢?code
先贴两张firefox控制台的截图:
你有没有发现什么问题呢?当咱们使用正常的索引添加元素,在打印数组的时候,添加的元素会被打印出来,而使用非正常的“索引”添加元素时,打印的数组里面却没有添加的元素,可是你看右侧的Array对象,全部添加的元素却一个很多。再看一张图,此次多添加几个元素,再给数组添加一个属性(注意看右侧Array对象的元素索引):
不知道你有没有发现。在右侧,上面几个是数字索引,打印数组的时候能被打印的,而下面几个是属性,打印数组不会打印属性!也就是说,a[-2] = 2;
这种语句,这个-2是属性的键,而不是特殊的数字索引的键,-2在被强制转换成正整数的时候,被认为是一个字符串,因此这个-2和4294967296和'name'同样,都是数组的一个属性的键!因此前面说的负索引或是超出范围的索引(应该说是属性的键)都是合法的,它们都是普通的字符串键。
这里一个问题,就是既然说-2这种键是普通的属性键,那有人可能会说为何使用a.-2
或是a.'-2'
访问-2这个键的值会报错,而a[-2]就不会报错?对呀,为何?前面在讲对象的时候,有一句加粗的话:对象的属性或方法可使用方括号或点号的方式访问,其中使用方括号引用要加引号,点号的使用只有在属性名称是一个合法的变量名称的时候才可使用,也就是属性不包含任何空格连字符而且不以数字开头时才能够。因此,-2这种键的属性,是不能用点号的方式访问的!
另外还有一个小问题,就是方括号,当咱们想访问数组的name属性的时候,须要这样:a['name']
,也就是name被引号包起来了,而-2是和name同样的属性的键,为什么-2能够不用(也能够用)引号包起来?其实,方括号内的全部字符会被当成一个表达式,单纯的一个数字-2,是个合法的表达式,但name若是没有被定义成变量名,name就不是合法的表达式,一样x^b&c这种也不是合法的,由于它会被当成变量x、b、c组成的某种表达式,可是x、b、c是否是变量还不肯定,并且里面的符号不必定是被js所支持的,因此a[name]
的问题出在name上,而不是[]上。若是还很差理解,你能够把name想象成x+y,在x、y没有被定义成变量的时候,x+y
这个表达式确定有问题对不对?那a[x+y]
也会有问题对不对?而a['x+y']
就没有问题,由于'x+y'
是个字符串。
后面补充一点,js中,变量名字是能够由数字、字母、下划线任意组合的,其中数字不能放在开始位置。而对象的属性键的命名要宽松一些,合法的能够不用引号,不合法的用引号包起来就能够。
好了,说的差很少了,总结一下:文章首先简单介绍了下对象,而后说了数组也是对象,最后解释了下一些疑问,而后总结。
写这篇文章的缘由是我昨天在微博里看了一条js的教程,对数组的讲解产生了一个疑问,而后评论的字数超出了140,因此我就查资料单独写出来了。目的是让本身弄明白,也愿能帮助到学js的同窗。数组范围和索引转换那里是参考的《Speaking Javascript》,其余地方都是本身的理解和见解。
最后,感谢观看,由于是分两次写的,可能语句有些乱,有的地方不乱可是上下文也完整,有的上下文完整可是废话太多,总之,就这样吧。下篇见。