Vue封裝JS-箭頭函數(shù)傳參的值類型與引用類型的差異

應(yīng)用場(chǎng)景

寫了一個(gè)關(guān)于canvas的標(biāo)注項(xiàng)目,大量的canvas交互,html結(jié)構(gòu)不超過50行,但是js邏輯大約2000行,主要就是對(duì)頁面上的一個(gè)canvas進(jìn)行操作。本著一個(gè).vue不超過400行的宗旨,對(duì)js文件進(jìn)行拆分,公共的放在common文件夾下進(jìn)行統(tǒng)一使用,不能二次使用的也根據(jù)類別進(jìn)行歸類。

然后就出現(xiàn)了下面的場(chǎng)景

import { getImgScale } from '@/assets/js/ImageLoad.js'
import { getDom ,mapCursor,setSelect, Draw, refreshCanvas} from 'common/js/Assistant.js'
import { apiGetImage } from 'common/js/api.js'
import { mapState , mapMutations} from 'vuex'
import { Rect, Info} from 'common/js/normalize.js'
import { InitBoxPosition } from '@/assets/js/InitClientWh.js'
import { judgeIsInRect} from "common/js/Rect.js";

箭頭函數(shù)

記得最開始使用箭頭函數(shù)的時(shí)候,帶給我最大的便利的不是書寫方便,而是this的指向性,this指向他定義的的地方,在使用異步回調(diào)的時(shí)候,箭頭函數(shù)非常方便,并不需要let that = this;這種普通構(gòu)造函數(shù)內(nèi)需要保存變量的寫法。這也是最開始使用箭頭函數(shù)的原因。寫多了,慢慢的就是拿來即用,沒有考慮上下文環(huán)境。

因?yàn)榉庋b了大量的js,js文件內(nèi)部又是大量的數(shù)據(jù)操作,直到前幾天莫名出現(xiàn)了一個(gè)bug,開始的時(shí)候沒有在意,調(diào)試了一下沒有找到問題,然后換了另外一種實(shí)現(xiàn)方法,在今天莫名又遇到了這個(gè)問題,停下來看了看問題的原因,原來這是箭頭函數(shù)this的問題啊。
看下列示例代碼:

<template>
<div>
  <div class="hello">
    value:{{value}}
    val:{{val.val1}}
  </div>
  <button type='button' @click="change"></button>
</div>
</template>

<script>
import {func1,func2} from '@/CommonJs/common.js'
export default {
  name: 'HelloWorld',
  data () {
    return {
      value:0,
      val:{
        val1:0
      },
    }
  },
  methods:{
    change(){
      func1(this.value);
      func2(this.val);
    }
  }
}
</script>

vue文件調(diào)用了common.js文件的func1、func2方法:
conmon.js

export let func1=(val)=>{
  console.log(this)
  val=100
}
export let func2=(val)=>{
  console.log(this)
  val.val1=100
}

點(diǎn)擊按鈕,理論上兩個(gè)對(duì)應(yīng)的val值會(huì)變?yōu)?00。看效果


image.png

只有val改變了,why?其實(shí)就是一個(gè)this指向的問題,但是會(huì)容易忽略:
看控制臺(tái):

image.png

打印this后,兩個(gè)函數(shù)this相同,并沒有指向那個(gè)vue文件,而是common.js文件,因?yàn)檫@才是它定義的地方。

結(jié)論?

箭頭函數(shù)傳參,如果在其他vue頁面調(diào)用此腳本中的箭頭函數(shù) 例如let a=(val)=>{..changevalue}

  • 傳遞參數(shù)一定會(huì)為this.value這種寫法的 例如 a(this.name),會(huì)將this傳遞進(jìn)箭頭函數(shù)

  • 但是,箭頭函數(shù)內(nèi)部讀取到this的時(shí)候,因?yàn)榧^函數(shù)的this指向定義的位置,

  • 所以當(dāng)傳遞this的時(shí)候,箭頭函數(shù)會(huì)將傳遞的this指向當(dāng)前腳本定義的位置,這個(gè)js文件

  • 因此如果在箭頭函數(shù)內(nèi)部修改這個(gè)值,并不會(huì)映射到這個(gè)vue頁面的值,例如上面的this.value, 因?yàn)?,他修改的是?dāng)前js文件下的this.value值,因?yàn)閠his的指向變了。

  • 如果傳遞引用類型,a(this.obj),則將this.obj傳遞進(jìn)箭頭函數(shù)時(shí),會(huì)將vue頁面的this.obj對(duì)應(yīng)的內(nèi)存中的指針
    賦值給當(dāng)前js腳本的this.obj(箭頭函數(shù)傳遞后,this引用改變,相當(dāng)于會(huì)在當(dāng)前腳本創(chuàng)建了一個(gè)obj),

  • 但是盡管不是同一個(gè)obj,但是引用卻指向同一塊內(nèi)存,所以傳遞引用類型進(jìn)行修改會(huì)映射到原來的值。
    很簡單的this指向與值類型引用類型的問題

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容