数组
object数据类型的时候,object有3种表现形式:
null - 空
{} - 俗称对象,一个大的内存空间存储多个小的内存空间,键值对组成
{}定义的对象跟[ ]定义的数据有什么区别?
{}对象中,数据是由多个键值对组成的。多个键值对之间是没有顺序的。
[ ] 定义的数据跟普通数据有什么区别?
跟{}定义的对象含义差不多,也是复杂的数据,在一个大的内存空间中,存储多个数据
[]里面的数据,是有顺序的
都是在大空间放很多小空间,{}描述的时候无需的,只看小空间的名称,[]描述的时候,是按照空间的顺序来描述的
[] - 俗称数组,也是使用一个大的内存空间来存放多个小的内存空间,大空间中的小空间之间是有顺序的
数组的定义 - 数组:Array
语法:
var arr = []
var arr = new Array() - 系统提供了各种构造函数用来创建各种数据
数组的细节:
1.数组中存放的数据,类型是没有限制的,可以存放任意类型的数据
2.数组中小空间的编号,永远都是从0开始,一次向后递增的,数组中第一个小空间的编号,永远是0。
3.数组中最后一个小空间的编号,永远都是 数组中数据的个数-1。
4.获取数组中数据的个数:数组.length 获取 - 数组长度
5.当使用[]定义数据时,如果[]中只有一个数字,此时代表大空间中只有一个小空间,小空间中的数据是这个数字;当使用new Array()定义数据时,如果()中只有一个数字,表示大空间中有 数字 个空的小空间
获取数组中的具体数据
数组[小空间编号]
小空间编号 - 下标
给数组设置数据
数组[下标] = 值
如果要添加的下标大于最大的下标,中间一定会创建多个空的小空间
当设置的下标大于最大下标,就是添加,如果设置的下标在0~最大下标之间,修改其中的值
删除数组数据
因为数组也属于object类型,所以,delete对于数组来说同样适用
delete 数组[下标] - 只能删除小空间中对应的数据,但是小空间还存在
可以利用数组的长度来删除数组
超出指定长度的数据都被删除掉了
如果赋的值超出原本的长度,就会在后面创建多个空的小空间
数组遍历:将数组中每个元素都访问一次
使用循环处理重复 - 利用循环遍历数组
数组规律:第一个下标是0,最后一个下标是 arr.length-1
输出第一个元素: arr[0]
输出最后一个元素:arr[arr.length-1]
因为数组也是object对象类型,只要是对象类型,就可以使用对象的遍历方式去遍历数组
可以使用 for in这种语法来遍历数组
区别1:for in遍历出来的下标是字符串,for i=0遍历出来的是数字
区别2:for in只遍历有值的空间,i=0的方式,会将空的小空间中的值也遍历出来
区别3:for in会遍历原型中的数据,for i=0只能遍历当前空间中的数据
建议大家使用i=0的方式去遍历
可以将数组理解成是由键值对组成的数据,键是数字
可以将对象理解成是有编号的很多小空间组成,下标是字符串
数组的嵌套
数组中数据类型没有限制,可以放number、boolean、undefined、string、object、function
数组中的数据也可以是数组,这样就形成了数组的嵌套
包含数组的数组,叫做多维数组,我们用的最多的就是二维数组。
大数组arr
中数组 arr[0]
小数组 中数组[1]
基础类型和引用类型
数据类型:number/string/boolean/undefined/object下(null/{}/[])/function
在js中没有null类型,没有数组类型,数据类型:object类型
根据每种数据类型存储方式和赋值方式的不同,将所有数据类型分成2大类:
基础类型:number/string/boolean/undefined/null
引用类型:{}/[]/function
从存储的角度来看待不同的数据类型:
基础数据类型会将数据存储在栈中,引用数据类型会将数据存储在堆中,将堆的地址存储在栈中
基础类型
var a = 10
在内存中开辟空间a,给其中放入数据10
我们在内存中存储数据,内存空间会被划分成多个区域,每个区域各司其职,例如,内存会专门划分一片区域用来运行我们的系统,内存会划分专门的区域用来执行js代码。
存储数据,也是会在内存中有专门的一片空间,用来存储数据,这个空间的名称叫做 栈
var arr = ['a', 'b', 'c']
会在栈中开辟空间arr,将数据存放在另一个内存空间 堆 中,堆中存放数据的内存地址,放在栈中arr的空间
通过赋值角度来看待不同的数据类型:
基础类型的赋值,是将其中一个值复制到另一个变量容器中,引用类型的赋值是将一个栈中的内存地址复制一份放到另一个变量容器中,改变其中一个的值,另一个也会发生改变
基础类型:
var a = 10
var b = a // 将a中的值复制一份放到了b中,复制以后,有两个独立的值
a = 20 // 改变其中一个,另一个不会发生改变的
console.log(b); // 10
引用类型:
var arr = ['a', 'b', 'c']
var brr = arr // 将arr在栈中存储的地址复制了一份给brr,此时arr和brr共享同一个值的内存地址
arr[1] = 'd' // 将arr存储的地址中的值的b改成d
没有改变arr在栈中存储的内存地址
console.log(brr); // brr也就跟着发生了改变
注意事项:重新给arr赋值,就会将arr在栈中存储的内存地址改掉
在进行全等比较的时候
基础类型先比较类型是否相同,如果类型相同了,再比较值是否相等;引用类型,会比较内存地址是否相同
基础类型的全等比较:比较类型和值
引用类型的全等比较: 引用类型在进行全等比较的时候,在比较栈中存储的内存地址是否相同
示例:
function map(arr) {
函数中的形参 隐形的定义操作 var arr
隐形的赋值操作: arr = 外面全局的arr - 是引用类型的赋值,改变其中的任何一个的值,另一个也会发生改变
arr[0] = 1
}
在函数中改变arr
var arr = [10,20,30]
map(arr) 用实参给形参赋值的时候,其实在函数内部:
console.log(arr); 输出 1,20,30
数组方法:因为系统为了方便我们对数组进行操作,系统提供了一些专业操作数组的方法
对象.方法名():对象的方法:对象中的键值对是一个函数
开头添加 unshift:数组.unshift(一个值或多个值):给数组的开头添加一个或多个元素:返回添加以后的新数组的长度
开头删除shift:数组.shift() 。 给数组的开头删除一个元素,不需要参数,返回被删除的元素
结尾添加push:数组.push(一个值或多个值) 。 给数组的末尾添加一个或多个元素,返回新数组的长度
结尾删除pop:数组.pop()。给数组的末尾删除一个元素,返回被删除的值
在任意位置对数组进行增、删、改 splice:数组.splice()。
数组.splice(要删除的元素开始的下标, 删除个数)删除语法:返回被删除的值组成的数字
数组.splice(要删除的元素开始下标, 删除个数, 要放在删除位置的1个或多个值) 修改语法:返回被删掉的元素组成的数组
在某个位置删除掉元素后,又放上新的元素 - 间接的形成了修改操作
添加操作:还是修改语法,将删除的个数设置为0即可
concat 合并数组 将多个数组或元素跟当前数组合并成一个更大的数组
语法: 数组.concat(1个或多个元素或数组) - 返回合并以后的大数组
sort:将数组进行排序
语法:数组.sort() - 返回当前排序后的数组 - 将数组从小到大进行排序
语法2:数组.sort(function(a, b) { a和b这两个参数是我们自定义的
return a-b 表示升序,从小到大
return b-a 表示降序,从大到小}
reverse:将数组翻转
语法:数组.reverse() - 返回值是当前数组,翻转以后的数组
join 将数组元素使用指定的连接符连接成一个字符串
语法:数组.join(指定的连接符) - 返回连接以后的字符串
连接符我们可以指定为空字符串
我们可以省略连接符 - 默认使用逗号连接
slice 截取数组 - 可以将数组中指定的连续的一部分,单独拿出来做为一个新的数组
语法:数组.slice(开始下标, 结束下标) - 返回截取的结果,结果中不包含结束下标对应的元素
冒泡排序
sort方法可以进行排序,要学习的这两个排序方式,是实现sort内部排序的原理
如果有一天sort方法不能用了,我们也可以手动将数组进行排序
这两种排序方式是一些算法的基础,最简单的算法
冒泡排序:每相邻两个元素进行比较,将一个数组中的数字使用循环进行升序或降序的排列
for(var j=0;j<arr.length-1;j++){
for(var i=0;i<arr.length;i++){
if(arr[i]>arr[i+1]){
var tmp = arr[i]
arr[i] = arr[i+1]
arr[i+1] = tmp}}}
选择排序
降序:先找最大值,排在最左边,再找第二大的值,往左边靠...,已经排好的,不再参与比较
for(var j=0;j<arr.length-1;j++){
for(var i=j+1;i<arr.length;i++){
if(arr[j]>arr[i]){
var tmp = arr[j]
arr[j] = arr[i]
arr[i] = tmp}}}
如果要进行降序排列,就将判断条件中的>换成<即可