数组Array
-
let a =['a','b'] 等价于 let a = new Array('a','b')
-
第一种用法: var a = Array(3) // 内存图展示整个过程,变量a 在stack存有一个地址,这个地址指向 heap内存某一块区域,这区域存有lengh:3 ;proto ;两个属性/ 其中的proto指向公有属性/ Array.prototype(里面存有push....等Array私有属性)
-
隐式原型指向创建这个对象的函数(constructor)的prototype;显式原型的作用:用来实现基于原型的继承与属性的共享。 隐式原型的作用:构成原型链,同样用于实现基于原型的继承。举个例子,当我们访问obj这个对象中的x属性时,如果在obj中找不到,那么就会沿着proto依次查找。/本质上没差别,只是身份不同叫法不一样.对象的proto 指向创建(new)这个对象的构造函数的prototype属性.
-
另外还有一种情况:var a = Array(3,3) //这时候a的值是一个数组,对应'0':3 ;'1':3; lengh=2
-
这就是JavaScriptArray奇怪的地方,当参数只有一个的时候,他代表的是长度lengh的值,当有多个参数就是一个实在的数组了.这叫JavaScript的Array不一致性.(就是垃圾)
-
检查某个键名是否存在的运算符in,适用于对象,也适用于数组。
-
for...in循环不仅可以遍历对象,也可以遍历数组,毕竟数组只是一种特殊对象。
特殊在哪里?(特殊在,对象数据是映射,数据无序;而数组数据是有序排列的)
第二种用法用new,其实加不加new对于Array来说没有区别
规律
- 在JavaScript中全局变量有两种,一种是基本类型的全局对象:Number String Boolean ,不加new返回的是一个基本类型的值,加了new之后返回的就是复杂类型的值,也就是对象;
- Object Function Array这三个加不加new都一样.
- 函数一定有返回代码:return 就算你不写,也会默认给你return undefined// Function a(){.....
//就算你不写return,浏览器也会自动帮你加上return undefined
} - 注意一点,我们可以通过var Function都可以声明一个函数, 但是var 是分步骤的,是两个语句;而Function a (){}这种形式是一步走.这也是为什么在变量提升的时候,var声明 会被拆分,而Function是整体前移.
- 函数分具名函数和匿名函数
终极问题,什么是数组?
- 数组是按次序排列的一组值(阮一峰),Array是由Array构造出来的对象,他是一种特殊的对象(方方)
- 特殊在哪里?
- 为什么var a =[1,2,3]是数组,obj ={'0':1,1:2,2:3}是对象? (在内存图上分析是一样的)! 因为他们的指向的公有属性不一样.数组指向Array.prototype 而对象指向Object.prototype 也就是说,他们内存是一样的,只是指向的原型不一样.原型不一样,有用的方法函数也不一样,这就是为什么伪数组没有push方法,
// 公式: 对象.proto === 构造函数.prototype
数组实际上还是对象,他只是有特殊原型链的对象.
var a = Array()
for (let i;i<3;i++){
console.log(a[i])
}
a.xxx = 'xxx'
console.log(a)// (3)[1,2,3,xxx:'xxx'] 括号里面是3,是因为JavaScript中的对象,将非数字选择性遍历就是数组.所以它是3 忽略了xxx,不是4
////////////////////////////////////
for(let key in a){
console.log(key)
}
这时候就是全部遍历,这就是对象. 数组就是对象,JavaScript在实现的过程中就是利用选择性遍历来实现区分的. 数组和对象的区别在于指向的原型不一样,拥有不用的公有属性.
- 知道上面的知识点之后,再来了解新的知识点:伪数组,伪数组就是那些不指向Array原型,没有push....等方法的对象(简单来说:一个数组的原型链中没有指向Array.prototype就是伪数组)
- 那么伪数组的意义在哪里呢? 在于我想用一个可以遍历下标的哈希结构的对象,我不关心有没有那些公有的属性,比如push之类的方法,这时候就可以用到伪数组了,JavaScript中只有一个伪数组,那就是arguments
数组常用的API
- forEach的使用是接受一个函数,以前都是简单的类型,现在来一个函数,是一个观念上的突破.
- 声明的函数,和不执行的代码就是放在内存,什么都不做.就那么简单,而且根据JavaScript的垃圾回收机制,一个不被引用的数据就会被回收,所以什么也不做,只是放在内存里,随之也会被销毁,除非有人引用.// function f (){....} 这就是声明了一个函数,并且被f引用,所以暂时内存不会被销毁,但是当函数执行完毕,退出之后,也会被销毁.
- 总的来说就是,JavaScript的函数可以接收一个函数,并且能执行他.不但可以执行,还能传进参数再执行.
数组的第一个API forEach(//遍历函数)
forEach函数的源码:
obj.forEach = function (x){
for(let i =0 ; i<array.lengh;i++){
x(array[i],i)
}
}
///////////////////////////////////////////////////////////////
function (x) {
for(let i = 0 ; i<this.length;i++){
x(this[i],i)
}
- 随之而来就有一个问题了,你forEach一个数组可以理解,那你a.forEach 是如何把a传进去了?还能遍历~~~?
- 这就涉及到一个问题,JavaScript坑人的地方// a.forEach(function(){})等价于
a.forEach.call(a,function(){}) JavaScript在调用一个函数的时候,实际是这样子的,隐藏地把参数传进去了.
结论是,forEach的源代码是通过this 把调用这个forEach()函数的参数传进去的.
数组除了forEach 还有 sort()属性,sort 属性是用来排序的//
a.sort(function (x,y){return x-y}) 就是从小到大的排序
a.sort(function (x,y){return y-x}) 就是从大到小的排序
sort会改变原来的数组
只有这两种,用的时候不用记,就两种试试就好了
在JavaScript虽然排序是木桶排序算法快,可是木桶内存太大.所以基本都是用快速排序实现排序.
-
数组剩下的API
-
join() 在一起
-
concat () 连在一起
..... 最后半小时视频以后补上就可以完成作业题了. -
concat的一个特殊用法: var a = [1,2,3]; var b = a.concat([])
这样子做的效果就是复制一个数组,和传统b=a的赋值区别在于,这是完全创建一个新的一样的数组,但是因为地址不同肯定a!==b 但是数组里面的值是一样的. 传统b=a这种赋值是同一个数组,b存储的只是a的地址, 但是用concat之后b就是一个完全新的数组和a没有任何关系. -
foreach 和map几乎一样,map有返回值,而forEach没有返回值.
箭头函数的使用a.map(value=>value*2)
- filter过滤函数
方法一览
- valueOf方法返回数组本身。
- toString方法返回数组的字符串形式。
- push方法用于在数组的末端添加一个或多个元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组。
- pop方法用于删除数组的最后一个元素,并返回该元素。注意,该方法会改变原数组。
- join方法以参数作为分隔符,将所有数组成员组成一个字符串返回。如果不提供参数,默认用逗号分隔。
- concat方法用于多个数组的合并。它将新数组的成员,添加到原数组成员的后部,然后返回一个新数组,原数组不变。
- shift方法用于删除数组的第一个元素,并返回该元素。注意,该方法会改变原数组。
- unshift方法用于在数组的第一个位置添加元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组。
- reverse方法用于颠倒数组中元素的顺序,返回改变后的数组。注意,该方法将改变原数组。
- slice方法用于提取原数组的一部分,返回一个新数组,原数组不变。
- splice方法用于删除原数组的一部分成员,并可以在被删除的位置添加入新的数组成员,返回值是被删除的元素。注意,该方法会改变原数组。
- sort方法对数组成员进行排序,默认是按照字典顺序排序。排序后,原数组将被改变。
- map方法对数组的所有成员依次调用一个函数,根据函数结果返回一个新数组。
- forEach方法与map方法很相似,也是遍历数组的所有成员,执行某种操作,但是forEach方法一般不返回值,只用来操作数据。如果需要有返回值,一般使用map方法。
- filter方法的参数是一个函数,所有数组成员依次执行该函数,返回结果为true的成员组成一个新数组返回。该方法不会改变原数组。
- some(),every()这两个方法类似“断言”(assert),用来判断数组成员是否符合某种条件。它们接受一个函数作为参数,所有数组成员依次执行该函数,返回一个布尔值。该函数接受三个参数,依次是当前位置的成员、当前位置的序号和整个数组。
- reduce方法和reduceRight方法依次处理数组的每个成员,最终累计为一个值。
使用说明
网友评论