尝试在Vue中的methods定义几个函数,实现函数A调用函数B的需求。但是发现通过this关键字引用会提示 B函数not defined
错误代码

报错信息如下:

报错信息

实际上个问题的根本原因是函数以及子函数的this作用域范围处理问题

Vue中this作用域说明

参考文章:
Vue里this指向

Vue官网对Methods的解析

如何修复Vue中的 “this is undefined” 问题

对于一个Java程序员来说,真的需要了解下这个this的作用域,因为和Java的差别还是有点大的。因为Java中的this默认都是指向当前的类,但是 Vue的作用域是以函数为单位划分的

从上面的文章归纳总结就是:

  • methods中通过xxx:function(){} 或 xxx(){}的方式定常规义函数,默认的this都是指向外部的Vue对象
  • 箭头函数,无论是在methods中定义的函数,或者是methods的嵌套子函数,都是不存在this对象的,默认都是继承与父函数的this
  • 假若在methods的函数中嵌套子函数function xxx ,function xxx的this作用域是指代xxx函数内部,而不是外部的Vue对象

光说还有点绕,因为这边有几种情况需要做例子说明才好说明。因为涉及到普通methods定义以及箭头函数、子函数的定义处理。

这里划分四种情况:

  1. Vue->methods中使用常规函数
  2. Vue->methods中使用箭头函数
  3. Vue->methods中的常规函数,定义内部子常规函数(目前题主遇到的问题)
  4. Vue->methods中的常规函数,定义内部子箭头函数(这个)

按照上面的设想,我们写了一套测试代码,以及输出对应的验证效果,主要看代码注释就好了

Demo代码
        // DES: Vue下的methods函数
        methods:{
            outerFunction() {
                console.log("this is outer function")
            },
            innerFunction() {
                console.log("this is inner function");
                // DES: 调用Methods下的其他函数,因为Vue中默认methods的函数都会持有Vue实体对象,所以直接调用不会出现问题
                this.outerFunction();

                // DES: 调用Methods下的箭头函数
                this.arrowFunction();

                // DES: 创建_this成员变量,保存Vue对象的引用,常用于子函数调用vue对象的情况
                let _this = this;

                // DES: 内部子常规函数
                function testInnerNestedFunction() {
                    // DES: 因为刚刚说过,js的作用域是根据function定义的,所以这个this指向的是testInnerNestedFunction的this
                    console.log("子常规函数输出this:" + this);
                    console.log("子常规函数输出本地变量_this:" + _this);

                    // DES: 按照刚刚的说法,这个outerFunction就是undefined的了,因为this指向的是testInnerNestedFunction函数自身
                    this.outerFunction();
                }

                // DES: 内部子箭头函数,Es6定义的箭头函数是不存在this的,默认是继承父函数的this,即继承了innerFunction的this,即Vue对象
                let testInnerNestedArrowFunction = () => {
                    console.log("子箭头函数输出this:" + this);
                    console.log("子箭头函数输出本地变量_this:" + _this);

                    // DES: 因为继承this,所以直接调用outerFunction是没问题的
                    this.outerFunction();
                };

                // DES: 因为先调用testInnerNestedFunction的话会抛出异常,这里执行顺序先改变下
                testInnerNestedArrowFunction();
                testInnerNestedFunction();
            },
            arrowFunction: () => {
                // DES: 按照刚刚设想,这个this没有继承到Vue这个对象,所以this是undefined的
                console.log("Methods 箭头函数输出this:" + this);
                // DES: 因为这里会报错就先注释掉了
                //this.outerFunction();
            }
        }

输出结果如下:注意子函数的输出,再对比下代码会理解更加深刻

demo结果输出

所以this作用域的建议有这些
  • 假若Methods中函数的子函数需要调用Methods同级函数有几个办法
    1. Methods同级函数提取到export default节点下
    2. 子函数定义使用箭头函数
    3. Methods函数内通过let _this = this; 保存外部vue对象,然后子函数就使用_this的对象而不是this
  • Methods层级的函数不建议用箭头函数
  • Methods层级的函数的子函数尽量都用箭头函数,因为会默认继承Methods层级的this(Vue)对象

所以刚刚我的问题也很容易解决吧。把promise构造函数的函数调用改为箭头函数即可
Logo

前往低代码交流专区

更多推荐