今天小K問了我一個面試題,怎麼實現一個實reverse方法,在實現的過程當中我仍是犯了一些錯,實現完之後,對一些知識點的理解又加深了。面試
最開始我是這麼寫的數組
var arr = [1,2,3,4,5] var reverse1 = function (arr) { let newArr = [] while (arr.length>0){ newArr.push(arr.pop()) } console.log(arr,newArr) // [],[5,4,3,2,1] arr = newArr //讓arr等於反轉後的新數組 console.log(arr) // [5,4,3,2,1] return arr } reverse1(arr)
結果有點打臉函數
console.log(arr) // []
上面的現象顯示:我將arr當參數傳入reverse1裏面,我能夠改變arr裏面的內容可是我卻沒法改變arr
(arr由[1,2,3,4,5]pop()五次變成[ ],可是隨後的賦值操做卻沒有成功)
爲何會出現這個問題,咱們得從函數的參數傳遞方式提及this
函數的參數都是值傳遞
怎麼理解這句話,按照高程
的說法,若是這裏是引用傳遞,那麼我在代碼第8行已經讓arr變成了[5,4,3,2,1],那麼外面的arr也應該變,可是如今外面arr倒是[ ],因此函數的參數的傳遞方法都是值傳遞prototype
若是你以爲這麼說仍是比較抽象,你能夠聽聽鄙人陋見,咱們徹底能夠把js裏面數組名當成一個指針變量,儲存的是實際的數組對象的地址。指針意味着咱們經過它能夠訪問它指向的對象。變量意味者我能夠改變這個變量。指針
在函數參數裏面當咱們傳入一個arr的時候,實際傳遞的是一個形參address1,儲存arr這個對象在內存裏的地址,address1=xxxx xxxxx xxxx xxx1。經過address1能夠對arr進行任何操做,一旦如今我爲address1賦上新的地址值,也就是address1=xxxx xxxxx xxxx xxx2。address1就和arr失去了聯繫。此時arr仍是在xxxx xxxxx xxxx xxx1上,而且至少在當前的reverse1方法中不會再被改變了,由於沒有哪一個指針能指向它了。code
ok說了這麼多,實際想說的是,你在方法中能夠經過索引,經過原生方法操做一個當參數傳進來的數組,可是絕對不容許對數組名直接進行賦值
那麼這個題目咱們就能夠嘗試使用原生方法來操做傳進來的數組,這裏提供一種思路對象
var arr = [1,2,3,4,5] var reverse1 = function () { for(var i = 0; i < arr.length; i ++){ arr.splice(i,0,arr.pop()) } } reverse1(arr) console.log(arr) // [5,4,3,2,1]
可是咱們能夠看到上面的方法仍是不是很好,這是由於這個reverse1貌似只能對arr進行操做,耦合性太強,咱們須要解耦,讓reverse1對全部的數組都適用,這裏適用this和原型方面的知識索引
//一個完美的寫法: Array.prototype.reverse1 = function () { for(var i = 0; i < this.length; i ++){ //this 解耦 this.splice(i,0,this.pop()) } return this }
今天介紹了一下reverse的實現思路,this解耦,以及函數參數是值傳遞這麼一個概念,
建議在方法中經過索引,經過原生方法改變一個當參數傳進來的數組,可是絕對不容許對數組名直接進行賦值
但願對你們有所幫助。內存