Eloquent JavaScript #08# Bugs and Errors
索引
Notes
Exercise
Notes
1、strict mode
strict mode优势:更严格的检查、删除了一些有问题的语言特性。
把 "use strict" 放在文件顶部(必须是文件顶部,放在其它地方就被当成字符串了)或者函数顶部开启js strict模式。
示例1:没启用strict模式,js就会给你悄摸摸地加一个let上去...
- function canYouSpotTheProblem() {
- "use strict";
- for (counter = 0; counter < 10; counter++) {
- console.log("Happy happy");
- }
- }
- canYouSpotTheProblem();
- // → ReferenceError: counter is not defined
示例2:没启用strict模式,name被悄悄地绑定到一个全局对象上而没报错。
- function Person(name) { this.name = name; }
- let ferdinand = Person("Ferdinand"); // oops
- console.log(name);
- // → Ferdinand
- console.log(window.name);
- // → Ferdinand
- // - -- - --修改↓分割线------------------------------------
- "use strict";
- function Person(name) { this.name = name; }
- let ferdinand = Person("Ferdinand"); // forgot new
- // → TypeError: Cannot set property 'name' of undefined
PS. 上述情况,用class定义类具有和采用strict模式一样的效果,所以尽量用class定义类。
2、js类型
js在在运行时才会涉及到类型。许多语言在编译期就考虑类型了。
为了减少js类型带来的一些问题,有两个简单的解决方案:
① 注释
- // (VillageState, Array) → {direction: string, memory: Array}
- function goalOrientedRobot(state, memory) {
- // ...
- }
可以进行类型检查,并编译成js
3、js测试
采用第三方测试套件或者如下所示:
- function test(label, body) {
- if (!body()) console.log(`Failed: ${label}`);
- }
- test("convert Latin text to uppercase", () => {
- return "hello".toUpperCase() == "HELLO";
- });
- test("convert Greek text to uppercase", () => {
- return "Χαίρετε".toUpperCase() == "ΧΑΊΡΕΤΕ";
- });
- test("don't convert case-less characters", () => {
- return "مرحبا".toUpperCase() == "مرحبا";
- });
4、Debugging
console.log或者debugger关键字:
- function add(a, b) {
- console.log(`add ${a} and ${b}`);
- return a + b;
- }
- debugger; // 从这一行开始进入浏览器debug模式
- let x = add(1, 3);
- prompt("只有在开发者模式下,debug模式才生效");
5、Exceptions
异常的一大优势:几乎无耦合地在多个函数中(调用栈)传递,中间函数什么都不需要知道,仅在最外层处理就行了。
- function promptDirection(question) {
- let result = prompt(question);
- if (result.toLowerCase() == "left") return "L";
- if (result.toLowerCase() == "right") return "R";
- throw new Error("Invalid direction: " + result);
- }
- function look() {
- if (promptDirection("Which way?") == "L") {
- return "a house";
- } else {
- return "two angry bears";
- }
- }
- try {
- console.log("You see", look());
- } catch (error) {
- console.log("Something went wrong: " + error);
- }
6、finally
- function transfer(from, amount) {
- if (accounts[from] < amount) return;
- let progress = 0;
- try {
- accounts[from] -= amount;
- progress = 1;
- accounts[getAccount()] += amount;
- progress = 2;
- } finally {
- if (progress == 1) {
- accounts[from] += amount;
- }
- }
- }
- //Writing programs that operate reliably
- //even when exceptions pop up in unexpected places
- //is hard. Many people simply don’t bother,
- //and because exceptions are typically reserved
- //for exceptional circumstances, the problem may
- //occur so rarely that it is never even noticed.
- //Whether that is a good thing or a really bad thing
- //depends on how much damage the software will do when it fails.
7、异常分支
js不支持catch分支,而在try-catch的时候,同样会捕获undefined.call等造成的异常。
有些人可能会想只要比对e里面的信息就可以知道哪儿出现问题了,但是异常信息不是一个稳定的东西,一旦抛出的异常信息的表达改变,程序就不会正常工作,更可靠的解决方案如下(自定义空异常,只为了利用class区分,不加任何东西):
- class InputError extends Error {}
- function promptDirection(question) {
- let result = prompt(question);
- if (result.toLowerCase() == "left") return "L";
- if (result.toLowerCase() == "right") return "R";
- throw new InputError("Invalid direction: " + result);
- }
- for (;;) {
- try {
- let dir = promptDirection("Where?");
- console.log("You chose ", dir);
- break;
- } catch (e) {
- if (e instanceof InputError) {
- console.log("Not a valid direction. Try again.");
- } else {
- throw e;
- }
- }
- }
Exercises
① Retry
- class MultiplicatorUnitFailure extends Error {}
- function primitiveMultiply(a, b) {
- if(Math.random() < 0.2) {
- return a * b;
- } else {
- throw new MultiplicatorUnitFailure("Klunk");
- }
- }
- function reliableMultiply(a, b) {
- let result = undefined;
- for (; result == undefined;) {
- try {
- result = primitiveMultiply(a, b);
- } catch(e) {
- if (e instanceof MultiplicatorUnitFailure) {
- } else {
- throw e;
- }
- }
- }
- return result;
- }
- console.log(reliableMultiply(8, 8));
- // → 64
————-- - --- -- - - -------—-- - -—-- - -
② The locked box
- const box = {
- locked: true,
- unlock() { this.locked = false; },
- lock() { this.locked = true; },
- _content: [],
- get content() {
- if (this.locked) throw new Error("Locked!");
- return this._content;
- }
- };
- function withBoxUnlocked(body) {
- let locked = box.locked;
- if (!locked) {
- return body();
- }
- box.unlock();
- try {
- return body();
- } finally {
- box.lock();
- }
- }
- withBoxUnlocked(function() {
- box.content.push("gold piece");
- });
- try {
- withBoxUnlocked(function() {
- throw new Error("Pirates on the horizon! Abort!");
- });
- } catch (e) {
- console.log("Error raised:", e);
- }
- console.log(box.locked);
- // → true
Eloquent JavaScript #08# Bugs and Errors的更多相关文章
- Eloquent JavaScript #13# HTTP and Forms
索引 Notes fetch form focus Disabled fields form’s elements property 阻止提交 快速插入单词 实时统计字数 监听checkbox和rad ...
- Eloquent JavaScript #11# The Document Object Model
索引 Notes js与html DOM 在DOM树中移动 在DOM中寻找元素 改变Document 创建节点 html元素属性 布局 style CSS选择器 动画 Exercises Build ...
- Eloquent JavaScript #10# Modules
索引 Notes 背景问题 模块Modules 软件包Packages 简易模块 Evaluating data as code CommonJS modules ECMAScript modules ...
- Eloquent JavaScript #04# Objects and Arrays
要点索引: JSON More ... 练习 1.补:js字符串的表达方式有三种: "" 和 '' 没什么区别,唯一区别在于 "" 中写 "要转义字符 ...
- Eloquent JavaScript #03# functions
索引: let VS. var 定义函数的几种方式 more... 1.作者反复用的side effect side effect就是对世界造成的改变,例如说打印某些东西到屏幕,或者以某种方式改变机器 ...
- Eloquent JavaScript #02# program_structure
第一章中作者介绍了各种值,但是这些独立的值是没有意义的,只有当值放在更大的框架的时候才会彰显它们的价值.所以第二章开始介绍程序结构. 1.var VS. let 以及 const 作者推荐用 let ...
- Eloquent JavaScript #01# values
When action grows unprofitable, gather information; when information grows unprofitable, sleep. ...
- Eloquent JavaScript #12# Handling Events
索引 Notes onclick removeEventListener Event objects stopPropagation event.target Default actions Key ...
- Eloquent JavaScript #09# Regular Expressions
索引 Notes js创建正则表达式的两种方式 js正则匹配方式(1) 字符集合 重复匹配 分组(子表达式) js正则匹配方式(2) The Date class 匹配整个字符串 Choice pat ...
随机推荐
- nodejs, vue, webpack 项目实践
vue 及 webpack,均不需要与nodejs一期使用,他们都可以单独使用到任何语言的框架中. http://jiongks.name/blog/just-vue/ https://cn.vuej ...
- python web框架介绍对比
Django Python框架虽然说是百花齐放,但仍然有那么一家是最大的,它就是Django.要说Django是Python框架里最好的,有人同意也有人 坚决反对,但说Django的文档最完善.市场占 ...
- Ajax 传包含集合的JSON
通过ajax给后台传json对象,当json中含对象集合时,如 $.ajax({ url : , type : "POST", dataType : "json" ...
- Linux 网络编程之 Select
/*server*/ #include <stdio.h> #include <string.h> #include <unistd.h> #include < ...
- JAVA_POI 操作Excel
转自: http://rensanning.iteye.com/blog/1538591# Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API ...
- 数据分析与挖掘 - R语言:多元线性回归
一个简单的例子!环境:CentOS6.5Hadoop集群.Hive.R.RHive,具体安装及调试方法见博客内文档. 线性回归主要用来做预测模型. 1.准备数据集: X Y 0.10 42.0 0.1 ...
- django 【form表单】
#########################根据类来生成表单################# ''' django form类 通模型类的属性映射到数据库的字段一样,表单类的字段会映射到HTM ...
- JAVA8方法引用
方法引用:若Lambda方法体已经实现,我们可以使用方法引用* 主要有三种语法格式:* 对象::实例方法名* 类::实例方法名* 类::静态方法名** 注意:Lambda体中调用的方法的参数列表与返回 ...
- LeetCode104.二叉树最大深度
给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例:给定二叉树 [3,9,20,null,null,15,7], ...
- Unity shader学习之屏幕后期处理效果之Bloom效果
Bloom特效是游戏中常见的一种屏幕效果.这种特效可以模拟真实摄像机的一种图像效果,它让画面中较亮的区域“扩散”到周围的区域中,造成一种朦胧的效果. Bloom的实现原理很简单,首先根据一个阈值提取出 ...