浅谈Javascript数组的使用_javascript技巧

上一篇说了数组的索引,这一篇说下数组的使用。

数组的大小

js的数组可以动态调整大小,更确切点说,它没有数组越界的概念,a[a.length]没什么问题。比如声明一个数组a = [1, 3, 5],现在的数组大小是3,最后一个元素的索引是2,但是你依然可以使用a[3],访问a[3]返回的是undefined,给a[3]赋值:a[3] = 7,是给数组a添加了一个元素,现在数组a的长度是4了。你可以试试把下面这段代码放到浏览器里运行下:

  var a = [];
  for(int i = 0; i <= a.length; i++)
  {
    a[a.length] = i;
  }

在我的电脑上,火狐会立马崩掉,chrome这一个标签cpu占用99%(使用chrome的任务管理器查看的)。

js的length的值会随着数组元素的改变而改变,当然你也可以手动设置数组的 length 属性,设置更大的length不会给数组分配更多的空间,但是设置更小的length则会导致所有下标大于等于新length的属性被删除。

另外有一点就是,数组的length值是怎么来的,有的资料说是最大一个数字索引值加一,应该是对的,不过如果把空槽也算数的话,length值就是数组的元素数。上张图解释下:

从图里可以看到,有个数组a,a[0]和a[10]都已赋值,这时候a的length是11,中间有9个empty slot(姑且就翻译为空槽好了)。那这九个空槽算不算数呢,我觉得应该算,这样就能合理的解释length值了。那这些空槽的值是什么呢?undefined!所以呢,如果在chrome里,使用foreach遍历(forin),那么这些空槽正好都能跳过,而使用for遍历,则会打印出undefined。至于在firefox里,表现不太一样,自己试吧。

数组的遍历

昨天在看微博上转的js教程的时候,里面说在遍历数组的时候,判断语句i<a.length会造成每循环一次都要计算一次长度,从而对性能有一点点影响。这一点我表示疑问,我不确定到底是不是这样,而且不同的浏览器对这种情况可能还有不同的优化,我在网上搜了下,找到了几个网页说了要缓存数组大小,但是都是抄的,没主见,也没说明原理,所以我表示很怀疑,而且我在chrome测试了下,性能上没什么明显差异。关键是我觉得,length是个数组的属性,每次调用a.length的时候,只是访问这个属性而已,属性都是用hash的方式存储的,所以访问的时间复杂度是O(1)。这是我的看法,如果不对,请告诉我。

关于数组的foreach遍历,js的方式相对于java/c#等语言是很奇怪的:

    for(var name in ['huey', 'dewey', 'louie']) {
      console.log(name);
    }
    /*
      打印结果:
      0
      1
      2
    */

可以看到,打印的结果不是数组的元素,而是数字索引值(感觉这好像也可以说明,js的数组也是用hash的方式存储的),不管怎样,这一点要注意。(至于为什么这样,我觉得数组元素都是数组的属性,这个遍历是遍历的length值,从0到length。而不是逐个输出数组的元素,因为元素是属性,数组又不只数字索引这一种属性,那么为什么这样遍历的时候只输出它们呢,而不是length,push,join等方法?公平起见,只好输出数组的数字索引了。当然,这只是我自己的看法,具体怎么样我没研究。)

数组的一些方法

数组有push和pop方法,这样数组就像堆栈一样了。对数组使用delete,可以将数组中某个元素移除,但是那样会在数组中留下一个空洞(也就是说delete也可以删除数组中的元素,但是只是删除该位置的值,不改变数组大小,原位置类型是undefined),这是因为排在被删除元素之后的元素保留着它们最初的属性,所以应该使用splice对进行过delete操作的数组进行瘦身,它会将被删除的属性移除,但这样效率并不是很高。数组中还有map、reduce、filter等方法,这里就不多说了(跟python中的list挺像的)。

补充

最后补充一点,我前面说过,js中的数组就是对象(废话,本来就是对象),那么是不是说,数组和对象可以互相互替换着用呢?答案是可以的。不过为了明确,还是分开用比较好,下面说下什么时候该用数组,什么时候该用对象(参考《javascript语言精粹》):

当属性名是小而连续的整数时,应该使用数组,否则,使用对象。
另外由于js中对数组和对象使用 typeof 的结果都是 Object,因此判断一个对象是否为数组的方法:

  var is_array = function(value) {
  return Object.prototype.toString.apply(value) === '[object Array]';
  };

番外

