代码之谜(二)- 语句与表达式

news/2025/2/26 21:46:56

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

虽然文章标题是『语句与表达式』,在这篇文章中,我将陈述一个观点 每个表达式都有一个值。 在此之外,也会继续表述这个『代码之谜』系列的主题——数学与计算机之间被经常忽略的矛盾。

简单的讲

  • “表达式”(expression)是一个单纯的运算过程,总是有返回值;
  • “语句”(statement)是执行某种操作,没有返回值。

使用表达式也是函数式编程语言所提倡的,而传统命令式编程语言都是语句的堆砌。

表达式和语句如何区分呢? 最简单最直观的鉴别方法就是, 后面有分号的是语句, 这是一个充分条件而不是必要条件。 有分号,就是语句;没有分号,就不一定了,也可能是语句,也可能是表达式。

在动态语言——比如javascript——中是通过上下文来区分这两者的。

假如如果 function foo(){} 在一个赋值表达式的一部分,则认为它是一个表达式。 表达式的一部分,也是表达式。 而如果 function foo(){} 被包含在一个函数体内,或者位于程序中,则将它作为一个语句。

function foo(){}; // 声明,因为它是程序的一部分
var bar = function foo(){}; // 表达式,因为它是赋值表达式的一部分

new function bar(){}; // 表达式,因为它是New表达式的一部分

(function(){
	function bar(){}; // 声明,因为它是函数体的一部分
})();

还有一种不那么显而易见的表达式,就是被包含在一对圆括号中—— (function foo(){})。 将这种形式看成表达式同样是因为上下文的关系: (和)构成一个分组操作符,而 分组操作符只能包含表达式

(function foo(){}); // 函数表达式:注意它被包含在分组操作符中
(var x = 5);  // error! 分组操作符只能包含表达式,不能包含语句(这里的var就是语句)

今天突然有人问我:

alert(eval(data));

为什么会报错呢?data 是一个对象,按理说应该会弹出 ObjectObject 啊。 这是因为,当我们写

{"username" : "justjavac"} 

时,它并不是一个对象。 因为我们知道有一种表示数据的方法叫做 jsonjavascript对象表示法), 所以想当然的认为这应该是一个对象。 其实,在大部分编程语言中,大括号({})表示的不是对象,而是代码块,这段代码其实等价于

{
	"username" : "justjavac"
}

很显然,"username" : "justjavac" 并不是合法的语句。 然而解决方法也很简单,就是添加括号——分组操作符

({"username" : "justjavac"})

这样就构成了一个合法的表达式,当我们进行 json 对象解析的时候可以写如下代码:

eval('(' + json + ')')

在表达式中,只能存在表达式,不能存在语句。

例如表达式

(var a = 4) + 4;

这段代码将产生一个错误,因为 var a = 4 是一个语句, 而不是表达式—— 对表达式求值必须返回值,但对语句求值则未必有返回值

类似的

if (var a = 0) {}

也产生错误,因为 var a = 0' 是一条语句,而 **语句没有返回值**。if 语句的语法结构为

if (expression) {
    statement;
    statement;
    ……
}

因此

if (var a = 0) {}

是错误的,但是

if (true) {
    var a = 0;
}

则是正确的。

最后重申一下,每个表达式都有一个值。 理解了这个,就可以很容易的理解 FP(函数式编程)的一些核心思想了。

转载于:https://my.oschina.net/justjavac/blog/87552


http://www.niftyadmin.cn/n/605967.html

相关文章

python ---- 字符串

python ---- 字符串 #字符串截取 #s "hqelloASd" #print(s[0:3]) #print(s[:]) #print(s[::2])#去空格(去左右空格) #print(s.strip()) #print(s.lstrip()) #print(s.rstrip())#字符串复制 #s_copy s #print(id(s)) #print(id(s_copy)) #s s.title() #print(s…

利用客户端XSLT样式表转换xml文档

function StorePage() { ddocument; td.selection?(d.selection.type!None?d.selection.createRange().text:):(d.getSelection?d.getSelection():); void(keyitwindow.open(http://www.365key.com/storeit.aspx?tescape(d.title)&uescape(d.location.href)&cescap…

server中创建了学生表 已知在sql_SQL试卷

1. 在SQL Server中,假定grade(成绩)表中包含字段:cid(班级编号)、lang(语文课成绩)、math(数学课成绩)、eng(英语课成绩),那么计算不同班级每门课程的平均成绩的SQL语句是( )。A. SELECT cid,AVG(lang,math,eng) FROM grade GROUP BY lang,ma…

使用node创建服务器 运行vue打包的文件

vueproject打包操作 npm build vue project打包之后默认在dist目录下编译生成静态资源 如果想在正式部署前测试,可以依赖node-static直接运行 安装node-static依赖 npm install -g node-static 或者编写node脚本 在根目录下新建node-static-start.js var static re…

SVN精确地控制目录访问权限的经验总结

作者:朱金灿来源:http://blog.csdn.net/clever101忙活半天,才实现了SVN精确地控制目录访问权限。事情的缘由是这样的:系统主要分为两部分:核心层和扩展层。扩展层的开发人员不允许访问核心层代码,这个嘛&am…

python---面向对象

python-----面向对象 编程语言的发展:机器语言 汇编语言 高级语言(面向过程的c) 面向对象(c Java python) 类:对具有相同属性和方法的抽象 对象:具有属性和方法的实物 床前明月光 疑是地上霜 举…

有关VS.NET的安装部署(2)--打包数据库的安装与配置

前面所介绍的有关VS.NET的安装部署,只是简单的打包应用程序,往往在制作安装包时需要连数据库的安装一起打包到安装程序中.而且还要自定义一个用户界面,让用户在安装时输入数据库的配置信息(服务器名,数据库名,登陆用户,密码),用安装程序创建数据库,同时配置应用程序的配置文件.…

mysql自定义排序

场景 业务需要,优惠券列表要求按类型进行排序,但是,类型并不是顺序的,即order by是解决不了问题的 建表 CREATE TABLE custom_sort (id int(20) NOT NULL AUTO_INCREMENT,name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8m…