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 ...
随机推荐
- centos7下源码编译方式安装httpd
前言 Apache至少需要apr.apr-util.pcre组件的支持. APR(Apache portable Run-time libraries,Apache可移植运行库)的目的如其名称一样,主 ...
- [vue]声明式导航和编程式导航
声明式导航和编程式导航 共同点: 都能进行导航,都可以触发路由,实现组件切换 区别: 写法不一样,声明式导航是写在组件的template中,通过router-link来触发,编程式导航写在js函数中, ...
- Java通过POI读取Excel
package com.hd.all.test.testjava; import java.io.File; import java.io.FileInputStream; import java.i ...
- shell for 循环数组
name=(aa bb) ;i<${#name[*]};i++)) do name=${name[i]} echo "$name" done
- tensorflow mac安装方法
480 pip install https://storage.googleapis.com/tensorflow/mac/tensorflow-0.5.0-py2-none-any.whl 481 ...
- pandas.query()
1. 查询 已知data: 查询概率等于0.4的所有行 问题所在:query后面只支持string形式的值,而"probability"==0.4返回的是一个bool类型,结果不是 ...
- SEO--多领域
1.社交媒体SEO优化,例如:视频,吸引流量 2.电商SEO,很多不是皇冠的商家也可以被搜索到 3.新媒体 微博 和 微信营销 手机端的SEO等.传统的SEO已经渐渐不具备竞争力 SEO盈利:网盟.广 ...
- WebAssembly 浏览器中运行c/c++模块
今天,要给前端造点儿福利 浏览器中能调用javascript,曾经我们以为够用了,够强大了,但是事实上是完全不够 还好,mozilla的工程师提出了webassembly,目前是利用emsctript ...
- python shutil.copytree 解决目标目录存在的情况
直接修改copytree的实现即可,如下: #copytree中找到 os.makedirs(dst),加入判断,就这么简单 if not os.path.exists(dst): os.makedi ...
- Jmeter安装与配置
Jmeter下载与安装配置 1.下载地址:https://jmeter.apache.org/ Apache Jmeter首页,点击 Download Releases 然后,选择,安装版本,有li ...