JavaScript中:表达式和语句的区别[译]


Posted in Javascript onSeptember 17, 2012

1.语句和表达式

JavaScript中的表达式和语句是有区别的.一个表达式会产生一个值,它可以放在任何需要一个值的地方,比如,作为一个函数调用的参数.下面的每行代码都是一个表达式:

myvar3 + xmyfunc("a", "b")语句可以理解成一个行为.循环语句和if语句就是典型的语句.一个程序是由一系列语句组成的.JavaScript中某些需要语句的地方,你可以使用一个表达式来代替.这样的语句称之为表达式语句.但反过来不可以:你不能在一个需要表达式的地方放一个语句.比如,一个if语句不能作为一个函数的参数.

2.其他语法

看看下面这两对类似的语法,搞懂这些后,能够帮助我们更好的理解语句和表达式之间的关系.

2.1 If语句和条件运算符
下面是一个if语句的例子:

var x; 
if (y >= 0) { 
x = y; 
} else { 
x = -y; 
}

类似if语句功能的表达式叫做条件运算符.上面的语句等价于下面的.

var x = (y >= 0 ? y : -y);

在等于号=和分号;之间的代码就是条件表达式.两边的小括号不是必需的,但我觉得小括号能让条件表达式更易读.

2.2 分号和逗号运算符
在JavaScript中,使用分号可以连接两个语句:

foo(); bar()要想连接两个表达式,使用的是不常见的逗号运算符:

foo(), bar()逗号运算符会计算前后两个表达式,然后返回右边表达式的计算结果.例如:

> "a", "b" 
'b' > var x = ("a", "b"); 
> x 
'b' 
> console.log(("a", "b"));

3.看似语句的表达式

一些表达式看起来像是语句,这可能会带来一些麻烦.

3.1 对象字面量和语句块
下面是一个对象字面量,也就是一个可以生成一个对象值的表达式.

{ 
foo: bar(3, 5) 
}

不过同时,它也是一个完全合法的语句,这个语句的组成部分有:

•一个代码块:一个由大括号包围的语句序列.
•一个标签:你可以在任何语句前面放置一个标签.这里的foo就是一个标签.
•一条语句:表达式语句bar(3, 5).
你也许会感到震惊,那就是JavaScript居然可以有独立的代码块(常见的代码块是依托于循环或者if语句的).下面的代码演示了这种代码块的作用:你可以给它设置一个标签然后跳出这个代码块.

function test(printTwo) { 
printing: { 
console.log("One"); 
if (!printTwo) break printing; 
console.log("Two"); 
} 
console.log("Three"); 
} 
> test(false) 
One 
Three 
> test(true) 
One 
Two 
Three

3.2 函数表达式和函数声明
下面的代码是一个函数表达式:

function () { }你还可以给这个函数表达式起一个名字,将它转变为一个命名(非匿名)的函数表达式:

function foo() { }这个函数的函数名(foo)只存在于函数内部,比如,可以用它来做递归运算:

> var fac = function me(x) { return x <= 1 ? 1 : x * me(x-1) } 
> fac(10) 
3628800 
> console.log(me) 
ReferenceError: me is not defined

一个命名的函数表达式从表面上看起来,和一个函数声明并没有什么区别.但他们的效果是不同的:一个函数表达式产生一个值(一个函数).一个函数声明执行一个动作:将一个函数赋值给一个变量. 此外,只有函数表达式可以被立即调用,函数声明不可以.

3.3 解决冲突
从3.1和3.2可以看出,有些表达式和语句在表面上看不出有什么区别.也就意味着,相同的代码,出现在表达式上下文和出现在语句上下文会表现出不同的作用.通常情况下,这两种上下文是没有交集的.但是,如果是表达式语句的话,会有一个重叠:也就是说,会有一些表达式出现在语句上下文上.为了解决这种歧义,JavaScript语法禁止表达式语句以大括号或关键字"function"开头:

ExpressionStatement : 
[lookahead ∉ {"{", "function"}] Expression ;

那么,如果你想写一个以那些标志开头的表达式语句,该怎办呢? 你可以把它放在一个括号内部,这样并不会改变运行结果,只会确保该表达式被解析在表达式上下文中.让我们看两个例子.第一个例子:eval会按照语句上下文解析它的参数.如果你想让eval返回一个对象,你必须在对象字面量两边加上一个括号.
> eval("{ foo: 123 }") 
123 
> eval("({ foo: 123 })") 
{ foo: 123 }

第二个例子:下面的例子是一个立即执行的函数表达式.
> (function () { return "abc" }()) 
'abc'

如果你省略了小括号,你会得到一个语法错误(函数声明不可以是匿名的):
> function () { return "abc" }() 
SyntaxError: function statement requires a name

如果你添加上函数名,还会得到一个语法错误(函数声明不能被理解执行):
> function foo() { return "abc" }() 
SyntaxError: syntax error

另外一个能让表达式在表达式上下文上被解析的办法是使用一元运算符,比如 + 或者 !.但是,和使用括号不同的是,这些操作符会改变表达式的运行结果.如果你不关心结果的话,完全可以使用:

