热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

深入解析:JavaScript中的表达式与语句有何不同

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Javascript中:表达式和语句的区别相关的知识,希望对你有一定的参考价值。 Javascript中:表达式和语句的区别Javascript语言精

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Javascript中:表达式和语句的区别相关的知识,希望对你有一定的参考价值。




Javascript中:表达式和语句的区别

Javascript语言精粹:
表达式是由运算符构成,并运算产生结果的语法结构。
程序是由语句构成,语句则是由“;(分号)”分隔的句子或命令。
如果在表达式后面加上一个“;”分隔符,这就被称为“表达式语句”。它表明“只有表达式,而没有其他语法元素的语句”

 

原文:http://www.2ality.com/2012/09/expressions-vs-statements.html



本文要讲的是Javascript中非常重要的两个知识点:表达式(expressions)和语句(statements)之间的区别.


1.语句和表达式

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


myvar
3 + x
myfunc("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"));
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
NaN

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


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




 


 

 



推荐阅读
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • Docker的安全基准
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 本文详细介绍 Go+ 编程语言中的上下文处理机制,涵盖其基本概念、关键方法及应用场景。Go+ 是一门结合了 Go 的高效工程开发特性和 Python 数据科学功能的编程语言。 ... [详细]
  • Windows服务与数据库交互问题解析
    本文探讨了在Windows 10(64位)环境下开发的Windows服务,旨在定期向本地MS SQL Server (v.11)插入记录。尽管服务已成功安装并运行,但记录并未正确插入。我们将详细分析可能的原因及解决方案。 ... [详细]
  • 本文介绍了如何利用JavaScript或jQuery来判断网页中的文本框是否处于焦点状态,以及如何检测鼠标是否悬停在指定的HTML元素上。 ... [详细]
  • 本文详细介绍了如何在BackTrack 5中配置和启动SSH服务,确保其正常运行,并通过Windows系统成功连接。涵盖了必要的密钥生成步骤及常见问题解决方法。 ... [详细]
  • 导航栏样式练习:项目实例解析
    本文详细介绍了如何创建一个具有动态效果的导航栏,包括HTML、CSS和JavaScript代码的实现,并附有详细的说明和效果图。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
author-avatar
潘怡安淑华寧生
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有