使用ES6、AngularJS与Babel构建应用时this被转为_this的问题
解决AngularJS服务转译时的代码截断与this绑定问题
嘿,我看你遇到了两个关联的问题:转译后代码被截断,还有this被替换成_this导致服务方法失效。咱们一步步来解决:
1. 先搞定this变成_this的问题
你这里犯了一个AngularJS service的常见错误:用箭头函数来定义服务构造函数。
AngularJS的service方法会把你传入的函数当作构造函数,用new关键字去实例化它——这时候this应该指向服务的实例对象。但箭头函数没有自己的this,它会“劫持”外层上下文的this(在严格模式下这里外层this是undefined),所以Babel转译时会把this换成_this,结果就是你的reloadWindowSize方法根本挂不到服务实例上。
修复很简单:把服务定义的箭头函数换成普通函数就行:
'use strict'; module.exports = (ngModule) => { ngModule.service('$ui', function() { // 这里换成普通函数 /* * 触发窗口resize函数。 * */ this.reloadWindowSize = () => { $(window).resize(); }; }); };
这样当AngularJS实例化服务时,this就会正确指向服务实例,转译后的代码也不会出现_this的问题了。
2. 解决转译后代码截断的问题
转译后出现ngModul...这种不完整的代码,大概率是转译过程中遇到了无法处理的语法或者错误,导致Babel提前终止了转译。结合你的代码来看,最可能的原因是//#region这种VS Code专用的区域折叠注释——旧版本的Babel(比如你用的7.1.4)对这种注释的支持不太好,容易触发转译中断。
排查和修复步骤:
- 先试试移除
//#region和//#endregion这两行注释,重新转译看看。如果代码完整了,那就是这个注释的锅,要么换成普通的多行注释,要么考虑添加babel-plugin-transform-strip-comments插件来处理这类注释。 - 检查你的Babel配置(比如
.babelrc或者webpack里的babel-loader选项),确保配置了正确的预设。Babel7的预设是@babel/preset-env,你的配置应该类似这样:
{ "presets": [ ["@babel/preset-env", { "targets": { "browsers": ["last 2 versions", "ie >= 11"] } }] ] }
- 确认Webpack的babel-loader规则正确覆盖了你的服务文件,没有被排除在外:
module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } } ] }
- 最后检查代码有没有其他语法错误,比如遗漏的分号、括号不匹配,这些小问题也可能导致转译中途崩溃。
验证修复
修改完之后重新运行Webpack,看看输出的代码是否完整。然后在你的AngularJS应用里注入$ui服务,调用$ui.reloadWindowSize()测试一下,应该就能正常工作了。
内容的提问来源于stack exchange,提问作者Redplane
相关产品推荐
相关产品推荐

