JS中ArrayAPI學習筆記

JS中ArrayAPI學習筆記

記博客,時常回顧.尤爲是面試之先回顧
阮一峯標準庫Array對象javascript

1 一些標準庫回顧

Cy4JNq.md.png
棧,堆,棧裏面存一個window/global對象的地址,指向對內存,堆內存存一個hash表.裏面有標準庫.
標準庫裏有Object()函數,String()函數,Number(),Boolean().這篇文章記錄Array(),Function()html

1.1 Object(),String(),Number()等

Cy475t.png

  1. Object(1)和Object('sss')分別返回Number對象和String對象,同理,Object(true)返回Boolean對象

Cy5F2T.png

  1. Object()和new Object()分別返回一個空對象.
  2. 除了Object()用不用new都是對象以外,其餘的標準庫函數跟Object不同
  3. 直接用String()函數返回的是一個字符串,而new String('1')則會返回一個對象.

Cy5ZqJ.png

  1. 其餘標準庫函數同理

Cy5uI1.png
NaN也是數java

  1. Boolean()

Cy58MD.png
五個false值
0 ,'' ,NaN ,undefined ,Null面試

Boolean({})//ture
Boolean('    ')//ture,空格也算ture

2 新api Array

JS的七種數據結構
number,string,boolean,object,undefined,null,symbol

symbol爲新加的
學習地址:MDNArray阮一峯標準庫Array對象segmentfault

2.1 聲明數組

let f1 = ['a','b'];
let f2 = new Array('a','b');

兩種方法等價api

3 聲明數組加不加new

3.1 JS坑一:var a = Array(3)

若是直接數組

var a = Array(3);//參數爲數組長度

那麼a就是一個長度爲3,但裏面每個內容都是undefined的數組
Cy5hWV.png
且a[0]a[1]a[2]都是不存在的,下面經過內存圖來看看爲何會這樣
Cy5oyF.md.png
這個a裏面在棧中存了一個地址,好比說是99,指向堆裏的一塊內存空間,可是這個堆裏只存了一個length:3的鍵值對和__proto__指向Array.Prototype,裏面有一些shift`push`的函數.
因此才undefined.由於沒有存下來
如圖
Cy5xSK.png數據結構

var 聲明一個變量的時候是一個語句,語句返回的值是undefined,但表達式返回的值隨着表達式變化函數

3.2 var a = Array(3,3)

兩個參數的時候,裏面的參數都是數組內部的值
CyIAYt.png學習

CyIkFI.md.png

3.3 加new

CyInOg.png
總結,加不加new都同樣

4 原始類型和和合成類型不一樣點

CyIJpV.md.png
原始類型Number,String,Boolean加不加new 同樣,複合類型object,array.function加不加new同樣
好比new Function()和不加new的Function()
CyId0J.png

4.1 function與Function的區別

CyIX7j.png
function是關鍵字,和var if let這些同樣,是用來聲明一個函數的關鍵字
而Function是window的全局對象
window.Function
只不過大寫的Function也能夠建立一個函數
詳細看阮一峯的三種聲明函數的方法

5 到底什麼是數組

用Array方法構造出來的那個對象,就是數組

爲何沒有聲明pushkey,就能夠用a.push呢,由於a.__proto__鏈接到了一個共用對象,Array.prototype
原型鏈
Array有不少API怎麼作到體積小,功能強大呢?原型鏈,共用屬性,共用方法,經過__proto__量過去就行了

Cyo0KS.png

var a  = Array(1,1);
a.__proto__ ===Array.prototype//true
a.__proto__.__proto__===Object.prototype//true
Array.prototype.__proto__=== Object.prototype//true

CyoBDg.png
CyoDbQ.png

5.1 對象和數組的本質區別:

CyoWvT.md.png
__proto__指向的不同,共用屬性不同,裏面所擁有的API不同.區別就在於原型不同.
數組和對象都是對象,只不過是原型鏈不一樣的對象.

5.2 數組之於對象

