JavaScript基础教程(五)输出:不只是console.log!JavaScript输出全攻略,90%的人不知道的骚操作

JavaScript的输出方法远不止console.log,不同场景需选用不同输出策略。

1. 控制台输出家族

console.log('%c带样式的输出', 'color: red; font-size: 20px;')
console.table([{name: 'John', age: 30}])
console.dir(document.body) // DOM对象详细结构

console.debug()/info()/warn()/error()提供了多级日志分类,配合过滤器和格式化字符可实现高级调试。

2. 页面内容输出对比

// 危险:重写整个文档
document.write('<h1>仅适用于同步加载</h1>')

// 推荐:精准更新
document.getElementById('app').innerHTML = '<b>安全更新</b>'

// 现代方案
targetElement.insertAdjacentHTML('beforeend', '<li>新项目</li>')

3. 警告与用户交互

// 阻塞式警告(慎用)
alert('立即中断用户操作')

// 非阻塞提示
Toast.show('操作成功') // 第三方库实现

4. Node.js环境特殊输出

process.stdout.write('无换行输出')
console.clear() // 清空控制台

5. 异步输出的陷阱

// 异步操作后的输出可能错过DOM加载期
setTimeout(() => {
  document.write('此时加载会导致页面重绘') 
}, 1000)

最佳实践:生产环境应使用日志库统一管理输出,开发阶段善用console的丰富API,页面输出优先使用DOM操作方法,避免使用阻塞式alert。

理解不同输出方式的底层机制,能在调试效率、用户体验和代码维护性之间找到最佳平衡。

auto.waitFor(); toast("开始查找价格控件..."); // 统一提取数字函数(只定义一次) function extractNumber(text) { if (!text) return null; let match = String(text).match(/[\d.]+/); return match ? parseFloat(match[0]) : null; } // === 第一步:获取售卖价格 === let sellingPriceWidget = id("tv_selling_price_value") .className("android.widget.TextView") .findOne(5000); let sellingPrice = null; if (sellingPriceWidget) { let rawText = sellingPriceWidget.text(); sellingPrice = extractNumber(rawText); console.log("✅ 售卖价格文本:", rawText, " -> 提取值:", sellingPrice); } else { toast("❌ 未找到售卖价格控件"); } // === 第二步:获取最低租金 === let lowestRentWidget = id("tv_lowest_rent_price") .className("android.widget.TextView") .findOne(5000); let lowestRent = null; if (lowestRentWidget) { let rawText = lowestRentWidget.text(); lowestRent = extractNumber(rawText); console.log("✅ 最低租金文本:", rawText, " -> 提取值:", lowestRent); } else { toast("❌ 未找到最低租金控件"); } // === 第三步:获取当前选中分类中的数字(如月租、底价等)=== let parentWidget = id("item_category_ll") .className("android.view.ViewGroup") .clickable(true) .selected(true) .findOne(5000); let categoryPrice = null; if (parentWidget) { console.log("✅ 找到选中的分类容器"); let children = parentWidget.children(); for (let i = 0; i < children.length; i++) { let child = children[i]; let text = child.text() || child.desc(); if (text) { let num = extractNumber(text); if (num !== null) { console.log(`📌 分类子控件 [${i+1}]: "${text}" → 数值: ${num}`); // 假设我们取第一个有效数字作为该分类的价格参考 if (categoryPrice === null) { categoryPrice = num; } } } } } else { toast("⚠️ 当前无选中分类"); } // === 第四步:综合比价分析 === if (sellingPrice !== null && lowestRent !== null && categoryPrice !== null) { toast("📊 开始比价分析..."); console.info(`📊 售卖价: ${sellingPrice}, 最低租金: ${lowestRent}, 分类价格: ${categoryPrice}`); let rentMultiple = sellingPrice / lowestRent; if (sellingPrice < lowestRent) { toast("✅ 售价低于最低租金!可能存在错误或促销"); console.warn("⚠️ 异常:售卖价 < 最低租金"); } else if (rentMultiple > 3) { toast(`🚨 售价是最低租金的 ${rentMultiple.toFixed(1)} 倍!`); console.error(`🚨 风险提示:售价远高于租金,注意资产回报率`); } else { toast("🟢 价格关系正常"); } // 对比分类价格与最低租金 if (Math.abs(categoryPrice - lowestRent) < 0.01) { toast("🔖 分类价格等于最低租金,状态一致"); } else { toast(`🔍 分类价格 (${categoryPrice}) ≠ 最低租金 (${lowestRent})`); } } else { toast("⚠️ 数据完整,无法完成比价"); console.warn("缺失数据:", { sellingPrice, lowestRent, categoryPrice }); } auto.waitFor(); // 等待无障碍服务启动 // 显示提示 toast("正在查找选中的分类项..."); // 查找符合条件的父控件 let parentWidget = id("item_category_ll") .className("android.view.ViewGroup") .clickable(true) .selected(true) .findOne(5000); // 最多等待5秒 if (!parentWidget) { toast("❌ 未找到已选中的分类容器"); console.error("未找到满足条件的控件:id=item_category_ll, clickable=true, selected=true"); exit(); } console.log("✅ 成功找到选中的分类容器:", parentWidget); // 获取所有直接子控件 let children = parentWidget.children(); if (children.length === 0) { toast("⚠️ 该容器没有子控件"); console.warn("容器 children 数量为 0"); exit(); } // 存储提取出的数字 let numbers = []; // 提取数字的通用函数 function extractNumber(text) { if (!text) return null; let match = String(text).match(/[\d.]+/); // 匹配连续的数字和小数点 return match ? parseFloat(match[0]) : null; } // 遍历每个子控件 for (let i = 0; i < children.length; i++) { let child = children[i]; let text = child.text() || child.desc() || ""; // 尝试文本、描述(Accessibility Desc) console.log(`🔍 子控件 [${i + 1}] 类型: ${child.className()}, 文本: "${text}"`); // 如果有文本或描述,尝试提取数字 if (text.trim() !== "") { let num = extractNumber(text); if (num !== null) { console.log(`🎉 提取到数字: ${num}`); numbers.push(num); } } } // 输出结果 if (numbers.length > 0) { toast(`✅ 共提取到 ${numbers.length} 个数字`); console.info("提取的所有数字:", JSON.stringify(numbers)); // 可选:返回最大值、最小值、平均值等 let minNum = Math.min(...numbers); let maxNum = Math.max(...numbers); let sumNum = numbers.reduce((a, b) => a + b, 0); let avgNum = sumNum / numbers.length; console.log("📊 统计信息:"); console.log(` 最小值: ${minNum}`); console.log(` 最大值: ${maxNum}`); console.log(` 平均值: ${avgNum.toFixed(2)}`); } else { toast("❌ 在子控件中未找到任何数字"); console.warn("未能从子控件中提取有效数字"); } 然后这三个脚本合并
11-10
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

值引力

持续创作,多谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值