摘要:圖示如下而對(duì)于引用類型的復(fù)制可不是這樣這個(gè)復(fù)制只是將的引用賦值給,二者是屬于同一個(gè)引用,訪問的都是堆內(nèi)存中的同一個(gè)對(duì)象,任何一個(gè)該引用的變量發(fā)生變化,會(huì)對(duì)其余使用該引用的變量也發(fā)生變化。
這兩天自己在寫代碼的時(shí)候,出現(xiàn)一個(gè)BUG,代碼如下:
class Car { constructor(carId) { this.position = [114, 130] this.path = [] this.speed = Math.floor(Math.random() * 5) this.timer = null } run(){ this.position[0] += this.speed * (Math.random() * 2 == 1 ? 1 : -1) this.position[1] += this.speed * (Math.random() * 2 == 1 ? 1 : -1) this.path.push(this.position) if(this.path.length > 10){ this.path.shift() } } start(){ this.timer = setInterval(function(){ this.run() }, 1000) } stop(){ clearInterval(this.timer) } } var car = new Car("10086") car.start()
代碼預(yù)期的結(jié)果是,記錄car的最近10個(gè)坐標(biāo)點(diǎn)。
但是實(shí)際結(jié)果大失所望,得出的是10個(gè)一模一樣的坐標(biāo)點(diǎn),原因在于調(diào)用run方法時(shí),其中坐標(biāo)的改變是基于其屬性position這個(gè)數(shù)組對(duì)象的改變,而數(shù)組對(duì)象的變量名其實(shí)是對(duì)數(shù)組對(duì)象地址的引用,因此導(dǎo)致了最后一個(gè)坐標(biāo)的改變引起了所有坐標(biāo)的改變。
通過這個(gè)BUG對(duì)自己的基礎(chǔ)知識(shí)又進(jìn)行了一次梳理,歸納以及總結(jié),參考資料為JavaScript高級(jí)程序設(shè)計(jì):
1:基礎(chǔ)類型 : Undefined、null、Boolean、Number和String
2:引用類型 : object
其中引用類型的賦值操作需要注意,因?yàn)橐妙愋偷闹凳前匆迷L問的,且具有動(dòng)態(tài)屬性,會(huì)根據(jù)取得其引用的變量的操作而改變該引用的內(nèi)存對(duì)象發(fā)生改變。取復(fù)制變量的例子用圖示的方法來解釋:
如下代碼:
var num1 = 5 var num2 = num1
基本類型的賦值就相當(dāng)于創(chuàng)建一個(gè)num1的副本,同時(shí)將num2的值等于該副本,兩個(gè)變量之間的操作互不影響。
圖示如下:
而對(duì)于引用類型的復(fù)制可不是這樣
var num1 = obj1 var num2 = num1
這個(gè)復(fù)制只是將num1的引用賦值給num2,二者是屬于同一個(gè)引用,訪問的都是堆內(nèi)存中的同一個(gè)對(duì)象,任何一個(gè)該引用的變量發(fā)生變化,會(huì)對(duì)其余使用該引用的變量也發(fā)生變化。
在JS中函數(shù)參數(shù)的傳參方式都是按值傳參的
可以近似看成函數(shù)內(nèi)部聲明一個(gè)局部變量名為參數(shù)名字的變量,同時(shí)為其賦值為參數(shù)的值,參數(shù)為引用類型則較為復(fù)雜些,主要是按值傳遞比較難理解。
傳遞的參數(shù)為引用類型的話,即函數(shù)內(nèi)部該參數(shù)發(fā)生了改變會(huì)引起堆內(nèi)存對(duì)象的屬性發(fā)生改變,那么為什么不叫按引用訪問,資料中有如下代碼進(jìn)行解釋:
function setName(obj) { obj.name = "Nicholas"; obj = new Object(); obj.name = "Greg"; } var person = new Object(); setName(person); alert(person.name); //"Nicholas"
書中的解釋比較簡潔,個(gè)人理解為如果是按引用傳參則會(huì)發(fā)生堆內(nèi)存的對(duì)象會(huì)發(fā)生改變,由原本的實(shí)例person將被新的new Object的實(shí)例,同時(shí)將其屬性name置為"Greg",即最終obj指向的是new Object的實(shí)例,而事實(shí)上沒有,可以理解為函數(shù)的引用類型的參數(shù)為引用類型的引用,且這里對(duì)引用的處理方式是類似基本類型的值一般,不會(huì)發(fā)生變化。
圖示如下:
歸納總結(jié)基礎(chǔ)知識(shí)梳理完畢,回到我的BUG,犯的錯(cuò)誤就是引用類型的訪問方式的錯(cuò)誤,path所push的position數(shù)組準(zhǔn)確來說指向的都是同一個(gè)對(duì)象,因此position的每次變化,數(shù)組中所有的元素都會(huì)發(fā)生相同的變化,導(dǎo)致path數(shù)組的元素均為一致.
為此對(duì)數(shù)組的方法進(jìn)行一次歸納,將數(shù)組中可以返回新數(shù)組副本(即對(duì)原數(shù)組無影響)的方法,以方便避免像我這種使用導(dǎo)致的BUG
返回新數(shù)組副本方法:concat, slice, splice, filter, map
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/90560.html
摘要:但在開始之前應(yīng)該心中有數(shù)值的不可變性并不是說我們不能在程序編寫時(shí)不改變某個(gè)值。這些都是對(duì)值的不可變這個(gè)概念的誤解。程序的其他部分不會(huì)影響的賦值。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 關(guān)于譯者:這是一個(gè)流淌著滬江血液的純粹工程:認(rèn)真,是 HTML 最堅(jiān)實(shí)的梁柱;分享,是 CSS 里最閃...
摘要:項(xiàng)目中異常分析引發(fā)崩潰日志的流程分析解決辦法常見的出現(xiàn)場景狀態(tài)異常非法線程操作。引發(fā)崩潰日志的流程分析解釋如下所示,釋放與此位圖關(guān)聯(lián)的本機(jī)對(duì)象,并清除對(duì)像素?cái)?shù)據(jù)的引用。 目錄介紹 1.1 java.lang.UnsatisfiedLinkError找不到so庫異常 1.2 java.lang.IllegalStateException非法狀態(tài)異常 1.3 android.conten...
摘要:幸運(yùn)的是,使用符號(hào)創(chuàng)建的構(gòu)造器,如果在不使用來調(diào)用,則始終會(huì)報(bào)錯(cuò),即使在非嚴(yán)格模式下也不會(huì)產(chǎn)生問題。 來源:ApacheCN『JavaScript 編程精解 中文第三版』翻譯項(xiàng)目原文:Bugs and Errors 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 自豪地采用谷歌翻譯 部分參考了《JavaScript 編程精解(第 2 版)》 調(diào)試的難度是開始編寫代碼的兩倍。 因此,如...
摘要:但是當(dāng)傳遞的參數(shù)為對(duì)象或者數(shù)組的時(shí)候,是通過引用傳入的,所以對(duì)于一個(gè)引用類型的來說,在子組件中改變這個(gè)參數(shù)本身將會(huì)影響到父組件的數(shù)據(jù)狀態(tài)。 問題 父級(jí)組件與子組件的通信一般都是通過props來實(shí)現(xiàn)的,因?yàn)閿?shù)據(jù)流向的單一才能保證數(shù)據(jù)變化的可追蹤性,在vue中props遵循的是單向數(shù)據(jù)流,原則上子組件修改props是不被允許的。但是當(dāng)props傳遞的參數(shù)為對(duì)象或者數(shù)組的時(shí)候,是通過引用傳入...
摘要:出現(xiàn)錯(cuò)誤引發(fā)崩潰日志的流程分析這個(gè)錯(cuò)誤是應(yīng)用的方法總數(shù)限制造成的。 目錄介紹 1.1 java.lang.ClassNotFoundException類找不到異常 1.2 java.util.concurrent.TimeoutException連接超時(shí)崩潰 1.3 java.lang.NumberFormatException格式轉(zhuǎn)化錯(cuò)誤 1.4 java.lang.Illegal...
閱讀 3555·2021-11-22 15:22
閱讀 3341·2019-08-30 15:54
閱讀 2735·2019-08-30 15:53
閱讀 827·2019-08-29 11:22
閱讀 3547·2019-08-29 11:14
閱讀 2087·2019-08-26 13:46
閱讀 2220·2019-08-26 13:24
閱讀 2286·2019-08-26 12:22