关于javascript:语句和表达式有什么不同

5次阅读

共计 2994 个字符,预计需要花费 8 分钟才能阅读完成。

前言

JavaScript 中的语句和表达式有什么不同之处?

对于这个问题,我仿佛晓得答案,但当我尝试向他人解释时,我却语塞了。对于这个问题我有一种感觉,但无奈清晰的表达出来。

我起初才意识到,这个问题极其重要。它能够说是屋宇的承重墙,将有助于撑持大量的 JavaScript 常识。

对 React 开发者来说,更为如此。你不得不记住的那些 JSX 规定,以及总是遗记恪守的那些规定,大部分都是 语句 / 表达式 双重性的后果。

在这篇文章中,我将分享我对这两者区别的一些感悟,以及咱们如何在日常工作中应用这些信息。

表达式

从实质上来说,表达式是产生值的一段 JavaScript 代码。

上面所有的例子全部都是表达式:

  • 1 → 产生值为1
  • "hello" → 产生值为"hello"
  • 5 * 10 → 产生值为50
  • num > 100 → 产生值为 true 或者false
  • isHappy ? "🙂" : "🙁" → 产生值为一个 emoji
  • [1, 2, 3].pop() → 产生值为3

表达式能够蕴含其余表达式。举例来说,你感觉上面的 JS 代码中有多少个表达式?

(5 + 1) * 2

答案是一共有 5 个表达式。

具体来说,别离是以下 5 个:

  1. (5 + 1) * 2,这段代码自身就是表达式,产生的值为12
  2. (5 + 1),因为有括号,这个子表达式首先求值,并解析为6
  3. 5,单个数字自身就是表达式,因为它们产生一个值。这个表达式解析为5
  4. 1,同样的情理,这个表达式解析为1
  5. 2,这个数字造成最初的表达式,它解析为2

语句

一个 JavaScript 程序是一连串的语句。每条语句都是计算机做某件事的指令。

这里是无关 JavaScript 中语句的示例:

let hi = 5;
if (hi > 10) {// 更多语句}
throw new Error('报错了');

对于语句和表达式,我是这么认为的:语句是撑持咱们程序的刚性构造,而表达式则填充了细节。

语句中通常有表达式的 “ 插槽 ”。咱们能够把任何咱们喜爱的表达式放到这些插槽里。

举例来说,申明一个具备表达式插槽的变量能够这么做:

let hi = /* 表达式 */;

在这个插槽中,咱们能够应用任何先前看到过的表达式:

let hi = 1;
let hi = "hello";
let hi = 5 * 10;
let hi = num > 100;
let hi = isHappy ? "🙂" : "🙁";
let hi = [1, 2, 3].pop();

就无效语法而言,表达式是能够调换的。如果一个语句有一个表达式插槽,咱们能够把任何表达式放在那里,代码就会运行。并且咱们不会失去语法报错。

也就是说,咱们可能会遇到其余的问题。比如说,上面的代码在语法层面来说是无效的,但如果咱们尝试运行就会让浏览器解体,因为它会导致死循环:

while ("hello") {
    // 因为 "hello" 永不扭转,因而循环会一遍又一遍的反复,直到脚本解体。// 语法上是无效的,但仍是有问题的。}

便捷技巧

想晓得一段 JS 代码到底是语句还是表达式吗?试着将它打印进去吧!

console.log(/* 这里是 JS 代码 */);

如果可能运行,该代码就是表达式。如果报错,那就是语句(当然,也有可能是非法 JS)。

此外,咱们甚至能够看到表达式的后果,因为会将后果打印到浏览器的控制台中。

这样能够凑效是因为任意函数的参数都必须是表达式。表达式会产生一个值,并将该值传递到函数中。语法并不会产生一个值,因而语句不能被用作函数的参数。

即便作为一个有教训的开发者,我也十分依赖console.log。它真的是一个好货色。

表达式作为语句

这是一个表达式:1 + 2 + 3

如果咱们创立一个只包含这个表达式的 JS 文件,会产生什么?让咱们试想把上面的内容保留为test.js

1 + 2 + 3

该文件中有多少个语句?0 个还是 1 个?

事件是这样的:表达方式不能独自存在。它们总是语句的一部分。所以在这种状况下,咱们有一个看起来像这样的语句:

/* 表达式插槽 */

除了表达式插槽之外,该语句基本上是空的。表达式 1 + 2 + 3 填充了该插槽,那么语句也就生成了。

换句话说,以下所有行都是无效的语句:

// 语句 1:
let hi = /* 表达式插槽 */;
// 语句 2:
return /* 表达式插槽 */;
// 语句 3:
if (/* 表达式插槽 */) { }
// 语句 4:
/* 表达式插槽 */

通常状况下,某些教程会谬误地指出,表达式就是语句,但这并不完全正确。表达式和语句是不同的货色。然而语句有可能在不提供任何额定字符的状况下包裹住表达式。这就如同用通明的保鲜膜包裹住一个三明治。

语句通常以分号结尾,它标记着语句的完结。对某些语句来说分号不是必须的,如 if 语句、while循环和函数申明。

React 中的实际

如果你曾应用过 React,你可能晓得大括号 {}容许咱们在 JSX 中嵌入一些 JavaScript,就像这样:

function CountdownClock({secondsRemaining}) {
  return (
    <div>
      Time left:
      {Math.round(secondsRemaining / 60)} minutes!
    </div>
  );
}

这就是 React 的神奇之处,它能够让咱们领有 JavaScript 的全副能力。

但有一个问题 — 咱们不能在大括号外面搁置任意 JavaScript 代码。具体来说,咱们只能包含表达式,而不能包含语句。大括号实质上是在咱们的 JSX 中创立一个表达式插槽。

如果咱们尝试在大括号内嵌入一个语句,比如说 if/else 语句,咱们会失去谬误:

function CountdownClock({secondsRemaining}) {
  return (
    // 🚫 语法报错
    <div>
      {if (secondsRemaining > 0) {`${secondsRemaining} seconds left`
      } else {"Time expired!"}}
    </div>
  );
}

这是因为语句不会产生值,只有表达式才会产生值。如果咱们想在 JSX 中嵌入 if/else 逻辑,咱们须要应用一个三元操作符表达式:

function CountdownClock({secondsRemaining}) {
  return (
    // ✅ 没问题
    <div>
      {secondsRemaining > 0
        ? `${secondsRemaining} seconds left`
        : "Time expired!"
      }
    </div>
  );
}

这仿佛是一个诡异的 JSX/React 限度,但它实际上是一个 JavaScript 限度。

我想咱们常常嗔怪 React 的一些看似果断的规定,比方组件必须返回一个顶层元素。但更多的时候,React 只是在正告咱们一个对于 JavaScript 的限度。

了解语句和表达式的区别是十分重要的。咱们还须要理解 JSX 是如何编译成 JavaScript 的,以及 React 的调度与渲染周期是如何工作的 …… 然而,这些话题曾经超出了本篇文章的范畴。

总结

一个 JavaScript 程序由一连串的语句组成。每个语句都是做某件事的指令,比如说,创立一个变量,运行一个 if/else 条件语句,或者开始一个循环。

表达式产生一个值,这些值被放入语句的插槽内。表达式始终是语句的一部分,即便该语句是空的。例如,上面的代码在运行一个循环时没有应用 for 语句,但它依然蕴含一个”通明保鲜膜”语句:

data.forEach(item => console.log(item));

这种区别可能须要一段时间能力变得不言而喻,心愿这篇文章能够帮忙到你。

以上就是本文的所有内容,欢送点赞珍藏转发~

正文完
 0