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 ...
随机推荐
- C 语言循环结构
25.有如下程序 main() { int i,sum; for(i=1;i<=3;sum++) sum+=i; printf("%d\n",sum); } 该程序的执行 ...
- 【UML】-NO.43.EBook.5.UML.1.003-【UML 大战需求分析】- 状态机图(State Machine Diagram)
1.0.0 Summary Tittle:[UML]-NO.43.EBook.1.UML.1.003-[UML 大战需求分析]- 状态机图(State Machine Diagram) Style:D ...
- openshift 调度命令
oc adm manage-node oc-node07 --schedulable=true #可调度 oc adm manage-node oc-node07 --schedulable=fal ...
- 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(六)RTP音视频传输解析层之音视频数据传输格式
一.差异 本地音视频数据格式和用来传输的音视频数据格式存在些许差异,由于音视频数据流到达客户端时,需要考虑数据流的数据边界.分包.组包顺序等问题,所以传输中的音视频数据往往会多一些字节. 举个例子,有 ...
- [LeetCode] 504. Base 7_Easy tag: Math
Given an integer, return its base 7 string representation. Example 1: Input: 100 Output: "202&q ...
- 利用Tensorflow实现神经网络模型
首先看一下神经网络模型,一个比较简单的两层神经. 代码如下: # 定义参数 n_hidden_1 = 256 #第一层神经元 n_hidden_2 = 128 #第二层神经元 n_input = 78 ...
- python class 1
//test.py class Employee: 'all employee' empCount = 0 def __init__(self, name, salary): self.name = ...
- layui透明弹框
效果: layui.use('layer', function () { var layer = layui.layer; var str = '<div>'; str += '<d ...
- python入门第一篇
python里面 单行注释用:#被注释内容 多行注释用:"""被注释内容""" 要想py2.7和py3.5都能运行,必须在文件头部加: #/ ...
- gispro设置标注属性字体样式设置
为了应对电子地图和卫星影像的底图,标注样式选择比较关键.挑选了黑字白色晕圈效果.记住不是设置字体轮廓. 因为字体宽度(字粗)有限,设置轮廓直接把字体本身的颜色覆盖了