Re:新手虚心求教March 10, 2010
经常有朋友邮件过来咨询技术问题,本人不才经常不是忘记回复就是回复的比较迟。原因是一来本人比较懒(或者可以托词为忙),二来是怕“误人子弟”。
当回复这位仁兄的邮件时,不觉得就发现回复的字数越来越长,于是就将其整理为篇 Blog。我的意图是不仅仅帮忙解决问题,而且能提供个解决类似问题的思路。
邮件原文
来自: Captain
时间: 2010-02-28 20:41
话题: 新手虚心求教
你好,我是刚刚入门学习Javascript的新手。我想向你请教一下我在学习过程中所
遇到的一个问题。恕我愚昧,但是我一直无法理解,恳请赐教。
我在学习中碰到过一条这样的声明: var !myVariable != variableValue, 因为在
以前的学习中知道双重否定等于可定,那这则声明是否可以理解成 var myVariable =
variableValue ?
若非如此解释,恳求正解。冒昧打扰请多多包涵。我的回复
不好意思,收到你的来信到现在才回复。第一眼看见您提供的代码,个人觉得它不合乎语法规则
var !myVariable != variableValue
根据 ECMA 相关的文档,var 关键字的定义在 12.2 章节(我看的是第五版),它的语法定义是:
var VariableDeclarationList ;
而 VariableDeclarationList 包括
VariableDeclarationList , VariableDeclaration
上述两个定义又包含多种情况,说起来有些复杂,所以我画了张草图(可能不准确,以文档为准):

所以,上面的表达式不符合 var 语句的定义要求,因此 Javascript 解析器会报语法错误。
如果是非赋值定义语句,也就是
!myVariable != variableValue
那么就是个条件判断语句,其中有两个条件判断操作符“非(!)”以及“不等于(!=)”,那么我们就要了解它们的结合优先级。
根据相关的参考文档,我们可以得知“非”操作符的优先级比“不等于”要高,因此语句先计算 !myVariable 这块,然后再计算“不等于”后的值。
至于能否改成其他等同的逻辑情况,这里还有个问题就是值取“非”的时候会有多种情况,这里有个讨论:
明城: 问: !a != b 是否等于 b == !!a 崇厚: 这个还要看数据类型吧? 比较运算符的优先级是最低的 渔隐: 照这样推理就是a == b 了 崇厚: a = '' b = 0 console.log(!a != b) console.log(b == !!a) true true 明城: 关键还有个“非”操作符,所以 B 始终是和布尔值对比的 崇厚: 我试出来三个结果 t t t f f f 痴灵: var a = 0; console.log(!a);console.log(typeof(!a),typeof(a)); true boolean number 类型发生了变化了 渔隐: 用!== 和===吧 明城: 不纠结了,以后记得逻辑表达式里千万不要加一元操作符 或者加括号 沉鱼: 有个比较有效的做法,不太记得操作符的优先级时,我都 加(),这样虽然比较挫,不过保险 崇厚: 不管记得不记得优先级,表达式比较复杂时最好都加括号 这样看起来清晰一些
举一反三,以后如果再碰到类似的问题,我们可以:
- 查文档。ECMAScript 规范、MDC 中的文档、甚至 Google 都是我们的好帮手
- 如果还是无法理解,可以“偷懒”先看运行结果,然后逆向推断
- 团队的力量胜过一个人闭门造车
-- EOF --
顶ls的。
顶楼下的
最后那三点是王道。呵呵。
文章我就收藏了,温故知新吗。 TXH!!!
很有帮助,特别是“先看运行结果,然后逆向推断” 若工作不是单纯研究js, 别那么纠结那些怪癖的写法。
坚持才是王道,多看书练习
恩,是啊,是的多学习,不知道有这么多的学问呢
JAVA这个东西就是难懂。