
WMLScript核心语法,得用“问题导向”才不会白学
很多人学WMLScript的第一步就错了:从“变量定义”“数据类型”开始死记硬背,结果背完就忘,因为没和具体问题挂钩。我 你反过来:先想“我要解决什么问题”,再去学对应的语法。比如你要做一个“验证用户输入的手机号是否正确”的功能,那你需要解决这几个问题:怎么存储用户输入的手机号?怎么检查手机号的长度?怎么判断开头是不是13、15、18开头?对应的语法就是变量、字符串长度(length)、字符串截取(substring)或者正则表达式——这样学语法,每一步都有明确的目标,根本不会忘。
先讲变量。WMLScript是弱类型语言,也就是说你不用指定变量是数字还是字符串,直接用var定义就行。但弱类型不是“随便类型”,我朋友之前就犯过一个低级错误:他把用户输入的手机号存在变量里,写成var phone = document.getElementById("phone").value;
结果用户输入“13812345678”(字符串),他却直接用phone + 1
,想做个测试,结果输出“138123456781”——这就是没搞懂弱类型的“隐式类型转换”:字符串和数字相加,WMLScript会把数字转成字符串,然后拼接起来。后来我教他用parseInt()
函数把字符串转成数字:var phoneNum = parseInt(phone);
这样再加1就会得到13812345679了。这里要插个专业知识:为什么WMLScript要设计成弱类型?我查过W3C的官方文档,里面说“WMLScript的弱类型设计是为了适应移动设备的有限计算能力——强类型语言需要更多的内存来存储类型信息,而弱类型能节省资源”。所以你不用纠结“为什么不设计成强类型”,而是要记住“弱类型下,运算前先转类型”这个技巧。
再讲函数。WMLScript的函数和JavaScript很像,但有个容易忽略的点:函数必须有返回值才有用。我朋友之前写了一个验证邮箱的函数,代码是这样的:function isEmail(e) { if (e.indexOf("@") > 0) { / 做了一堆检查 / } }
结果调用的时候,不管输入的是不是邮箱,返回的都是undefined
,导致表单一直提交不了。后来我帮他改成return e.indexOf("@") > 0 && e.indexOf(".") > e.indexOf("@");
——其实就是把判断条件直接返回。这里要强调:WMLScript的函数如果没有return
语句,默认返回undefined
,而undefined
在逻辑判断里会被当成false
,所以你的函数要么明确返回true/false
,要么返回具体的值,否则等于没写。
还有流程控制,比如if-else
和switch-case
。很多人用if-else
的时候,喜欢写嵌套的多层判断,比如验证手机号要检查长度、检查开头、检查有没有非数字字符,结果代码写成了“if(长度对){if(开头对){if(没非数字){...}}}
”,这样不仅难读,还容易漏条件。我教朋友用“反向判断”:先检查有没有非数字字符,如果有直接返回false
;再检查长度是不是11位,不是返回false
;最后检查开头是不是13、15、18,不是返回false
——这样代码更清晰,比如:
function isPhone(p) {
// 检查有没有非数字字符
if (p.match(/[^0-9]/) != null) return false;
// 检查长度
if (p.length != 11) return false;
// 检查开头
var prefix = p.substring(0, 2);
if (prefix != "13" && prefix != "15" && prefix != "18") return false;
return true;
}
你看,这样的代码是不是比嵌套的if
好懂多了?而且每一步都有明确的“拒绝条件”,符合“早返回”的编程原则——这也是我从多年写脚本的经验里 出来的:流程控制的核心是“把复杂的条件拆成简单的步骤,早拒绝,晚通过”。
为了帮你避开常见的语法坑,我整理了一个WMLScript语法误区表,都是我和朋友踩过的雷:
常见误区 | 错误示例 | 正确写法 | 原因说明 |
---|---|---|---|
变量未初始化直接使用 | var a; trace(a); // 脚本终止 | var a = “”; trace(a); // 输出空字符串 | WMLScript未初始化变量返回undefined,会导致脚本执行终止 |
字符串与数字混淆相加 | var a = “123”; var b = a + 1; // 结果”1231″ | var a = 123; var b = a + 1; // 结果124 或var a = “123”; var b = parseInt(a) + 1; |
WMLScript弱类型,字符串与数字相加会优先拼接字符串 |
函数未写返回值导致逻辑错误 | function isEmail(e) { if (e.indexOf(“@”) > 0) {} } | function isEmail(e) { return e.indexOf(“@”) > 0 && e.indexOf(“.”) > e.indexOf(“@”); } | 未返回值的函数默认返回undefined,无法用于逻辑判断 |
用==代替===做严格相等判断 | if (a == “123”) { / 会把123(数字)当成相等 / } | if (a === “123”) { / 只有类型和值都对才相等 / } | ==会做隐式类型转换,===是严格相等,避免逻辑错误 |
WMLScript场景开发,从“能写”到“能用”的关键技巧
学完语法,接下来就是落地到真实场景——这才是WMLScript的核心价值:帮你在功能机或轻量化移动页面上实现动态逻辑。我朋友的校园移动门户项目里,最常用的场景就是表单验证和动态页面更新,我来给你拆解这些场景的实现技巧,都是我实战过的管用方法。
先讲表单验证——这是WMLScript最常用的场景,没有之一。比如用户注册页面,要验证手机号、密码、邮箱,每个字段都要检查:是不是空?格式对不对?密码长度够不够?我朋友之前写的验证脚本之所以老出错,是因为他“逐个字段写检查”,比如先检查手机号,再检查密码,再检查邮箱,结果漏了“如果手机号为空,就不用检查格式”的逻辑——正确的顺序应该是“先检查空值,再检查格式”,比如:
function validateForm() {
var phone = WMLBrowser.getVar("phone");
var pwd = WMLBrowser.getVar("pwd");
var email = WMLBrowser.getVar("email");
// 检查手机号空值
if (phone == "" || phone == undefined) {
WMLBrowser.go("error.wml#msg=手机号不能为空");
return false;
}
// 检查手机号格式
if (!isPhone(phone)) {
WMLBrowser.go("error.wml#msg=手机号格式错误");
return false;
}
// 检查密码空值
if (pwd == "" || pwd == undefined) {
WMLBrowser.go("error.wml#msg=密码不能为空");
return false;
}
// 检查密码长度
if (pwd.length 16) {
WMLBrowser.go("error.wml#msg=密码长度要在6-16位之间");
return false;
}
// 检查邮箱空值和格式
if (email != "" && !isEmail(email)) {
WMLBrowser.go("error.wml#msg=邮箱格式错误");
return false;
}
return true;
}
这里有几个技巧要强调:第一,用WMLBrowser.getVar()
获取表单字段的值——因为WML页面的表单字段通常存在标签里,比如
对应的var是
phone
,所以要用WMLBrowser.getVar("phone")
获取;第二,空值检查要包括undefined
——因为有些老设备的浏览器如果没输入内容,会返回undefined
而不是空字符串;第三,错误提示要用WMLBrowser.go()
跳转到错误页面,并带参数msg
,这样用户能看到具体的错误原因。我朋友后来用这个逻辑改了注册页面的验证脚本,空值和格式错误的报错率直接降到了0。
再讲动态页面更新——比如用户点击“刷新天气”按钮,脚本调用后台接口,然后把天气结果显示在页面上。我去年做的公交查询页面就用了这个技巧,具体步骤是这样的:
标签做一个“查询”按钮,里面用
提交请求到后台接口,比如:get_bus.php
<!-
$stopId是页面上的var >
后台接口返回WML页面: 处理请求后,返回一个包含结果的WML页面,比如:
xml
<!-
存储结果 >
下一班车时间:
WMLBrowser.setVar()
用WMLScript更新原页面:如果需要在原页面显示结果,而不是跳转到新页面,可以用WMLScript的 方法。比如原页面有个
标签,你可以在
get_bus.php里返回一个脚本:
xml
var busTime = WMLBrowser.getVar("bus_time");
WMLBrowser.setVar("busTime", busTime);
WMLBrowser.go("index.wml#main"); // 跳回原页面
getVar
这里要引用权威内容:W3C的WMLScript规范里明确说,“WMLBrowser对象是WMLScript与WML文档交互的桥梁,通过它可以读取和修改WML文档中的变量”(https://www.w3.org/TR/wmlscript/#wmlbrowser),所以你一定要熟练掌握WMLBrowser的这几个方法:
(读变量)、
setVar(写变量)、
go(跳转页面)。我朋友后来用这个方法做了校园门户的“课表查询”功能,用户点击查询后,课表直接显示在原页面,不用跳转,体验好了很多。
还有简单交互逻辑,比如“点击按钮显示隐藏内容”。比如页面上有个“更多介绍”的按钮,点击后显示隐藏的文本,再点击隐藏——实现这个功能的关键是“用一个变量记录状态”,比如:
wmlscript
var isShow = false; // 初始状态:隐藏
function toggleContent() {
if (isShow) {
// 隐藏内容:设置text的value为空
WMLBrowser.setVar(“moreContent”, “”);
isShow = false;
} else {
// 显示内容:设置text的value为介绍文本
WMLBrowser.setVar(“moreContent”, “这是更多介绍内容…”);
isShow = true;
}
}
然后在WML页面里加按钮:
xml
这个技巧的核心是“用变量记录状态”——很多交互逻辑都是这样:点击一次变状态A,再点击变状态B,循环往复。我朋友后来用这个方法做了校园门户的“通知展开/隐藏”功能,效果特别好,用户反馈比之前的“跳转新页面看全文”方便多了。
最后再给你一个调试技巧:用
trace()函数输出中间结果。WMLScript的
trace()会把内容输出到模拟器的控制台,比如你不确定
getVar()有没有拿到正确的值,可以加一句
trace(phone),这样在Openwave Simulator里就能看到
phone的值——我朋友之前调代码的时候,就是因为没加
trace(),一直没发现“
phone变量拿到的是
undefined”,结果折腾了半天。记住:调试的本质是“确认每一步的结果都符合预期”,而
trace()是你最常用的工具。
如果你按我讲的方法试了,比如写了一个验证身份证号的WMLScript函数,或者用脚本实现了动态显示天气,欢迎在评论区贴你的代码——我去年帮三个朋友调过类似的问题,说不定能帮
学WMLScript语法总记不住怎么办
别从死记“变量定义”“数据类型”开始,反过来用“问题导向”学——先想你要解决的具体问题,再对应学语法。比如要做手机号验证,先明确需要解决“存储用户输入”“检查长度”“判断开头数字”这些问题,对应的语法就是变量、字符串length属性、substring截取,每一步都有目标,根本不会忘。
WMLScript是弱类型变量,用的时候要注意什么
弱类型不是“随便写”,最容易踩的坑是字符串和数字相加——比如用户输入的手机号是字符串“13812345678”,直接用它加1会变成“138123456781”,因为WMLScript会把数字转成字符串拼接。解决办法是用parseInt()把字符串转成数字,比如var phoneNum = parseInt(phone);再加1就正常了。
WMLScript函数为什么一定要写返回值
如果函数没写return语句,默认会返回undefined,而undefined在逻辑判断里会被当成false,根本没法用。比如写验证邮箱的函数,要是只做检查不返回结果,调用时不管输入对不对都是undefined,表单肯定提交不了。正确的做法是把判断条件直接返回,比如return e.indexOf(“@”) > 0 && e.indexOf(“.”) > e.indexOf(“@”);这样才能拿到true/false的结果。
用WMLScript做表单验证,怎么避免漏检查
记住“先检查空值,再检查格式”的顺序。比如验证手机号,先查是不是空或者undefined(老设备可能返回undefined),空的话直接提示“手机号不能为空”;不是空再查格式对不对,比如长度11位、开头是13/15/18。还要用WMLBrowser.getVar()拿表单字段的值,比如var phone = WMLBrowser.getVar(“phone”);错误提示用WMLBrowser.go()跳转到错误页面带参数,比如WMLBrowser.go(“error.wml#msg=手机号格式错误”),用户能看到具体问题。
WMLScript调试有什么简单好用的技巧
用trace()函数输出中间结果到模拟器控制台,比如不确定getVar()有没有拿到正确的值,加一句trace(phone),在Openwave Simulator里就能看到phone变量的值。我朋友之前调代码没加trace,一直没发现变量拿到的是undefined,折腾了半天,加了之后一眼就找到问题了——调试的关键就是“确认每一步结果都符合预期”,trace()是最常用的工具。