部分源码
const util$ = new Util();
const wxSelectorInfo = {
homeSearchButton: {
className: ClassNameType.RelativeLayout,
desc: "搜索",
depth: 13,
id: "com.tencent.mm:id/jha"
},
editText: {
className: ClassNameType.EditText,
text: "搜索",
depth: 11,
id: "com.tencent.mm:id/d98",
editable: true
},
editTextSearchButton: {
className: ClassNameType.Button,
text: "搜索",
depth: 11,
id: "com.tencent.mm:id/mdg"
},
visitWebButton: {
className: ClassNameType.Text,
text: "访问网页",
depth: 28
},
continueVisitButton: {
className: ClassNameType.Button,
text: "继续访问",
depth: 19
},
homeSerachSelectOption: {
className: ClassNameType.Text,
depth: 17,
id: "com.tencent.mm:id/ltk"
}
};
const findSelectorInfo = {
startReadButton: {
id: "readCtl",
className: ClassNameType.Text,
text: "开始阅读",
depth: 20
},
coinsText: {
id: "text2",
className: ClassNameType.Text,
depth: 19
},
urlText: {
className: ClassNameType.Text,
textStartsWith: "http://",
depth: 22
}
};
function CokeRead(appName, url, taskInterval, interval) {
this.taskInterval = taskInterval;
this.interval = interval;
this.appName = appName;
this.url = url;
this.coinsTotal = 0;
this.pageTotal = 0;
this.one_task_time = 5;
this.regex = /阅读第(\d+)篇成功,获得(\d+)币/;
}
CokeRead.prototype.start = function() {
this.interval = setInterval(() => {
util$.autoService(() => {
const flag = util$.openApp(this.appName);
if (!flag) {
return;
}
this.taskOne();
home();
});
}, this.taskInterval);
};
CokeRead.prototype.stop = function() {
clearInterval(this.interval);
console.log("CokeRead stop");
this.interval = 0;
};
CokeRead.prototype.openCokeRead = function() {
const wxhomeSearchButton = util$.findSelector(wxSelectorInfo.homeSearchButton);
if (!wxhomeSearchButton) return false;
util$.SelectorClick(wxhomeSearchButton);
util$.wait(2);
const editText = util$.findSelector(wxSelectorInfo.editText);
if (!editText) return false;
editText.setText(this.url);
util$.wait(2);
const homeSerachSelectOption = util$.findSelector(wxSelectorInfo.homeSerachSelectOption);
if (!homeSerachSelectOption) return false;
util$.SelectorClick(homeSerachSelectOption);
util$.wait(2);
const visitWebButton = util.findSelector(wxSelectorInfo.visitWebButton);
if (!visitWebButton) return false;
util$.SelectorClick(visitWebButton);
util$.wait(2);
const continueVisitButton = util$.findSelector(wxSelectorInfo.continueVisitButton);
if (!continueVisitButton) return false;
util$.SelectorClick(continueVisitButton);
util$.wait(2);
const startReadButton = util$.findSelector(findSelectorInfo.startReadButton);
if (!startReadButton) return false;
util$.SelectorClick(startReadButton);
util$.wait(2);
return true;
};
CokeRead.prototype.openUrlView = function() {
const urlText = util$.findSelector(findSelectorInfo.urlText);
if (!urlText) return false;
const url = urlText.text();
for (let i = 0; i < 3; i++) {
back();
}
const editText = util$.findSelector(wxSelectorInfo.editText);
if (!editText) return false;
editText.setText(url);
util$.wait(2);
const editTextSearchButton = util.findSelector(wxSelectorInfo.editTextSearchButton);
if (!editTextSearchButton) return false;
util$.SelectorClick(editTextSearchButton);
util$.wait(2);
const visitWebButton = util$.findSelector(wxSelectorInfo.visitWebButton);
if (!visitWebButton) return false;
util$.SelectorClick(visitWebButton);
util$.wait(2);
const continueVisitButton = util$.findSelector(wxSelectorInfo.continueVisitButton);
if (!continueVisitButton) return false;
util$.SelectorClick(continueVisitButton);
util$.wait(2);
return true;
};
CokeRead.prototype.taskOne = function() {
let flag = this.openCokeRead();
if (!flag) return;
flag = this.openUrlView();
if (!flag) return;
问题
我使用的vite构建的js,明明没有形参问题
结果报错:
形参后没有")"
回答
该报错是因为 Hamibot 脚本运行环境基于 Rhino 1.7.15 JavaScript 引擎,不支持 ES6 及以上的语法特性,尤其是箭头函数。报错信息“形参后没有')'"是 Rhino 解析箭头函数 => 时的典型错误。
问题原因
- 箭头函数不支持:代码中
this.interval = setInterval(() => { ... }, this.taskInterval);使用了箭头函数() => {}。Rhino 引擎无法识别=>符号,导致解析函数参数时出错。 - Vite 构建产物兼容性:Vite 默认面向现代浏览器构建,输出的代码通常包含 ES6+ 特性。即使源代码没有箭头函数,构建后的代码也可能包含。
- this 指向问题:将箭头函数改为普通函数后,
this的指向会发生变化,不再指向CokeRead实例,需要手动绑定。
解决方案
- 修改代码语法:将所有箭头函数改为标准
function表达式。 - 修正 this 指向:在函数外部保存
this引用(例如var self = this;),或在内部使用.bind(this)。 - 调整构建配置:如果必须使用 Vite,需配置 Babel 将目标环境设置为 ES5,确保输出代码不包含箭头函数、
const、let等特性(尽管 Rhino 支持部分const/let,但var最稳妥)。
修正后的代码示例
针对 CokeRead.prototype.start 方法的修正如下:
// 文档地址 https://docs.hamibot.com/
CokeRead.prototype.start = function() {
var self = this; // 保存 this 指向
this.interval = setInterval(function() {
// 普通函数内部 this 指向全局,需使用 self
util$.autoService(function() {
var flag = util$.openApp(self.appName);
if (!flag) {
return;
}
self.taskOne();
home();
});
}, this.taskInterval);
};
其他兼容性建议
在 Hamibot 脚本开发中,请遵循以下规范以避免类似报错:
- 禁用箭头函数:所有回调函数均使用
function() {}。 - 避免默认参数:函数定义不要使用
function(a = 1) {}语法。 - 变量声明:优先使用
var,虽然 Rhino 支持let/const,但var兼容性最好。 - 构建工具配置:若使用 Webpack 或 Vite,请配置
target: 'es5'并使用 Babel 插件@babel/preset-env确保转译完全。 - 检查构建产物:上传到 Hamibot 前,检查最终生成的 JS 文件是否仍包含
=>、class、import/export等语法。
建议直接在 Hamibot 编辑器中编写脚本,或使用构建工具时严格限制语法特性,确保输出代码符合 Rhino 1.7.15 规范。
ℹ️ 本回答由 AI 生成,内容仅供参考