美文网首页
Vue封装JS-箭头函数传参的值类型与引用类型的差异

Vue封装JS-箭头函数传参的值类型与引用类型的差异

作者: 冯阳阳的博客 | 来源:发表于2018-10-26 18:36 被阅读0次

    应用场景

    写了一个关于canvas的标注项目,大量的canvas交互,html结构不超过50行,但是js逻辑大约2000行,主要就是对页面上的一个canvas进行操作。本着一个.vue不超过400行的宗旨,对js文件进行拆分,公共的放在common文件夹下进行统一使用,不能二次使用的也根据类别进行归类。

    然后就出现了下面的场景

    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";
    

    箭头函数

    记得最开始使用箭头函数的时候,带给我最大的便利的不是书写方便,而是this的指向性,this指向他定义的的地方,在使用异步回调的时候,箭头函数非常方便,并不需要let that = this;这种普通构造函数内需要保存变量的写法。这也是最开始使用箭头函数的原因。写多了,慢慢的就是拿来即用,没有考虑上下文环境。

    因为封装了大量的js,js文件内部又是大量的数据操作,直到前几天莫名出现了一个bug,开始的时候没有在意,调试了一下没有找到问题,然后换了另外一种实现方法,在今天莫名又遇到了这个问题,停下来看了看问题的原因,原来这是箭头函数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文件调用了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
    }
    

    点击按钮,理论上两个对应的val值会变为100。看效果


    image.png

    只有val改变了,why?其实就是一个this指向的问题,但是会容易忽略:
    看控制台:

    image.png

    打印this后,两个函数this相同,并没有指向那个vue文件,而是common.js文件,因为这才是它定义的地方。

    结论?

    箭头函数传参,如果在其他vue页面调用此脚本中的箭头函数 例如let a=(val)=>{..changevalue}

    • 传递参数一定会为this.value这种写法的 例如 a(this.name),会将this传递进箭头函数

    • 但是,箭头函数内部读取到this的时候,因为箭头函数的this指向定义的位置,

    • 所以当传递this的时候,箭头函数会将传递的this指向当前脚本定义的位置,这个js文件

    • 因此如果在箭头函数内部修改这个值,并不会映射到这个vue页面的值,例如上面的this.value, 因为,他修改的是当前js文件下的this.value值,因为this的指向变了。

    • 如果传递引用类型,a(this.obj),则将this.obj传递进箭头函数时,会将vue页面的this.obj对应的内存中的指针
      赋值给当前js脚本的this.obj(箭头函数传递后,this引用改变,相当于会在当前脚本创建了一个obj),

    • 但是尽管不是同一个obj,但是引用却指向同一块内存,所以传递引用类型进行修改会映射到原来的值。
      很简单的this指向与值类型引用类型的问题

    相关文章

      网友评论

          本文标题:Vue封装JS-箭头函数传参的值类型与引用类型的差异

          本文链接:https://www.haomeiwen.com/subject/ezultqtx.html