記博客,時常回顧.尤爲是面試之先回顧
阮一峯標準庫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 