Vue3中立即执行函数(IIFE)无法访问this的问题及方案咨询
问题解答
1. (function(){...})() 结构的本质
这个结构叫做立即调用函数表达式(IIFE, Immediately Invoked Function Expression):
- 外层的括号作用是把普通的函数声明转化为函数表达式,避免JS引擎把它识别成普通函数声明报错
- 末尾的
()就是执行这个函数的语法,和你定义完普通函数之后调用的func()作用完全一致,只是这个函数没有被赋值给变量,定义完就立刻执行。
绝大多数第三方库的示例代码用IIFE是为了创建独立的作用域,内部的变量不会污染外部作用域,所以你看到的Stripe示例会默认用这个结构包裹代码。
2. 内部this.myVar失效的原因
普通函数的this指向是调用时动态决定的,不是定义时决定的:
- 你在Vue组件的
myMethod里拿到的this是Vue组件实例,是Vue内部帮你把方法的this绑定到了实例上 - 而IIFE是全局直接调用的,没有绑定任何执行上下文,在严格模式下内部的
this默认是undefined,非严格模式下指向window,自然不可能拿到Vue组件实例上的myVar属性。
你碰到的参数默认值报错也是同一个逻辑:普通函数的参数默认值的this指向和函数内部的this是一致的,指向IIFE的this而不是外层的组件实例,所以读取this.myVar会直接报错。
3. 无需全局变量的解决方案
你可以任选以下任意一种方案替换原来的IIFE写法,都不需要额外定义全局变量:
方案1:用箭头函数写IIFE(最省事)
箭头函数没有自己的this,会直接继承外层作用域的this,也就是组件实例的this,直接就能访问到myVar:
methods: { myMethod() { console.log(this.myVar); // 输出 'foo' // 箭头函数版IIFE (() => { console.log(this.myVar); // 直接输出 'foo' // 这里写你的Stripe相关逻辑即可 })(); } }
方案2:给普通函数IIFE绑定外层this
用call方法把外层的组件实例this绑定到IIFE内部:
(function () { console.log(this.myVar); // 输出 'foo' }).call(this); // 把外层的this作为上下文传入
方案3:把需要的变量直接作为参数传入IIFE
如果只需要少数几个变量,可以直接当成实参传给IIFE:
// 把需要的变量在调用时传进去 (function (bar) { console.log(bar); // 输出 'foo' })(this.myVar); // 调用时把外层的this.myVar作为实参传入
内容的提问来源于stack exchange,提问作者Adrian Harris in London
相关产品推荐
相关产品推荐

