JavaScript 语言基础 — 在浏览器里跑起来的 PHP 近亲
JavaScript 语言基础 — 在浏览器里跑起来的 PHP 近亲
这一章讲什么: 从 PHP 跨到 JavaScript。好消息是这两者刻意长得像, 七成内容是对照复习;要新学的三成也摆得清清楚楚:DOM(浏览器把整张页面变成可编程对象)、 弱类型的另一面(变量类型随赋值飘)、var/let/const 三代声明规则。 读之前需要本组 02–04;你会一路看到「这和 PHP 一样」和「注意,这里不一样」两种路标。
1. 顶层全景:代码在哪个世界跑
PHP: 跑在服务器 ──▶ 浏览器只收 HTML(看不见 PHP 代码)
JS: 跑在浏览器 ──▶ 代码随页面一起到用户手里,能看到、能调试、能改
同一棵家族树(C 系语法)
表达式 / if / switch / while / for / === ← 与 PHP 几乎逐字相同
拼接用 + 不是 . 逻辑符只有 && || ! ← 小差异
弱类型 + truthy/falsy + var/let/const ← JS 自己的地盘
DOM: document → links → mylink → href ← 全新的世界记住这个定位差异,很多「为什么 JS 这样设计」就通了:你的代码在陌生人的浏览器里裸奔, 所以它没有文件操作、没有数据库直连,它的全部权力就是——操作它面前这张页面。
2. 出场与运行环境(原书第 13 章前半)
JavaScript 1995 年随 Netscape Navigator 登场;名字蹭 Java 的热度是营销, 两门语言除了表面语法之外没有血缘1。JavaScript 引擎每个现代浏览器都内置; Node.js 是同一门语言「脱离浏览器」的运行环境(第 21 章讲)2。
代码进页面的三条路:内联在 <script> 标签里;外链 <script src="script.js"></script>
(被引入的文件不能再含 script 标签);框架类库进 <head>,
业务代码放 </body> 之前——等 DOM 加载完再动手3。禁用 JS 的访客由
<noscript> 标签承接,至少告诉他「本站需要 JavaScript」4。
输出与调试:对应 PHP 的 echo 的是 console.log(...)——输出进浏览器的控制台
(F12 打开),不是页面本身5。console 是个对象,log 是它的方法——
「对象.方法」这个写法,是 JS 世界的地基语法6。
调试习惯的迁移值得单独说一句:PHP 出错会把错误直接印在页面上(第 3 章的 Parse error 你躲都躲不掉);JavaScript 出错只进控制台,页面表面若无其事—— 学了 PHP 转 JS 的人最大的不适应就是「代码没反应」,而真相往往是控制台里躺着一行红字。 Safari 用户要先在 偏好设置→高级 里打开「开发者功能」,才能用 Cmd-Opt-C 唤出控制台7。 养成肌肉记忆:页面行为不对,先看控制台,再看代码。
分号:一行一条语句时,换行符充当分号,可以全省;一行多条就必须用分号隔; 拿不准就加——末尾那句 "when in doubt, use a semicolon" 是原书原话8。
注释:和 PHP 的 //、/* */ 完全同源(都从 C 继承);不能嵌套;
函数文档惯例叫 JSDoc(/** ... @param ... */)9。
3. 变量:没有 $,有 let 和 const
JS 变量不用 $ 开头,合法字符是字母、数字、下划线和 $(对,$ 合法——
方便从 PHP 移植代码,但原书不建议保留,因为 jQuery 把 $ 占作自家别名)10。
字符串单双引号都行,同类引号用反斜杠转义;数字直接赋值;数组用方括号字面量
(['bat', 'ball', ...]),下标从 0 起,二维数组就是数组套数组11。
运算符对照速览(和第 4 章 PHP 版并排记):
| 事项 | PHP | JavaScript |
|---|---|---|
| 字符串拼接 | . 和 .= | + 和 += |
| 相等比较 | ==/=== | ==/===(同样推荐 ===) |
| 逻辑与或 | &&/and | 只有 &&(没有 and/or 拼写版,没有 xor) |
| 复合赋值 | += -= .= | += -=(+= 遇字符串自动当拼接) |
+= 的自动分派值得停一秒:count += 1 在数字上是加,name += " Dean" 在字符串上是拼接——
同一个运算符按两边类型自动选语义,这是弱类型语言的典型手感12。
弱类型现场直播(例 13-2,JS 版):
n = '838102050' // 字符串
console.log(typeof n) // string
n = 12345 * 67890 // 参与乘法,变成数字(值恰好同为 838102050)
console.log(typeof n) // number
n += ' plus some text' // 拼接,又变回字符串
console.log(typeof n) // string同一个变量三次赋值三种类型,typeof 当场作证13。想强制转换:
n *= 1(转数字)、n += ""(转字符串),或函数版 parseInt/parseFloat/toString14。
两个 typeof 的坑:typeof null 和 typeof [] 都返回 "object"——查类型前先知道这两个例外15。
4. 作用域三代:var / let / const
这是 JS 与 PHP 最不一样、也最容易出 bug 的地带,原书给了完整的对照:
function test() {
a = 123 // 全局!——函数里不用 var/let/const 赋值 = 全局(反模式)
var b = 456 // 函数级局部
if (a == 123) var c = 789 // var 无视块:{} 里的 var 照样函数级
}
test()
console.log(typeof a) // "number" —— a 漏出去了
console.log(typeof b) // "undefined" —— b 被关住var 的两大毛病:①函数里裸赋值成全局;②无视块边界——if 块里 var 的变量, 块外照样活着。于是有了两个新关键字16:
把例 13-5 的作用域实验走到底,每个变量的「逃没逃出去」都有据可查:
function test() {
a = 123 // 没带关键字 → 直接挂到全局
var b = 456 // var → 函数级,出了函数没有
if (a == 123) var c = 789 // var 无视 {} → 其实还是函数级
}
test()
console.log(typeof a) // "number" ——逃出去了(打印 a 会得 123)
console.log(typeof b) // "undefined" ——被关住了(没逃)
console.log(typeof c) // "undefined" ——也被关住了(但它其实"不该"活过 if 块)注意 typeof 不存在的变量 不报错、返回字符串 "undefined"——
这就是 JS 里替代 PHP isset 的探法17。
读法:typeof b != 'undefined' 为假,就是「b 不存在」。
let ≈ 理智版 var:同样声明变量,但块级作用域——{ } 里 let 的变量,
出了块就消失;同一块内不许重复声明(var 可以,这正是 obscure bugs 的温床)。
原书的对比实验:var 版里 if 块重声明 hello 会覆盖外层的值;换成 let,
块里那个 hello 只在块内可见,外面还是原值17。
const:声明时必须赋初值,之后再赋值直接报错(Uncaught TypeError:
Assignment to constant variable)。但注意细节:const array = [1,2]; array.push(3) 可以——
const 锁的是「变量指向谁」,不是「那个对象内部怎么变」;array = [4,5,6] 才报错18。
一张表收拢三代:
| var | let | const | |
|---|---|---|---|
| 作用域 | 全局/函数 | 全局/块 | 全局/块 |
| 声明时不初始化 | 可以 | 可以 | 不行 |
| 重复声明 | 可以 | 同块不行 | 不行 |
| 声明后再赋值 | 可以 | 可以 | 不行 |
原书的总建议:新代码用 let 和 const,别再用 var16。
5. DOM:页面即对象(原书第 13 章后半)
DOM(Document Object Model,文档对象模型)是浏览器把 HTML 文档转成的对象树——
每个标签是一个对象,有属性(数据)和方法(动作),沿层级排列:
document 是根,往下分出 body、links、images……19。
原书的名片比喻很好用:对象 card 有属性 card.name、card.phone,
有方法 card.display();「对象.属性」「对象.方法()」——
回头再看 console.log,log 就是 console 对象的方法20。
顺着这棵树读页面(例 13-6):
<a id="mylink" href="mysite.com">Click me</a>
<script>
url = document.links.mylink.href // 沿树下行:文档→链接集合→这条链→href 属性
console.log('The URL is ' + url) // The URL is mysite.com/
</script>两种等价写法:document.links.mylink.href(沿树)和 mylink.href
(id 直接当变量名,简写)。也有数组式访问:document.links[0].href(第 0 条链接),
配合 document.links.length 就能 for 循环扫出全站链接21。
history 对象:浏览器历史。history.length 是条数(出于隐私,
你只能数有几条,读不出内容是哪些——防的就是网站偷窥你浏览过什么);
history.back()、history.forward()、history.go(-3) 在会话历史里穿梭;
document.location.href = 'http://google.com' 把当前页换成任意地址22。
6. 表达式与控制流:七成像,三成异(原书第 14 章)
第 14 章几乎就是第 4 章的 JavaScript 复读,但复读里埋着几处必考的差异。
6.1 真与假的写法不同
PHP 打印布尔:TRUE→1、FALSE→空串;JavaScript 直接打印:
console.log(42 > 3) 输出 true,console.log(8 === 2) 输出 false——
看得见的小写字母23。大小写是硬规矩:true/false 必须小写,
TRUE 会直接报错「TRUE is not defined」24。
falsy 全家桶(在 if/while 的条件里被当 false 的):字符串 "false"、
0、-0、空串 ""、null、undefined、NaN(Not a Number,非法浮点运算的结果,比如除以零)25。
其余全 truthy——包括空数组 [] 和非零数字。Boolean(x) 可以把任何值显式转布尔验货26。
6.2 === 的规矩和 PHP 一致,连教训都一样
== 比较时 JS 也自动转型:0 == "" 为真(空串被转成 0);
=== 关掉了这个行为。原书的建议原话:「always use the strict equality
operators === and !== as they are more safe」——和第 4 章 PHP 那节一字不差的立场27。
6.3 短路求值:同一个坑,两边都讲
|| 和 && 都是短路运算:finished === 1 || getnext() === 1 里,
finished 一旦为 1,getnext() 根本不会被调用——和第 4 章 PHP 那节完全同款。
修法也一样:先调用存变量,再进条件28。
6.4 错误捕获:JS 的 try...catch 与 PHP 用途不同
JS 运行错误默认直接抛进控制台。两个兜法:全局的 onerror(老派,
连语法错误也能接);局部的 try { ... } catch(err) { ... } finally { ... }
(只管运行期错误,语法错误管不着——那还得 onerror)。典型场景:
操作一个不存在的元素时优雅降级,而不是整个脚本暴死29。
6.5 条件语句:没有 elseif,但不需要
if / else if / else 链完全同 PHP——只是 JS 没有 elseif 这个合并写法,
else if(两个词)是它的全部。switch 同 PHP:case/break/default 一个不少,
fall-through 同样靠「忘写 break」或「故意叠 case」发生30。
三元 a <= 5 ? "short" : "long",同一家人31。
6.6 循环:for...of 是新面孔
while / do...while / for 三兄弟结构与 PHP 完全一致(初始化;条件;更新);
for (i = 1, j = 1; i < 10; i++, --j) 的逗号多变量也一致。
新增:for...of 直接遍历数组的值——for (let value of [1,2,3]),
不用下标32。break(出整圈)与 continue(出本轮)的语义不变;
原书多给了一条浏览器特有的警告:JS 死循环会冻住页面,Escape 都未必救得回来——
循环变量别忘更新33。
6.7 显式转换:函数代替 cast
PHP 的 (int)$x 在 JS 不存在;用函数:parseInt(n, 10)(第二个参数是进制,
永远写上 10,防八进制意外)、parseFloat、Boolean、String、split(字符串转数组)34。
6.8 第 14 章的一页差异清单
把「JS 版控制流和 PHP 不一样的地方」压成一张小抄,接手代码时都用得上:
- 布尔打印得出
true/false小写字母,PHP 打印1/空串23。 TRUE大写直接报错;falsy 全家七个:"false"、0、-0、""、null、undefined、NaN25。- 逻辑运算符没有 and/or/xor 拼写版,只有
&&||!。 ==照样隐式转型(0 == ""为真),===依旧是默认答案27。- 多分支没有
elseif关键字,写else if两个词30。 - 循环家族多了
for...of直接取值;死循环会冻住浏览器,不是悄悄超时3233。 - 错误兜底两层:onerror(含语法错误)/ try...catch(只管运行错误,有 finally)29。
- 转类型没有
(int)这种 cast,只有函数;parseInt 永远带第二参数 1034。 - 短路求值两边同款:
||/&&的右操作数可能根本不执行28。
这九条之外的控制流内容(优先级、括号、switch 的 break、三元的形态、 while/do/for 的分工),和第 4 章 PHP 版完全同构,可以放心迁移—— 这也是原书把两章安排成「先 PHP 后 JS 镜像」的全部用意。
7. 两章合一的主线例子:页面里的一次完整「摸」
把散例收拢成一段能在浏览器里跑的完整走查(linktest.html 的精神续作):
<body>
<a id="mylink" href="mysite.com">Click me</a>
<script>
const links = document.links // ① 拿到页面上所有链接的对象集合
let report = "" // ② let:块外的累计变量
for (let j = 0; j < links.length; ++j) {
const url = links[j].href // ③ 逐条读 href(const:循环内不重建名的常量)
if (url === "mysite.com/") { // ④ === 严格比较
report += "Found mysite at " + j // ⑤ + 拼接
break // ⑥ 找到即停
}
}
console.log(report || "not found") // ⑦ || 短路:空串当 false,回退默认文本
</script>
</body>每一步都踩着本章的机制:① DOM 集合、② let 声明、③ 数组式访问、④ === 纪律、 ⑤ + 拼接、⑥ break、⑦ || 短路回退。这段能默写,两章就到手了。
7.1 再加一根梁:错误兜底叠进同一走查
把第 14 章的错误捕获叠进同一个例子,看它如何不打断主流程:
try {
const links = document.links
// ……上面 ①—⑥ 原样……
}
catch(err) {
console.log("出错了:" + err.message) // 元素缺失/笔误 → 接住,页面其余部分照常
}
finally {
console.log("扫描完成") // 无论成败都打这一行
}try 包住「可能翻车的段落」,catch 兜底,finally 收场——
与第 10 章 PDO 连接的 try...catch 同款结构,只是这里接的是浏览器脚本错误。
语法错误(少个括号这类「代码根本没跑起来」)不在这条防线内,
那是 onerror 和编辑器该管的事29。
8. 作者的判断与证据
| 书中的说法 | 成色 | |---|---|---| | 用 ===/!==,「更安全,== 只在极少数场合」 | 规范性建议,与 PHP 章节及业界共识三处一致;0 == "" 的例子是机制级证据27 | | 「when in doubt, use a semicolon」 | 风格裁决,理由(换行分号的例外情形)真实存在;最终听团队的8 | | 新代码用 let/const,弃 var | 时代共识,var 的两个毛病(全局泄漏、无视块)是语言设计史公认的缺陷16 | | document.write 不进生产代码 | 一致的行业立场,理由(加载后调用整页覆盖)机制清楚35 | | typeof null / typeof [] 返回 "object" 属「意外结果」 | 机制事实 + 承认坑,诚实的表述;这俩是 JS 类型系统最著名的历史遗留15 | | JS 死循环会让浏览器假死 | 用户可感的实证,比 PHP 死循环(只是服务器超时)的后果更重,Warning 给得对33 | | 「框架进 head,业务代码垫底」的摆放 | 通行最佳实践,理由是等 DOM 就绪——第 19 章的交互代码都按此摆放3 | | 数组按引用传进函数(例 13-4 注释) | 机制事实,一句带过没有展开——与 PHP 按值传数组形成对照,接手两边代码时值得专门记36 |
9. 边界与局限
- "use strict" 没出现:严格模式是理解 var/作用域问题的另一半钥匙,原书用 let/const 绕过而非讲解——够用,但读老代码遇到严格模式报错会缺一块背景。
- DOM 只讲了 links/history/location 一角:getElementById、事件监听、增删节点全部押到 第 15–19 章;本章的 DOM 是「观光」不是「上手」。
- 没有讲解作用域提升(hoisting):var 的「声明提前、赋值不提前」是 let 诞生前的 主要 bug 源,原书提了「var 声明前可引用(值为 undefined)」一句,没有展开成机制课17。
- 错误处理停在教学层:onerror/try...catch 只兜「元素不存在」这种演示错误; Promise 的 catch、async/await 的错误链(第 17 章 fetch 一带而过)才是现代 JS 的主战场。
- typeof 的坑只列了两个:函数 typeof 得 "function"、正则等其余怪值没有盘点—— 靠 typeof 判类型在复杂代码里迟早翻车,这是它留给读者的隐藏作业。
- 调试方法只给了「开控制台」:console.log 打点、断点、单步这些 IDE 级调试手段 一句带过(F12 打开 Console)。浏览器 DevTools 的 Sources/Network 面板全书几乎没出现, 而它们是现代前端排查的主兵器。
- DOM Level 0 的写法:用 id 当变量名(
mylink.href)、document.links集合, 都是最老的 DOM 便捷写法——今天的主流通用写法是 getElementById/querySelector(第 19 章), 教学起点合理,但别把这些简写当标准 API 记。
10. 章末自测:两章的问答题合答
| 原书的问题 | 我们的回答 |
|---|---|
| JS 代码包在什么标签里? | <script>…</script>(外链用 src)3 |
| 怎么引入外部 JS? | <script src="…"></script>;文件内不得再含 script 标签3 |
| JS 的 echo 等价物? | console.log5 |
| 怎么写注释? | // 单行、/* */ 多行(不可嵌套)、/** */ JSDoc9 |
| 字符串拼接运算符? | +(和 PHP 的 . 不同)12 |
| 函数内声明局部变量用哪个关键字? | let(或 var;新代码用 let/const)16 |
| 两条跨浏览器读 id=thislink 链接 URL 的方法? | document.links.thislink.href 与 document.links[0].href(简写 thislink.href)21 |
| 哪两个命令让浏览器回到上一页? | history.back() 与 history.go(-1)22 |
| 怎么把当前文档换成 oreilly.com? | document.location.href = 'http://oreilly.com'22 |
| PHP 与 JS 处理布尔有何不同? | PHP 打印 1/空串,JS 直接打印 true/false 小写23 |
| 一元/二元/三元? | 一个操作数(++)、两个(+)、三个(? :)31 |
| 强制优先级的最好办法? | 括号(两章同一答案) |
| 字面量与变量之外最简单的表达式? | 就这两样本身26 |
| if/while 怎么处理不同类型的条件? | 按 truthy/falsy 规则隐式转布尔26 |
| for 与 while 各何时用? | 规律变化用 for,事件式条件用 while(与 PHP 同) |
| 怎么转换类型? | parseInt/parseFloat/Boolean/String/split,无 cast 语法34 |
11. 可带走的
- JS 跑在浏览器,代码对用户可见;权力仅限操作当前页面(DOM)。
- 输出用 console.log(进控制台);错误也进控制台,不在页面上。
- 拼接用
+;逻辑只有&&||!;比较默认===。 - 弱类型:类型跟着赋值走,
typeof查证;n *= 1/n += ""秒转。 typeof null、typeof []都是 "object"——JS 最有名的历史坑。- var 会漏成全局、无视块;新代码 let/const;const 锁指向不锁内容。
- DOM 是对象树:
document.links.mylink.href沿树下行;links.length+ for 扫全页。 - history 只给数不给内容(隐私);back/forward/go 穿梭;改页用 location.href。
- falsy:字符串 "false"、0、-0、""、null、undefined、NaN;其余皆 truthy(含 [])。
||/&&短路——右操作数可能根本不执行;依赖它前先调用存值。- try...catch 管运行错误、语法错误管不着;死循环会冻住浏览器页面。
- 显式转换用函数:parseInt 永远带第二参数 10。
11.1 PHP → JavaScript 一页对照
| 概念 | PHP | JavaScript |
|---|---|---|
| 变量标记 | 必须 $ 开头 | 无标记;$ 合法但不推荐 |
| 拼接 | . | + |
| 输出 | echo / print | console.log(进控制台) |
| 打印 true/false | 1 / 空串 | true / false(小写) |
| 逻辑与或 | && and | 只有 &&(没有 and/or/xor) |
| 严格比较 | ===(同样推荐) | ===(同样推荐) |
| 数组字面量 | array(...) 或 [...] | 只有 [...] |
| 转数字/字符串 | (int)$x / (string)$x | parseInt(x,10) / String(x) |
| 未定义检测 | isset($x) | typeof x !== 'undefined' |
| 局部声明 | 函数内自动局部 | let/const(var 过时);裸赋值=全局 |
| 块级作用域 | 无(函数级) | let/const 有 |
| 多分支关键字 | elseif | 只有 else if |
| 循环遍历数组 | foreach($a as $v) | for...of |
| 错误兜底 | try...catch | onerror / try...catch finally |
这张表是「会 PHP 学 JS」的最短路径——左列你已经有,右列补差异即可。 反过来,它也是「会 JS 学 PHP」的同一扇门。
11.1 两种"输出":console.log 与 document.write 的分工
第 13 章给了两种立刻看到结果的方式,作者对它们的态度截然不同:
- console.log:把任何值或表达式打到浏览器的控制台—— 开发者工具里那个与页面分离的小窗口37。错误信息也往这里来, 所以"开着控制台学 JavaScript"是原书的默认姿势。
- document.write:在当前位置把内容写进页面,例子短小平快, 但作者明说生产代码绝不用它——他几乎总是写到预先备好的元素里 (第 17 章起用 innerHTML)38。
记法:console.log 是"草稿纸",document.write 是"直接在墙上涂鸦"。 学的时候两张纸都用;写真东西时,只留草稿纸。
11.2 嵌入与外挂:<script> 的三种姿势
第 13 章覆盖了三种引入方式39:
<script>console.log("Hello World")</script> <!-- ① 页内直写:教学用 -->
<script src="script.js"></script> <!-- ② 外链本域:正式用法 -->
<script src="http://someserver.com/script.js"></script> <!-- ③ 外链他域 -->两个硬性规则:
- 外链文件里不能再出现 script 标签——写进去直接报错40。
- 本书此处的
<script>写法在教学语境下成立;第 20 章的 React 工具链会换成带 type 属性的现代写法,届时再对照。
11.3 字符串与转义:同一张表,两种用法
第 13 章的字符串规则与 PHP 高度同构:单引号串里可以直接放双引号、 双引号串里可以直接放单引号;同型引号要用反斜杠转义41。 转义符不止管引号——制表符、换行、回车都靠它,原书 Table 13-5 给了完整表42。
一个 PHP 转过来的人最易栽的点:JavaScript 的字符串只有引号两种,
没有 PHP 那种 heredoc;多行文本要靠 \n 或模板拼接。
11.4 类型与 typeof:JavaScript 的"照妖镜"
第 13 章专门用 typeof 做了一次类型巡礼43,三个结论值得钉死:
- typeof 返回的是字符串:
typeof n的结果是'number'这种 字符串,所以判断写法是typeof n === 'number'。 - typeof null 和 typeof [] 都是 "object"——原书明确标注这是 "unexpected results"44。想区分数组和 null,typeof 不够, 这是第 15 章的伏笔(书外补充:Array.isArray 是现成判法)。
- JavaScript 里判"变量存不存在"也用 typeof:PHP 有 isset,
JavaScript 没有对应的函数,判断
typeof x === 'undefined'是 第 13 章给的替代写法45。
11.5 数值的两个怪邻居:NaN 与 Infinity
第 13 章在算术运算符一带(自增自减、取余与 PHP 完全同构)46 留给读者的两个坑:
- NaN(Not a Number):本该是数的地方不是数,比如从文本框
取值直接做算术。特征:NaN 不等于任何值,连自己都不等于;
判断它要用
isNaN()。 - Infinity:除以 0 的归宿。比较运算里 Infinity 大于一切有限数, 但 Infinity - Infinity 是 NaN。
本书的处理很务实:知道存在、会用 isNaN 挡一下即可; 真正的"取数→转数→算数"流水线在第 16 章表单校验里现形。
11.6 == 与 ===:第 14 章最重要的一行字
第 14 章的原文值得整段记住:"you're encouraged to always use the strict equality operators === and !== as they are more safe"47。
机理一句话:== 比较前会把两边转成同一类型再比——
全数字字符串遇数字会被转成数字,空串也会参与这种"善意"转换,
结果常常出人意料48。=== 先比类型、类型不同直接 false。
"5" == 5 // true —— 字符串被转成了数(== 的"善意")
"5" === 5 // false —— 类型不同,免谈配套记忆点:JavaScript 的布尔字面量是小写 true/false,
写大写直接报错——原书例 14-x 里 TRUE 那一行就是演示这个错49。
11.7 控制流全家桶:第 14 章的对照表
第 14 章把 PHP 已有的控制流在 JavaScript 里重讲了一遍, 差异点浓缩成表:
| 结构 | 与 PHP 的差异 |
|---|---|
| if / else if / else | 无差异 |
三元 ? : | 无差异,"单行 if"50 |
| switch | 无本质差异 |
| while / do...while | 无差异;do...while 至少执行一次 |
| for | 建议 let 声明循环变量(for (let i = 0; ...)),限缩作用域 |
| break / continue | 无差异 |
真正的差异不在语法,在本书反复强调的一条:JavaScript 跑在浏览器, PHP 跑在服务器——同样的控制流,一个管"页面如何回应用户", 一个管"服务器如何回应请求"。第 14 章所有例子换到浏览器里跑, 都要先开 console.log 这张草稿纸。
11.8 主线例子再走一遍:浏览器里的一次完整交互
把第 13+14 章的机制串成一个最小交互(全部可在控制台里亲手跑):
1. [ch13] 打开开发者工具,console 就是草稿纸
2. [ch13] let name = prompt(...) 之类取得一段文本(或先写死)
3. [ch13] typeof 检查它是 string
4. [ch14] if (typeof x === 'undefined') 判存在性
5. [ch14] 用 === 判断内容是否符合预期
6. [ch13] console.log 输出结论;document.write 版留作对照,
体会"写进页面"与"写进控制台"的分别
7. [ch14] 循环把一组值逐个过一遍,三元写一行小摘要这个走查刻意只用第 13/14 章的工具——不碰 DOM、不碰事件。 它回答的问题是:"离开 HTML,JavaScript 作为一门语言能不能先立住?" 答案是能,而且这正是原书的排课理由。
11.9 PHP→JavaScript 速译卡(第 13+14 章版)
| PHP 里你会写 | JavaScript 里对应 | 注意 |
|---|---|---|
echo "Hi" | console.log("Hi") | 输出去了控制台,不在页面 |
$name = 'Joe' | let name = 'Joe' | 变量名风格:JavaScript 惯用驼峰 |
isset($x) | typeof x === 'undefined'(取反) | 方向相反,小心写反 |
"5" === 5 | 同样 false | 严格比较语义一致 |
TRUE | true(小写) | 大写报错 |
.(点号拼接) | +(加号拼接) | + 遇到数字会真的相加——见下 |
最后一行是最大的坑源:"You have " + messages + " messages" 这种
拼接本书照用51,但一旦某一项本该是数却是字符串,+ 就从
"拼接"滑向"算术"。防御:拼接前自己心里过一遍每项的类型。
11.10 练习场(第 13+14 章)
- 草稿纸热身:console 里用三种方式各输出一次 Hello, 其中一种走 document.write,对比二者的呈现位置。
- typeof 巡礼:对 42、"42"、true、undefined、null、[] 逐个 typeof,把结果抄成表——重点体会 null 和 [] 的"意外"。
- 严格比较实验:先猜再跑——
"5" == 5、"5" === 5、"" == 0、"" === 0,把每个结果和机理写出来。 - 控制流翻译:把第 3 章练习场的会员判定从 PHP 逐行翻成 JavaScript,只许用 console.log 输出——体会"同构的语法、 不同的家"。
- isNaN 防线:写一段"输入框取数×2"的小代码,先 isNaN 挡, 挡不住的让 console 显示原始值与类型——为第 16 章的表单校验 预演。
11.11 FAQ(四问)
Q1:为什么本书 JavaScript 部分全程 console.log,不直接改页面? 因为教学顺序:先把"语言"从"页面"里剥出来立住,再谈操作页面 (第 18/19 章)。一开始就混着 DOM,每个错都分不清是语言错还是 页面错。
Q2:let、const、var 我到底声明哪个? 本书第 13 章以 let 为主线(数组、循环变量的例子都是 let)。 const 留给"绑定了就不换"的场景(第 15 章会更多出现); var 是旧写法,本书新例子不再使用。一句话:新代码先 let, 明确不变的换 const。
Q3:JavaScript 数组和 PHP 数组一样吗? "能装字符串、数字、还能装数组"这点一样52;但 JavaScript 没有 PHP 那种键值数组的原生形态(第 15 章用对象补位), length、索引从 0 起这些细节两章对照着记。
Q4:本书让我"总是用 ===",可老代码全是 == 怎么办? 读老代码时把 == 当"会隐式转换的比较"来读,写新代码时一律 ===。 两者混用不是风格问题,是"这行代码的行为我能不能一眼预测"的问题。
11.12 console 排错五式:把草稿纸用成工具
第 13 章把 console 定义为"与页面分离、显示错误和消息的特殊窗口"53。 把它用出五种固定招式,比"瞎打 console.log"高效得多:
- 打值先看类型:
console.log('n = ' + n + ', is a ' + typeof n)——原书 typeof 巡礼的标准输出格式54。一半的"怎么会这样", 答案是类型不是你以为的那个。 - 分步打点:怀疑一段三行的计算,就在每行后打一次中间值。 不要在脑内单步调试——浏览器不会奖励你的记忆力。
- 报错即教材:console 里的红字不是失败,是 JavaScript 在 免费给你上课。逐字读第一行报错,九成问题在这一行里。
- 对照实验:一个表达式结果不对,把它的每个子表达式拆开
各打一次——第 14 章的
==转规,用这一招五分钟就能看清。 - typeof 当照妖镜常态化:拿不准就 typeof,这是原书给的 官方答案("you can always look up a variable's type")55。
11.13 与 PHP 的「同名不同物」速查
两章学下来,最容易张冠李戴的不是不同名的东西,是同名不同物的东西:
| 词 | PHP 里的它 | JavaScript 里的它 |
|---|---|---|
+ | 只做加法 | 拼接字符串,也能做加法——看两边类型 |
== | 松散比较(也会转类型) | 同样会转类型,且规则更野 |
=== | 值与类型都同 | 同左——本书两边都鼓励用它 |
Array | 键值对+索引混住一体 | 只有索引数组;键值对是 Object 的地盘 |
undefined | 无此概念(用 isset) | "从未被赋值"的专用值 |
true/false | 不区分大小写 | 必须小写,大写即错 |
. | 字符串拼接 | 取对象的属性(user.name) |
这张表的使用方式:写 JavaScript 时先查表再下笔,尤其 + 和
.——一个是运算符的多重身份,一个是两个语言里完全不同的词。
第 15 章展开数组与对象后,这张表还会再加两行(类、方法),
到时候回来更新它。
11.14 数组初见:JavaScript 数组与 PHP 数组的第一次对照
第 13 章给 JavaScript 数组的定位很干脆:和 PHP 很像—— 能装字符串、数字,也能装数组56;更深的展开留给第 15 章57。 这一节先做最小对照,把"像"与"不像"各划清楚:
| 维度 | PHP(第 6 章) | JavaScript(第 13 章) |
|---|---|---|
| 索引起点 | 0 | 0 |
| 能装异质数据 | 能 | 能(一个数组里数字字符串混装) |
| 键值对 | 原生支持($a['name']) | 不支持——那是对象的地盘 |
| 求长度 | count($a) | a.length(属性,不是函数) |
| 嵌套 | 多维数组 | 数组套数组,同形 |
两个立刻能上手的例子:
let face = [[1,2,3],[4,5,6],[7,8,9]]; // 二维,同 PHP 多维数组
console.log(face[1][2]); // 6 —— 行列从 0 数[^88]let messages = 5;
console.log("You have " + messages + " messages."); // 拼接仍用 +[^89]注意第二例:+ 的左边是字符串,于是数字被悄悄转成字符串拼上去——
这正是 §11.9 速译卡里标过的坑的最小现场。写拼接时心里默念:
+ 的左边是字符串,右边就都成了字符串。
11.15 两章机制的合练:一个控制台小工具
只用第 13/14 章的工具,在控制台里完成这个小程序(逐行可跑):
1. let items = [] // 空数组
2. 向 items push 三样"待办",各是字符串
3. 用 for(let i = 0; i < items.length; i++) 逐个打印,
每行前加序号(用 i + 1)
4. 用三元给空数组一个特别输出:"(空)" vs "共 N 项"
5. 全部包进一个 list() 函数 —— 这是给第 15 章的预习
6. typeof items === 'object' 验一下类型,记住这个"意外"这个练习的设计意图:它不引入任何第 15 章之后的概念, 却把你推到了第 15 章的门口(函数化)。跑完之后回看, 两章的工具——变量、类型、数组、循环、三元、严格比较—— 已经全部出场过一遍,且互相配合过。
11.16 新手三报错:症状、病因、处方
第 13/14 章的练习期,有三个报错几乎人人会遇,各配一句处方:
报错一:Uncaught ReferenceError: x is not defined。
病因:用了没声明过的变量——拼写错了,或作用域不对。
处方:console 点进报错链接,看它指向的行;仍看不出,
对那个变量 typeof 一下。这类错的九成是手滑,不是机制不懂。
报错二:Unexpected token。
病因:上一行少了个括号/引号/分号,解析器在下一行才喊疼。
处方:永远先看报错行的上一行。JavaScript 的报错位置
常常比真正的病灶晚一行——这是它最不体贴的地方。
报错三:什么都不报错,结果就是不对。
病因:逻辑错,不是语法错——比较写反、==/=== 用混、
循环边界差一。处方:console 五式(§11.12)逐项过,
重点用 typeof 与分步打点;把每个中间值的"预期 vs 实际"
写成对照表,错的那个数就是病灶。
三条处方背后是同一个态度:报错不是中断,是免费教学; 没有报错也不是通过,只是还没测到错的输入。
11.17 过渡段:从这两章走向第 15 章
第 13/14 章立住了 JavaScript 作为"语言"的部分;第 15 章起, 它开始作为"工具"出现——函数、对象、数组方法,全是冲着 "操作页面、组织代码"去的。过渡时只带三样东西:
- 严格比较
===的肌肉记忆(第 14 章的铁律,后半本书全程适用); - console 五式(§11.12)——后半本书每个例子都值得开着控制台跟跑;
- typeof 照妖镜——每次拿到的数据拿不准,先照一下再加工。
其余的(转义、字符串、算术、控制流)已是内化的背景知识, 不需要"带着走",它们自己会跟着。
11.18 留给练习者的最后一格
这两章的练习量,原书每章末尾留了复习题,本章 §11.10/§11.15 另加了两组。如果只挑三道做,按投入产出比选:§11.10 的第 3 题 (严格比较实验——撞一次"=="的隐式转换,终生免疫)、 §11.10 的第 4 题(PHP 翻译——亲手量出两语言的同与不同)、 §11.15 的合练(全工具出场一遍)。三道做完,两章没有死角。
12. 原文地图
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 命名与诞生 | Chapter 13. Exploring JavaScript | text/24-ch13-chapter-13-exploring-javascript.txt:11(搜「marketing」)· :15(搜「DOM」) |
| console.log 与 document.write | 同上 | text/24-ch13-chapter-13-exploring-javascript.txt:37(搜「console.log」)· :82(搜「never use」) |
| script 标签与分号 | 同上 | text/24-ch13-chapter-13-exploring-javascript.txt:127(搜「no trailing semicolon」)· :172(搜「bottom of the page」)· :197(搜「must not include」) |
| 注释与 JSDoc | 同上 | text/24-ch13-chapter-13-exploring-javascript.txt:245(搜「// This is a comment」)· :261(搜「JSDoc」) |
| 变量命名规则 | 同上 | text/24-ch13-chapter-13-exploring-javascript.txt:319(搜「letters a–z」)· :350(搜「$ is in that list」) |
| 弱类型与 typeof | 同上 | text/24-ch13-chapter-13-exploring-javascript.txt:916(搜「838102050」)· :959(搜「is a string」)· :994(搜「typeof null」) |
| 函数与作用域 | 同上 | text/24-ch13-chapter-13-exploring-javascript.txt:1021(搜「function product」)· :1059(搜「Arrays are passed」) |
| var/let/const | 同上 | text/24-ch13-chapter-13-exploring-javascript.txt:1130(搜「let keyword」)· :1169(搜「block scoped」)· :1203(搜「constant value」)· :1235(搜「array.push」) |
| DOM 与名片比喻 | 同上 | text/24-ch13-chapter-13-exploring-javascript.txt:1256(搜「Document Object Model」)· :1265(搜「card.name」)· :1276(搜「log is actually a method」) |
| links/history/location | 同上 | text/24-ch13-chapter-13-exploring-javascript.txt:1319(搜「mylink.href」)· :1382(搜「length property」)· :1404(搜「cannot read the full history」)· :1413(搜「history.go」)· :1428(搜「document.location.href」) |
| 布尔打印与 falsy | Chapter 14. Expressions and Control Flow in JavaScript | text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:49(搜「strings true and false」)· :58(搜「string false itself」)· :81(搜「lowercase」)· :558(搜「truthy value」) |
| === 纪律 | 同上 | text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:467(搜「more safe」)· :503(搜「temporarily converted」)· :511(搜「always use」) |
| 短路求值 | 同上 | text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:697(搜「short-circuit」) |
| onerror / try...catch | 同上 | text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:816(搜「errorHandler」)· :855(搜「do not catch syntax errors」)· :889(搜「finally」) |
| if/else if/switch/三元 | 同上 | text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:940(搜「no elseif」)· :1038(搜「fall-through」)· :1084(搜「default」)· :1099(搜「ternary」) |
| 循环与 for...of | 同上 | text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:1148(搜「while loop」)· :1188(搜「never-ending loop」)· :1215(搜「times 7」)· :1305(搜「for...of」)· :1339(搜「Needle」) |
| 显式转换 | 同上 | text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:1465(搜「parseInt(n, 10)」)· :1417(搜「no explicit casting」) |
Footnotes
-
出处:「Chapter 13. Exploring JavaScript」第 11 段(
text/24-ch13-chapter-13-exploring-javascript.txt:11,搜「marketing」)。「the naming was just a marketing ploy」。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 95 段(
text/24-ch13-chapter-13-exploring-javascript.txt:95,搜「Node.js」)。「Node.js... is a JavaScript engine that doesn't require a browser」。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 99 段(
text/24-ch13-chapter-13-exploring-javascript.txt:99,搜「script」)与第 172 段(:172,搜「bottom of the page」)、第 188 段(:188,搜「src」)、第 197 段(:197,搜「must not include」)。「putting them in the JavaScript files will cause an error」。 ↩ ↩2 ↩3 ↩4 -
出处:「Chapter 13. Exploring JavaScript」第 115 段(
text/24-ch13-chapter-13-exploring-javascript.txt:115,搜「noscript」)。「you ought to use them at least to tell users that JavaScript is required」。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 37 段(
text/24-ch13-chapter-13-exploring-javascript.txt:37,搜「console.log」)。「its equivalent of the PHP echo or print commands」。 ↩ ↩2 -
出处:「Chapter 13. Exploring JavaScript」第 1276 段(
text/24-ch13-chapter-13-exploring-javascript.txt:1276,搜「log is actually a method」)。「log is actually a method of the console object」。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 221 段(
text/24-ch13-chapter-13-exploring-javascript.txt:221,搜「Show features for developers」)。Safari 需先启用 Develop 菜单;其余浏览器 F12 / Ctrl-Shift-J / Cmd-Shift-J。document.write也能输出到页面,但页面加载完再调它会整页覆盖,原书明说不进生产代码35。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 127 段(
text/24-ch13-chapter-13-exploring-javascript.txt:127,搜「no trailing semicolon」)与第 300 段(:300,搜「When in doubt」)。「When in doubt, use a semicolon」。 ↩ ↩2 -
出处:「Chapter 13. Exploring JavaScript」第 245 段(
text/24-ch13-chapter-13-exploring-javascript.txt:245,搜「// This is a comment」)与第 257 段(:257,搜「cannot nest」)、第 261 段(:261,搜「JSDoc」)。 ↩ ↩2 -
出处:「Chapter 13. Exploring JavaScript」第 319 段(
text/24-ch13-chapter-13-exploring-javascript.txt:319,搜「letters a–z」)与第 350 段(:350,搜「$ is in that list」)。「It is allowed by JavaScript... I don't recommend keeping the $ character because it is frequently employed by jQuery」。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 364 段(
text/24-ch13-chapter-13-exploring-javascript.txt:364,搜「greeting」)、第 421 段(:421,搜「toys」)、第 458 段(:458,搜「face[1][2]」)。魔方一面作二维数组例。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 778 段(
text/24-ch13-chapter-13-exploring-javascript.txt:778,搜「plus sign」)。「JavaScript handles string concatenation slightly differently from PHP. Instead of the . (period) operator, it uses the plus sign」;+=追加见第 792 段。 ↩ ↩2 -
出处:「Chapter 13. Exploring JavaScript」第 916 段(
text/24-ch13-chapter-13-exploring-javascript.txt:916,搜「838102050」)。三次 typeof 输出见第 959–961 段:「n = 838102050, and is a string / number / string」。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 969 段(
text/24-ch13-chapter-13-exploring-javascript.txt:969,搜「n *= 1」)与第 980 段(:980,搜「parseInt」)。n += ""转字符串在同段。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 994 段(
text/24-ch13-chapter-13-exploring-javascript.txt:994,搜「typeof null」)。「may give unexpected results as both typeof null and typeof [] return "object"」。 ↩ ↩2 -
出处:「Chapter 13. Exploring JavaScript」第 1130 段(
text/24-ch13-chapter-13-exploring-javascript.txt:1130,搜「let keyword」)。「you should be using them [let and const] instead of the rather legacy var」;var 的两个毛病见第 1134 段与第 1169 段。 ↩ ↩2 ↩3 ↩4 -
出处:「Chapter 13. Exploring JavaScript」第 1139 段(
text/24-ch13-chapter-13-exploring-javascript.txt:1139,搜「Hello there」)与第 1153 段(:1153,搜「seemingly ignored」)。var 版输出 "How are you?"、let 版输出 "Hello there" 的对照实验;var 声明前可引用(初始 undefined)见第 1169 段。 ↩ ↩2 ↩3 -
出处:「Chapter 13. Exploring JavaScript」第 1212 段(
text/24-ch13-chapter-13-exploring-javascript.txt:1212,搜「Assignment to constant」)与第 1235 段(:1235,搜「array.push」)。「You don't modify the variable itself but only change its internals」。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 1256 段(
text/24-ch13-chapter-13-exploring-javascript.txt:1256,搜「Document Object Model」)。「breaks down the parts of an HTML document into discrete objects, each with its own properties and methods」。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 1265 段(
text/24-ch13-chapter-13-exploring-javascript.txt:1265,搜「card.name」)与第 1274 段(:1274,搜「card.display」)。名片比喻原文。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 1319 段(
text/24-ch13-chapter-13-exploring-javascript.txt:1319,搜「mylink.href」)与第 1338 段(:1338,搜「short form」)、第 1380 段(:1380,搜「document.links[0]」)、第 1387 段(:1382,搜「length property」)、第 1394 段(:1394,搜「for (j=0」)。 ↩ ↩2 -
出处:「Chapter 13. Exploring JavaScript」第 1402 段(
text/24-ch13-chapter-13-exploring-javascript.txt:1402,搜「history.length」)与第 1404 段(:1404,搜「cannot read the full history」)、第 1413 段(:1413,搜「history.go」)、第 1428 段(:1428,搜「document.location.href」)。「you cannot read the full history」的隐私设计解释在同段。 ↩ ↩2 ↩3 -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 49 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:49,搜「strings true and false」)。「Unlike PHP (which would print the number 1 and nothing, respectively), the actual strings true and false are displayed」。 ↩ ↩2 ↩3 -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 81 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:81,搜「lowercase」)。「the second will cause a TRUE is not defined error」。 ↩ -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 58 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:58,搜「string false itself」)。falsy 清单原文逐项列出。 ↩ ↩2 -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 558 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:558,搜「truthy value」)。「An array like [1, 2, 3]」「And even an empty array like []」皆为 truthy;Boolean() 验货见第 606 段。 ↩ ↩2 ↩3 -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 467 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:467,搜「more safe」)。「you're encouraged to always use the strict equality operators === and !== as they are more safe」;0 == ""实验见第 495 段,结论在第 511 段。 ↩ ↩2 ↩3 -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 697 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:697,搜「short-circuit」)。「the second operand will not be evaluated」;修法(先调用)见第 724 段。 ↩ ↩2 -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 797 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:797,搜「onerror」)与第 855 段(:855,搜「do not catch syntax errors」)、第 884 段(:884,搜「finally」)。 ↩ ↩2 ↩3 -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 940 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:940,搜「no elseif」)。「JavaScript has no elseif statement, but that's not a problem because you can use an else followed by another if」;fall-through cases 见第 1038 段。 ↩ ↩2 -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 1099 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:1099,搜「ternary」)。一行版size = a <= 5 ? "short" : "long"见第 1128 段;三元占三个操作数见第 251 段。 ↩ ↩2 -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 1305 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:1305,搜「for...of」)。「loop over values coming from iterable objects, for example, arrays」。 ↩ ↩2 -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 1188 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:1188,搜「never-ending loop」)。「some browsers could become unresponsive due to a never-ending loop」。 ↩ ↩2 ↩3 -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 1417 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:1417,搜「no explicit casting」)。函数表见 Table 14-6;「10 is an optional radix, recommended to always use it」见第 1465 段。 ↩ ↩2 ↩3 -
出处:「Chapter 13. Exploring JavaScript」第 78 段(
text/24-ch13-chapter-13-exploring-javascript.txt:78,搜「unsafe」)与第 82 段(:82,搜「never use」)。「I never use document.write in production code」。 ↩ ↩2 -
出处:「Chapter 13. Exploring JavaScript」第 1059 段(
text/24-ch13-chapter-13-exploring-javascript.txt:1059,搜「Arrays are passed」)。「Arrays are passed to a function by reference, so if you modify any elements in an array parameter, the elements of the original array will be modified」——PHP 的数组复制是照抄纸条,JS 是牵线,与对象一致(第 5 章讲过)。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 41 段(
text/24-ch13-chapter-13-exploring-javascript.txt:41,搜「console of the current browser」)。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 82 段(
text/24-ch13-chapter-13-exploring-javascript.txt:82,搜「never use document.write」)。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 99 段(
text/24-ch13-chapter-13-exploring-javascript.txt:99,搜「opening <script>」)与第 188 段(:188,搜「script.js」)。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 197 段(
text/24-ch13-chapter-13-exploring-javascript.txt:197,搜「must not include」)。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 367 段(
text/24-ch13-chapter-13-exploring-javascript.txt:367,搜「backslash character」)。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 807 段(
text/24-ch13-chapter-13-exploring-javascript.txt:807,搜「Escape characters」);Table 13-5 见第 819 段。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 916 段(
text/24-ch13-chapter-13-exploring-javascript.txt:916,搜「typeof operator」)。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 994 段(
text/24-ch13-chapter-13-exploring-javascript.txt:994,搜「unexpected results」)。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 1083 段(
text/24-ch13-chapter-13-exploring-javascript.txt:1083,搜「no such function」)。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 761 段(
text/24-ch13-chapter-13-exploring-javascript.txt:761,搜「post- and pre-incrementing」)。 ↩ -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 467 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:467,搜「strict equality operators」)。 ↩ -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 484 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:484,搜「convert them to whatever type」)。 ↩ -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 87–88 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:88,搜「Will cause an error」)。 ↩ -
出处:「Chapter 14. Expressions and Control Flow in JavaScript」第 251 段(
text/25-ch14-chapter-14-expressions-and-control-flow-in-javas.txt:251,搜「ternary operator」)。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 783 段(
text/24-ch13-chapter-13-exploring-javascript.txt:783,搜「You have」)。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 416 段(
text/24-ch13-chapter-13-exploring-javascript.txt:416,搜「array can contain」)。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 41 段(
text/24-ch13-chapter-13-exploring-javascript.txt:41,搜「special mode」)。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 943 段(
text/24-ch13-chapter-13-exploring-javascript.txt:943,搜「and is a」)。输出格式n = '838102050', and is a string见第 916–949 段。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 987 段(
text/24-ch13-chapter-13-exploring-javascript.txt:987,搜「always look up」)。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 416 段(
text/24-ch13-chapter-13-exploring-javascript.txt:416,搜「array can contain」)。 ↩ -
出处:「Chapter 13. Exploring JavaScript」第 467 段(
text/24-ch13-chapter-13-exploring-javascript.txt:467,搜「much greater depth」)。 ↩