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

上述两个定义又包含多种情况,说起来有些复杂,所以我画了张草图(可能不准确,以文档为准):

http://files.gracecode.com/2010_03_10/1268192678.png

所以,上面的表达式不符合 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
类型发生了变化了

渔隐: 
用!== 和===吧

明城: 
不纠结了,以后记得逻辑表达式里千万不要加一元操作符
或者加括号

沉鱼: 
有个比较有效的做法,不太记得操作符的优先级时,我都
加(),这样虽然比较挫,不过保险

崇厚: 
不管记得不记得优先级,表达式比较复杂时最好都加括号
这样看起来清晰一些

举一反三,以后如果再碰到类似的问题,我们可以:

  1. 查文档。ECMAScript 规范MDC 中的文档、甚至 Google 都是我们的好帮手
  2. 如果还是无法理解,可以“偷懒”先看运行结果,然后逆向推断
  3. 团队的力量胜过一个人闭门造车

-- EOF --

已有 8 条评论

  1. 顶ls的。

  2. 顶楼下的

  3. 最后那三点是王道。呵呵。

  4. the Captain the Captain

    文章我就收藏了,温故知新吗。 TXH!!!

  5. 很有帮助,特别是“先看运行结果,然后逆向推断” 若工作不是单纯研究js, 别那么纠结那些怪癖的写法。

  6. 坚持才是王道,多看书练习

  7. 恩,是啊,是的多学习,不知道有这么多的学问呢

  8. JAVA这个东西就是难懂。

添加新评论




* Required (but your email address will never be published)

Yahoo 统计