教程文档【免费下载链接】thejswayThe JavaScript Way book项目地址https://gitcode.com/gh_mirrors/th/thejsway点击查看免费下载本篇文章精读开源书籍 The JavaScript Way仓库源文件位于 manuscript/的第 2 章 chapter02.md。本章位于书籍导航的「Learn to code programs」板块见 mkdocs.yml解决的是程序如何存储数据并与用户交换信息这一核心问题从变量的声明、赋值、常量与作用域到表达式求值、模板字面量、隐式/显式类型转换再到prompt()/alert()实现的用户交互。学完本章你将能够用纯 JavaScript 写出提问—计算—应答的完整交互式小程序并掌握一套贯穿全书、可复用的变量命名规范。变量程序存储数据的基础变量的作用上一章chapter01.md已经教会你用console.log()向控制台输出值。但一个真正有用的程序必须能够存储数据例如保存用户输入的信息。计算机程序正是通过**变量variable**来存储数据的——可以把变量想象成一个信息存储盒程序在盒子里放入数据、读取数据、随时更换数据。变量的三个属性任何一个变量都具有三个主要属性名称name用于标识变量。变量名可以包含大小写字母、数字但不能出现在第一位以及美元符号$和下划线_。值value变量中实际存储的数据。类型type决定了变量的用途以及可以对其执行的操作。动态类型 vs 静态类型在 JavaScript 中你不必显式声明变量的类型——类型会根据变量中存储的值被自动推导出来并且在程序运行期间可能发生变化。正因如此JavaScript 被称为动态类型dynamically typed语言。而 C、Java 这类语言要求变量类型始终被显式定义这被称为静态类型static typing。动态类型带来灵活性的同时也要求开发者更谨慎地跟踪变量当前到底存的是什么类型的值。声明变量let关键字在往变量里存数据之前必须先创建它这个动作叫声明declaring。声明变量意味着计算机为该变量预留出一块内存之后程序就可以通过操作变量来读写这块内存中的数据let a; console.log(a);在 JavaScript 中用let关键字后跟变量名来声明变量。上例创建了一个名为a的变量执行结果如下注意结果是undefined。这是 JavaScript 的一种特殊类型表示没有值——我声明了变量a但并没有给它任何值。关于var过去 JavaScript 用var关键字声明变量。现在依然可以使用但在大多数场景下用let和const更简单也更安全两者的区别与作用域见下文。给变量赋值赋值运算符程序运行期间变量存储的值可以改变。要给变量赋予新值使用运算符它被称为赋值运算符assignment operatorlet a; a 3.14; console.log(a);这里我们通过赋值修改了变量a 3.14读作a 接收值 3.14。警告千万不要把赋值运算符和数学上的等号混淆在 JavaScript 中表达相等用的是另外的运算符——第 3 章 chapter03.md 会正式介绍比较运算符严格相等等到时你会看到与是两种截然不同的东西。声明变量和给变量赋值也可以合并成一行完成。只是要知道这一行里实际上同时做了两件事let a 3.14; console.log(a);声明常量const如果某个变量的初始值在整个程序运行期间都不会改变它就叫做常量constant。用const关键字代替let声明可以强制这种不变性程序表达力更强而且任何后续试图修改该常量的操作都会立刻被检测为错误const a 3.14; // a 的值不能被修改 a 6.28; // 不可能会报错在浏览器控制台中执行会得到类似Attempting to override a which is a constant.的报错递增数字变量和对于数字型变量可以用增加其值等价于自身加上某个数而被称为递增运算符increment operator每次让变量值增加 1。下面例子中第 2 行和第 3 行各把变量b的值加 1let b 0; // b 现在是 0 b 1; // b 现在是 1 b; // b 现在是 2 console.log(b); // 显示 2同理-、--分别对应减少和递减在第 2 章的练习「Final values」中你会实际用到a - 1这种写法。变量作用域块级作用域变量的**作用域scope是程序中该变量可见、可用的那部分区域。用let或const声明的变量是块级作用域block-scoped**的其可见性被限制在声明它的那个代码块以及所有子块内。在 JavaScript 中**代码块code block**是用一对花括号{ ... }界定的程序片段默认情况下整个 JavaScript 程序本身就是一个代码块let num1 0; { num1 1; // OKnum1 声明在父级块中 const num2 0; } console.log(num1); // OKnum1 声明在当前块中 console.log(num2); // 错误num2 在这里不可见注意上面的报错发生在运行期严格模式下甚至可能在解析期被工具检测到——这也是动态类型语言的一个特点许多错误要等代码真正执行才会暴露。本书配套的 ESLint 配置见 appendix02.md中的no-unused-vars规则就会在编辑阶段提醒这类声明了变量却从未使用的隐患。表达式产生值的代码表达式expression是一段能够产生值的代码它由变量、值和运算符组合而成。每个表达式都有值因而也有类型。计算表达式值的过程称为求值evaluation求值过程中变量会被替换为其当前值// c 是一个表达式其值为 3 const c 3; // d 是一个表达式其值为 c 的值这里为 3 let d c; // (d 1) 是一个表达式其值为 d 的值加 1这里为 4 d d 1; // d 现在包含值 4 console.log(d); // 显示 4运算符优先级与括号表达式内部的运算符优先级与数学中一致先乘除、后加减。但可以通过括号来改变这些优先级let e 3 2 * 4; // e 的值为 113 8 e (3 2) * 4; // e 的值为 205 * 4模板字面量Template literal可以在字符串中嵌入表达式用一对反引号界定字符串这样的字符串称为模板字面量template literal。在模板字面量内部表达式通过${expression}语法标识。这在构造包含某些变量值的字符串时非常常用const country France; console.log(I live in ${country}); // 显示 I live in France const x 3; const y 7; console.log(${x} ${y} ${x y}); // 显示 3 7 10类型转换隐式转换表达式求值可能引发类型转换这种转换是**隐式implicit**的——它自动发生无需程序员干预。例如在字符串和数字之间使用运算符会把两个值拼接成一个字符串结果const f 100; // 显示 Variable f contains the value 100 console.log(Variable f contains the value f);NaN转换失败的结果JavaScript 在类型转换上非常宽容但有时转换根本无法进行。如果某个值无法成功转换为数字你会得到NaNNot a Number非数字const g five * 2; console.log(g); // 显示 NaN显式转换Number()与String()有时你希望主动把一个值转换成另一种类型这叫**显式explicit**转换。JavaScript 提供Number()和String()命令分别把括号中的值转换为数字或字符串const h 5; console.log(h 1); // 拼接显示字符串 51 const i Number(5); console.log(i 1); // 数值加法显示数字 6这里藏着 JavaScript 初学者的经典陷阱5 1得到的是字符串51而不是数字6只有先通过Number(5)完成显式转换才会按数值加法运算。与用户交互有了变量程序就能与用户交换信息了。本章引入两个用于交互的命令prompt()负责输入alert()负责输出对话框形式。输入信息prompt()const name prompt(Enter your first name:); alert(Hello, ${name});执行时浏览器会弹出一个对话框询问你的名字。这是prompt(Enter your first name:)命令的结果输入名字并点击OK后你会收到一条个性化的问候整个流程的机制是你在第一个对话框中输入的值以字符串形式存入变量name随后alert()命令触发第二个对话框其中显示的是字符串Hello, 与变量name的值拼接后的结果这里恰好用到了模板字面量。显示信息alert()与console.log()console.log()上一章已介绍和alert()都可以向用户展示信息但两者有明显区别与alert()不同console.log()不会中断程序的执行因此在多数场景下是更好的选择本书 ESLint 配置中也将no-console规则关闭为允许见 appendix02.md。console.log()还可以一次显示多个逗号分隔的值const temp1 36.9; const temp2 37.6; const temp3 37.1; console.log(temp1, temp2, temp3); // 显示 36.9 37.6 37.1输入数字Number(prompt(...))无论用户输入什么prompt()命令总是返回字符串。如果要把输入用于数值计算就必须先用Number()把它转换成数字const input prompt(Enter a number:); // input 的类型是 string const nb Number(input); // nb 的类型是 number两步操作也可以合并成一行效果相同const nb Number(prompt(Enter a number:)); // nb 的类型是 number在这个例子中用户输入被Number()直接转换成数字值并存入变量nb。这正是第 3 章 chapter03.md 中const number Number(prompt(Enter a number:))这类惯用写法的源头——先转换、再比较避免字符串与数字参与运算时的隐式转换陷阱。变量命名让你的代码可读计算机其实根本不在乎变量名怎么起——你完全可以只用单个字母a、b、c……或者起burrito、puppieskittens90210这种离谱的名字。但是好的变量名能让代码可读性大幅提升。请看下面两个功能完全相同的例子const a 5.5; const b 3.14; const c 2 * a * b; console.log(c);const radius 5.5; const pi 3.14; const perimeter 2 * pi * radius; console.log(perimeter);两者的执行结果完全一样但第二个版本的含义一目了然。当变量代表比较复杂的含义例如游戏中预期的最高分时就不应该再用单个单词命名而应采用驼峰命名法camelCase除第一个单词外其余每个单词的首字母大写例如maxExpectedScore。本书将全程采用这一流行命名约定。本书的风格指南还给出了一些更具体的命名规则值得一并记住每个元素变量、函数、类等的名字都应具体且反映其职责存放圆半径的变量应叫radius而不是num或myVal简洁命名只应留给生命周期极短的元素如循环计数器。不要使用保留字JavaScript 的关键字如let、const、if等作为变量名。JavaScript区分大小写myVariable与myvariable是两个完全不同的变量名。函数名应包含动作动词如computeTotal()、findFirstParent()类名以大写字母开头如User数组可含多个元素用复数或List后缀命名如movies或movieListDOM 元素变量用Element后缀与普通变量区分。本章要点回顾TL;DR变量是一个信息存储区域每个变量都有名称、值、类型三个属性。JavaScript 中变量类型由存储的值推导而来因此它是动态类型语言。变量用let关键字加变量名声明要声明常量初始值永不改变用const关键字更合适。用赋值运算符给变量赋值对数字变量可增加其值可递增每次加 1。变量的作用域是程序中该变量可见的部分let或const声明的变量是块级作用域的。代码块是用一对花括号{ ... }界定的程序片段。表达式是组合变量、值和运算符的代码片段对表达式求值会产生一个带有类型的值。表达式可以嵌入到用一对反引号界定的字符串中这种字符串叫模板字面量。类型转换可能在表达式求值时隐式发生也可以通过Number()和String()命令显式执行分别得到数字或字符串。prompt()和alert()命令分别以对话框的形式处理信息的输入与显示。变量命名对程序可读性至关重要遵循 camelCase 这类命名约定是良好实践。动手练习Coding Time下面的练习是本章的配套实战环节。请在浏览器控制台或 CodePen 等在线 JS 环境中逐步验证练习过程中刻意养成先想好语义化命名再写代码的习惯——这比代码本身更值得训练。练习 1Improved hello改良问候编写一个程序询问用户的名字和姓氏然后把它们显示在同一句话中。const firstName prompt(Enter your first name:); const lastName prompt(Enter your last name:); console.log(Your name is ${firstName} ${lastName});练习 2Final values最终值预测观察下面的程序先预测各变量的最终值再运行验证你的判断let a 2; a - 1; a; let b 8; b 2; const c a b * b; const d a * b b; const e a * (b b); const f a * b / a; const g b / a * a; console.log(a, b, c, d, e, f, g);参考答案可在控制台验证逐步推算可得a 22 - 1 1后再回到 2、b 108 2、c 1022 10 * 10、d 302 * 10 10、e 402 * (10 10)、f 102 * 10 / 2、g 1010 / 2 * 2注意乘除同优先级、从左到右计算。这个练习直观地检验了你对-、、以及运算符优先级的理解。练习 3VAT calculation增值税计算编写一个程序询问用户一个不含税价格raw price然后按20.6%的增值税率计算出最终价格const rawPrice Number(prompt(Enter the raw price:)); const vatRate 0.206; const finalPrice rawPrice * (1 vatRate); alert(Final price: ${finalPrice});注意不要忘记Number()转换——如果漏掉rawPrice是字符串rawPrice * (1 vatRate)虽然会因为*的隐式转换碰巧得到数字但明确转换永远是更稳妥的写法。练习 4From Celsius to Fahrenheit degrees摄氏转华氏编写一个程序询问一个摄氏温度然后显示对应的华氏温度。换算公式为[°F] [°C] × 9/5 32。const celsius Number(prompt(Enter a temperature in Celsius:)); const fahrenheit celsius * 9 / 5 32; alert(${celsius}°C ${fahrenheit}°F);练习 5Variable swapping变量交换观察下面的程序在// TODO处添加代码只能在这里添加使number1和number2的值互换let number1 5; let number2 3; // TODO: type your code here (and nowhere else!) console.log(number1); // 应显示 3 console.log(number2); // 应显示 5这个练习有多个合法解法。最简单的做法是引入第三个临时变量let temp number1; number1 number2; number2 temp;先把number1的值暂存到temp再把number2赋给number1最后把暂存值赋给number2——这正是变量是存储盒这一比喻的经典应用。本章的内容量不大却是一切 JavaScript 程序的地基变量、表达式、类型转换和交互式输入输出几乎在后续每一章的示例中都会反复出现。下一章将基于这些能力引入条件执行if语句与比较运算符见 chapter03.md更多命名与代码质量规范可查阅风格指南。整个仓库以 Mkdocs 构建构建方式见 README.md 与 mkdocs.yml你可以随时在本地poetry shell poetry install mkdocs serve后于浏览器中翻阅全书。赞分享教程文档【免费下载链接】thejswayThe JavaScript Way book项目地址https://gitcode.com/gh_mirrors/th/thejsway点击查看免费下载相关推荐3分钟搞定国家中小学智慧教育平台电子课本下载终极指南3分钟搞定国家中小学智慧教育平台电子课本下载终极指南 还在为无法下载国家中小学智慧教育平台的电子课本而烦恼吗tchMaterial parser这款智能下载网页爬虫教育《The JavaScript Way》第 1 章精读3, 2, 1... Code——你的第一段 JavaScript 程序、值与类型、程序结构《The JavaScript Way》第 1 章精读3, 2, 1... Code——你的第一段 JavaScript 程序、值与类型、程序结构 本文是对开教程文档深入理解 JavaScript 面向对象编程class、原型链与委托实战The JavaScript Way 第 9 章精读深入理解 JavaScript 面向对象编程class、原型链与委托实战The JavaScript Way 第 9 章精读 本篇技术指南围绕开源书籍《T教程文档上一篇告别 PPT 演讲超时三步上手 PPTTimer 演示计时器完整指南下一篇3步搞定NCM格式转换ncmdumpGUI免费工具完整上手指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考