> +function () { console.log("hello") }() 
hello 
NaNNaN

是+作用在函数执行后的返回值undefined上的结果.

译者注:我觉的没翻译明白,所以用拙劣的水平画了张图.

JavaScript中:表达式和语句的区别[译]
原文(英文):http://www.2ality.com/2012/09/expressions-vs-statements.html 

Javascript 相关文章推荐
使用onbeforeunload属性后的副作用
Mar 08 Javascript
jQuery 处理网页内容的实现代码
Feb 15 Javascript
用XMLDOM和ADODB.Stream实现base64编码解码实现代码
Nov 28 Javascript
JS多物体 任意值 链式 缓冲运动
Aug 10 Javascript
Javascript图像处理—亮度对比度应用案例
Jan 03 Javascript
js setTimeout 常见问题小结
Aug 13 Javascript
Javasipt:操作radio标签详解
Dec 30 Javascript
巧用jquery解决下拉菜单被Div遮挡的相关问题
Feb 13 Javascript
JavaScript验证18位身份证号码最后一位正确性的实现代码
Aug 07 Javascript
详解js中常规日期格式处理、月历渲染和倒计时函数
Dec 28 Javascript
表格展示利器 Bootstrap Table实例代码
Sep 06 Javascript
Vue页面切换和a链接的本质区别详解
Nov 12 Javascript
JavaScript取得鼠标绝对位置程序代码介绍
Sep 16 #Javascript
JavaScript高级程序设计 阅读笔记(二十一) JavaScript中的XML
Sep 14 #Javascript
IE6-IE9不支持table.innerHTML的解决方法分享
Sep 14 #Javascript
javascript时区函数介绍
Sep 14 #Javascript
推荐40个简单的 jQuery 导航插件和教程(下篇)
Sep 14 #Javascript
推荐40款强大的 jQuery 导航插件和教程(上篇)
Sep 14 #Javascript
基于JQuery的一句话搞定手风琴菜单
Sep 14 #Javascript
You might like
如何使用PHP中的字符串函数
2006/10/09 PHP
php读取文件内容至字符串中,同时去除换行、空行、行首行尾空格(Zjmainstay原创)
2012/07/31 PHP
PHP实现通过中文字符比率来判断垃圾评论的方法
2014/10/20 PHP
[原创]网络复制内容时常用的正则+editplus
2006/11/30 Javascript
浅谈javascript 面向对象编程
2009/10/28 Javascript
js 变量类型转换常用函数与代码[比较全]
2009/12/01 Javascript
jQuery 获取对象 根据属性、内容匹配, 还有表单元素匹配
2010/05/31 Javascript
学习并汇集javascript匿名函数
2010/11/25 Javascript
js实现鼠标悬浮给图片加边框的方法
2015/01/30 Javascript
原创jQuery弹出层插件分享
2015/04/02 Javascript
javascript insertAfter()定义与用法示例
2016/07/25 Javascript
Vue.js表单标签中的单选按钮、复选按钮和下拉列表的取值问题
2017/11/22 Javascript
JavaScript设计模式之代理模式简单实例教程
2018/07/03 Javascript
解决vue2.0 element-ui中el-upload的before-upload方法返回false时submit()不生效问题
2018/08/24 Javascript
setTimeout与setInterval的区别浅析
2019/03/23 Javascript
使用nodejs分离html文件里的js和css详解
2019/04/12 NodeJs
ES6 Generator基本使用方法示例
2020/06/06 Javascript
JS highcharts动态柱状图原理及实现
2020/10/16 Javascript
HTML元素拖拽功能实现的完整实例
2020/12/04 Javascript
详解Python中的各种函数的使用
2015/05/24 Python
Python编程中装饰器的使用示例解析
2016/06/20 Python
Python引用传值概念与用法实例小结
2017/10/07 Python
Python实现的拟合二元一次函数功能示例【基于scipy模块】
2018/05/15 Python
python调用staf自动化框架的方法
2018/12/26 Python
浅谈Python小波分析库Pywavelets的一点使用心得
2019/07/09 Python
python已协程方式处理任务实现过程
2019/12/27 Python
使用PyTorch将文件夹下的图片分为训练集和验证集实例
2020/01/08 Python
python Timer 类使用介绍
2020/12/28 Python
用python批量下载apk
2020/12/29 Python
Html5实现移动端、PC端 刮刮卡效果
2016/06/30 HTML / CSS
韩国知名的家庭购物网站:CJmall
2016/08/01 全球购物
Spanx塑身衣官网:美国知名内衣品牌
2017/01/11 全球购物
纽约通行卡:The New York Pass(免费游览纽约90多个景点)
2017/07/29 全球购物
工作检讨书500字
2014/10/19 职场文书
2016年习主席讲话学习心得体会
2016/01/20 职场文书
在NumPy中深拷贝和浅拷贝相关操作的定义和背后的原理
2022/04/14 Python