记博客,时常回顾.尤为是面试之先回顾
阮一峰标准库Array对象javascript
栈,堆,栈里面存一个window/global对象的地址,指向对内存,堆内存存一个hash表.里面有标准库.
标准库里有Object()函数,String()函数,Number(),Boolean().这篇文章记录Array(),Function()html
NaN也是数java
五个false值0 ,'' ,NaN ,undefined ,Null
面试
Boolean({})//ture Boolean(' ')//ture,空格也算ture
JS的七种数据结构
number,string,boolean,object,undefined,null,symbol
symbol为新加的
学习地址:MDNArray或阮一峰标准库Array对象segmentfault
let f1 = ['a','b']; let f2 = new Array('a','b');
两种方法等价api
var a = Array(3)
若是直接数组
var a = Array(3);//参数为数组长度
那么a就是一个长度为3,但里面每个内容都是undefined的数组
且a[0]a[1]a[2]都是不存在的,下面经过内存图来看看为何会这样
这个a里面在栈中存了一个地址,好比说是99,指向堆里的一块内存空间,可是这个堆里只存了一个length:3
的键值对和__proto__
指向Array.Prototype
,里面有一些shift
`push`的函数.
因此才undefined
.由于没有存下来
如图数据结构
var 声明一个变量的时候是一个语句,语句返回的值是undefined,但表达式返回的值随着表达式变化函数
var a = Array(3,3)
两个参数的时候,里面的参数都是数组内部的值学习
总结,加不加new都同样
原始类型Number,String,Boolean加不加new 不 同样,复合类型object,array.function加不加new同样
好比new Function()和不加new的Function()
function是关键字,和var if let这些同样,是用来声明一个函数的关键字
而Function是window的全局对象
window.Function
只不过大写的Function也能够建立一个函数
详细看阮一峰的三种声明函数的方法
用Array方法构造出来的那个对象,就是数组
为何没有声明push
的key
,就能够用a.push
呢,由于a.__proto__
链接到了一个共用对象,Array.prototype
原型链
Array有不少API怎么作到体积小,功能强大呢?原型链,共用属性,共用方法,经过__proto__
量过去就行了
var a = Array(1,1); a.__proto__ ===Array.prototype//true a.__proto__.__proto__===Object.prototype//true Array.prototype.__proto__=== Object.prototype//true
__proto__
指向的不同,共用属性不同,里面所拥有的API不同.区别就在于原型不同.
数组和对象都是对象,只不过是原型链不一样的对象.
length仍是3,可是却有新加入的属性,就像对象同样.
第一种方式,把数组看成真数组,故意去访问数组的下标
第二种,打印出全部的的key.
总结:数组只不过是拥有特殊原型链的对象.
for in遍历 只关内心面有全部的键值对,for i循环只关心循环的标序.
__proto__
中没有Array.prototype
,就是伪数组.
例如:只关心他的下标,能够彻底用hash键值对来表示.
JS里面只有一个伪数组arguments
arguments表明函数里面所传入的全部的参数,是伪数组.
由于不必在伪数组里push和pop东西,因此没有那些Array.prototype
里面的方法.
a.forEach()须要接受一个函数,这个函数必须接受两个参数.
数组的api中,a.forEach之因此没有把array传进去,是由于用了this指代当前的对象.用this就能够找到那个调用它的数组.因此forEach原理:
forEach中函数传的第三个参数是他本身
内置快排.
阮一峰标准库Array.sort()
排序后原数组也会改变,只有sort改变了原值
sort
方法不是按照大小排序,而是按照字典顺序。也就是说,数值会被先转成字符串,再按照字典顺序进行比较,因此101排在11的前面。若是想让sort方法按照自定义方式排序,能够传入一个函数做为参数。
[10111, 1101, 111].sort(function (a, b) { return a - b; }) // [111, 1101, 10111]
上面代码中,sort的参数函数自己接受两个参数,表示进行比较的两个数组成员。若是该函数的返回值大于0,表示第一个成员排在第二个成员后面;其余状况下,都是第一个元素排在第二个元素前面。
[ { name: "张三", age: 30 }, { name: "李四", age: 24 }, { name: "王五", age: 28 } ].sort(function (o1, o2) { return o1.age - o2.age; }) // [ // { name: "李四", age: 24 }, // { name: "王五", age: 28 }, // { name: "张三", age: 30 } // ]
里面的参数是两个比较的数组成员
通常用法,链接数组
数组中a + b
是a.toString() + b.toString()
特殊用法,复制数组
内容同样,地址不同
map是映射的意思
map和forEach同样,能够遍历数组,可是与forEach不一样的是能够有返回值,能够将传递进去的函数的返回值在收集起来,返回一个新数组
下面是箭头函数,参数=>返回值
也能够返回对象
全部的value都会一一映射
filter是过滤的意思
与map的区别,过滤.不是一一映射了
总结:forEach,map,filter均可以传入一个函数,这个函数均可以接受三个参数,分别是值,键,数组自己,forEach没有返回值,
map,filter分别返回一个新数组,map为映射返回,filter为过滤返回
[1, 2, 3].map(function(elem, index, arr) { return elem * index; }); // [0, 2, 6]
reduce() 方法对累加器和数组中的每一个元素(从左到右)应用一个函数,将其减小为单个值。----MDN
MDN:Array.prototype.reduce()
![]()
阮一峰reduce()
下面是阮一峰的教学:
reduce方法和reduceRight方法依次处理数组的每一个成员,最终累计为一个值。它们的差异是,reduce是从左到右处理(从第一个成员到最后一个成员),reduceRight则是从右到左(从最后一个成员到第一个成员),其余彻底同样。
[1, 2, 3, 4, 5].reduce(function (a, b) { console.log(a, b); return a + b; }) // 1 2 // 3 3 // 6 4 // 10 5 //最后结果:15
上面代码中,reduce方法求出数组全部成员的和。第一次执行,a是数组的第一个成员1,b是数组的第二个成员2。第二次执行,a为上一轮的返回值3,b为第三个成员3。第三次执行,a为上一轮的返回值6,b为第四个成员4。第四次执行,a为上一轮返回值10,b为第五个成员5。至此全部成员遍历完成,整个方法的返回值就是最后一轮的返回值15。
reduce方法和reduceRight方法的第一个参数都是一个函数。该函数接受如下四个参数。
累积变量,默认为数组的第一个成员
当前变量,默认为数组的第二个成员
当前位置(从0开始)
原数组
这四个参数之中,只有前两个是必须的,后两个则是可选的。
若是要对累积变量指定初值,能够把它放在reduce方法和reduceRight方法的第二个参数。
[1, 2, 3, 4, 5].reduce(function (a, b) { return a + b; }, 10); // 25
上面代码指定参数a的初值为10,因此数组从10开始累加,最终结果为25。注意,这时b是从数组的第一个成员开始遍历。
上面的第二个参数至关于设定了默认值,处理空数组时尤为有用。
function add(prev, cur) { return prev + cur; } [].reduce(add) // TypeError: Reduce of empty array with no initial value [].reduce(add, 1) // 1
上面代码中,因为空数组取不到初始值,reduce方法会报错。这时,加上第二个参数,就能保证老是会返回一个值。
因为这两个方法会遍历数组,因此实际上还能够用来作一些遍历相关的操做。好比,找出字符长度最长的数组成员。
function findLongest(entries) { return entries.reduce(function (longest, entry) { return entry.length > longest.length ? entry : longest; }, ''); } findLongest(['aaa', 'bb', 'c']) // "aaa"
上面代码中,reduce的参数函数会将字符长度较长的那个数组成员,做为累积值。这致使遍历全部成员以后,累积值就是字符长度最长的那个成员。
reduce中函数的第一个参数表示的是累计值,第二个参数是每次遍历数组时的每个当前值.return的是下一次开始循环的累积值.
因此
reverse方法用于颠倒排列数组元素,返回改变后的数组。注意,该方法将改变原数组。
var a = ['a', 'b', 'c']; a.reverse() // ["c", "b", "a"] a // ["c", "b", "a"]
计算全部偶数的平方,并将其返回成一个新数组
var a = [1,2,3,4,5,6,7,8,9] a.filter((x)=>(x%2===0)).map((x)=>(x*x))//(4) [4, 16, 36, 64]
filter()和map()里面传递函数的参数,第一个为value,第二个为key.
计算全部奇数的和
var a = [1,2,3,4,5,6,7,8,9] a.reduce((sum,a)=>{if(a%2===1){return sum+a}else{return sum}},0)//25 1+3+5+7+9//25 