CccFJO.png
length仍是3,可是卻有新加入的屬性,就像對象同樣.

5.3 遍歷數組的幾種方式

第一種方式,把數組看成真數組,故意去訪問數組的下標
第二種,打印出全部的的key.
Cccsl4.png
總結:數組只不過是擁有特殊原型鏈的對象.

CccgmR.png
for in遍歷 只關內心面有全部的鍵值對,for i循環只關心循環的標序.

6 僞數組

__proto__中沒有Array.prototype,就是僞數組.
例如:只關心他的下標,能夠徹底用hash鍵值對來表示.
CccIpD.png
JS裏面只有一個僞數組arguments
arguments表明函數裏面所傳入的全部的參數,是僞數組.
由於不必在僞數組裏push和pop東西,因此沒有那些Array.prototype裏面的方法.
CcgF7q.png

7 數組api forEach()

a.forEach()須要接受一個函數,這個函數必須接受兩個參數.
CcgG4K.png

7.1函數參數能夠爲函數理解

Cc2dRU.png

Cc2RJK.png

CcRiF0.md.png
因此forEach實際上相似於下面的實現方法

CcWs4x.png
數組的api中,a.forEach之因此沒有把array傳進去,是由於用了this指代當前的對象.用this就能夠找到那個調用它的數組.因此forEach原理:
CgGO1K.png
forEach中函數傳的第三個參數是他本身
CgJk1f.png

8 數組的sort() api

內置快排.
阮一峯標準庫Array.sort()
CgJKNn.png
排序後原數組也會改變,只有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 }
// ]

裏面的參數是兩個比較的數組成員
CgJIv8.png

9 join&concat&map&filter&reduce

9.1 join

CgJv80.png
阮一峯

9.2 concat

通常用法,鏈接數組
CgY9rF.png

數組中a + ba.toString() + b.toString()

特殊用法,複製數組
CgYFa9.png
內容同樣,地址不同

9.3 map

map是映射的意思
map和forEach同樣,能夠遍歷數組,可是與forEach不一樣的是能夠有返回值,能夠將傳遞進去的函數的返回值在收集起來,返回一個新數組

CgYQVH.png
下面是箭頭函數,參數=>返回值

也能夠返回對象
CgYNM8.png
全部的value都會一一映射

9.4 filter

filter是過濾的意思
CgYBIs.png
與map的區別,過濾.不是一一映射了
CgYrin.png

9.5 filter和map一塊兒用

CgYhdJ.png

鏈式操做
CgtPQf.md.png

總結:forEach,map,filter均可以傳入一個函數,這個函數均可以接受三個參數,分別是值,鍵,數組自己,forEach沒有返回值,
map,filter分別返回一個新數組,map爲映射返回,filter爲過濾返回

[1, 2, 3].map(function(elem, index, arr) {
  return elem * index;
});
// [0, 2, 6]

9.6 reduce

9.6.1 mdn

reduce() 方法對累加器和數組中的每一個元素(從左到右)應用一個函數,將其減小爲單個值。----MDN
MDN:Array.prototype.reduce()
CgBk3d.md.png

9.6.2 阮一峯教學

阮一峯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的參數函數會將字符長度較長的那個數組成員,做爲累積值。這致使遍歷全部成員以後,累積值就是字符長度最長的那個成員。

9.6.3 高級用法

reduce中函數的第一個參數表示的是累計值,第二個參數是每次遍歷數組時的每個當前值.return的是下一次開始循環的累積值.
因此
CgBzxs.png

9.7 reverse()

reverse方法用於顛倒排列數組元素,返回改變後的數組。注意,該方法將改變原數組。

var a = ['a', 'b', 'c'];

a.reverse() // ["c", "b", "a"]
a // ["c", "b", "a"]

map(),filter(),reduce()題目

計算全部偶數的平方,並將其返回成一個新數組

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

![CgsCNT.png](https://s1.ax1x.com/2018/05/20/CgsCNT.png)
相關文章
相關標籤/搜索