觉得闭包被神化了,可能语言层面上的实现有技术,但是在应用层面我觉得就应该那样啊,使用的时候都感觉不到那是在用闭包。但是这个闭包却几乎成了面试前端必问的概念了。

以上所述就是本文的全部内容了,希望大家能够喜欢。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索javascript
数组的使用
浅谈英语课堂导入技巧、浅谈散文写作技巧、浅谈数学中的变形技巧、浅谈纹绣飘眉经营技巧、浅谈工程施工投标技巧,以便于您获取更多的相关知识。

时间: 2024-10-31 01:28:20

浅谈Javascript数组的使用_javascript技巧的相关文章

浅谈Javascript 数组与字典_javascript技巧

Javascript 的数组Array,既是一个数组,也是一个字典(Dictionary). 先举例看看数组的用法. 复制代码 代码如下: var a = new Array();  a[0] = "Acer";  a[1] = "Dell";  for (var i in a) {      alert(i);   }  上面的代码创立了一个数组,每个元素都是一个字符串对象. 然后对数组进行遍历.注意 i 的结果为 0 和 1,a[i] 的结果才为字符串. 这个很

浅谈JavaScript for循环 闭包_javascript技巧

有个网友问了个问题,如下的html,为什么每次输出都是5,而不是点击每个p,就alert出对应的1,2,3,4,5. <html > <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>闭包演示</title> <script type="text/javascript&quo

浅谈javascript的Touch事件_javascript技巧

js的touch事件,一般用于移动端的触屏滑动 复制代码 代码如下: $(function(){document.addEventListener("touchmove", _touch, false);}) function _touch(event){alert(1);} touchstart:当手指触摸屏幕时触发:即使已经有一个手指放在了屏幕上也会触发. touchmove:当手指在屏幕上滑动时连续的触发.在这个事件发生期间,调用preventDefault()可阻止滚动. to

浅谈JavaScript的闭包函数_javascript技巧

在JavaScript中,闭包恐怕是很多人不能理解的一个概念了,甚至很多人也会把闭包和匿名函数混淆. 闭包是有权访问另一个函数作用域中的变量的函数.首先要明白的就是,闭包是函数.由于要求它可以访问另一个函数的作用于中的变量,所以我们往往是在一个函数的内部创建另一个函数,而"另一个函数"就是闭包. 比如之前提到过的作为比较函数: function createComparisonFunction(propertyName){ return function(object1,object2

浅谈javascript中replace()方法_javascript技巧

定义和用法 replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串.语法stringObject.replace(regexp/substr,replacement) 返回值 一个新的字符串,是用 replacement 替换了 regexp 的第一次匹配或所有匹配之后得到的.说明 字符串 stringObject 的 replace() 方法执行的是查找并替换的操作.它将在 stringObject 中查找与 regexp 相匹配的子字符串,然后用 r

浅谈javascript中自定义模版_javascript技巧

/** * Created by Administrator on 15-1-19. */ function functionUtil() { } functionUtil = { //某个DOM节点是否有某个属性 hasAttr: function (el, name) { var attr = el.getAttributeNode && el.getAttributeNode(name); return attr ? attr.specified : false }, //根据cla

浅谈javascript中的闭包_javascript技巧

很长一段时间不理解闭包,后来了解了作用域,以及this相关问题才理解了闭包相关知识. 闭包(closure),也是面试题常客.简单点来说就是函数嵌套函数. 函数作为返回值: function foo () { var a = 1; return function () { a++; console.log(a); } } var aaa = foo(); aaa(); //2 aaa(); //3 其实这个代码不难理解,aaa是指向foo()返回的一个新函数,但是在这个函数里面引用了a变量,所以

浅谈JavaScript之事件绑定_javascript技巧

其实没有什么新的知识点,只是为了方便其他有需要的朋友们翻阅,对自己而言也算是一个积累,所以只能算是闲谈 JavaScript,老鸟们可以尽情飘过.在进入正题之前,先提个问题热热身吧.现在有如下 HTML 结构: 复制代码 代码如下: <div id="wrap"> <input type="button" value="按钮一" /> <input type="button" value=&quo

浅谈javascript的原型继承_javascript技巧

请看源码: 复制代码 代码如下: function clone(o) { var F = function(){}; F.prototype = o; return new F(); } 首先看ext(4.1的1896行开始)的原型式继承. 复制代码 代码如下: var TemplateClass = function(){}; var ExtObject = Ext.Object = { chain: function (object) { TemplateClass.prototype =