zoukankan      html  css  js  c++  java
  • 代码之谜(二) 语句与表达式

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

    简单的讲

    • “表达式”(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"} 

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

    {
    	"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(函数式编程)的一些核心思想了。


  • 相关阅读:
    箭头函数中的this
    剑指offer(十六) 合并两个排序的链表
    http中的referer
    剑指offer(十四,十五)链表中倒数第k个结点,反转链表
    剑指offer(十二,十三) 数值的整数次方,调整数组顺序使奇数位于偶数前面
    那些短小精悍的&奇葩的&令人感到惊讶的JavaScript代码----更新中
    对箭头函数的补充
    Promise和Async/Await用法整理
    Vue父子组件互相通信实例
    Vue实例里面的data属性为什么用函数返回
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6468276.html
Copyright © 2011-2022 走看看