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) {
// ...
}

② TypeScript

可以进行类型检查,并编译成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的更多相关文章

  1. Eloquent JavaScript #13# HTTP and Forms

    索引 Notes fetch form focus Disabled fields form’s elements property 阻止提交 快速插入单词 实时统计字数 监听checkbox和rad ...

  2. Eloquent JavaScript #11# The Document Object Model

    索引 Notes js与html DOM 在DOM树中移动 在DOM中寻找元素 改变Document 创建节点 html元素属性 布局 style CSS选择器 动画 Exercises Build ...

  3. Eloquent JavaScript #10# Modules

    索引 Notes 背景问题 模块Modules 软件包Packages 简易模块 Evaluating data as code CommonJS modules ECMAScript modules ...

  4. Eloquent JavaScript #04# Objects and Arrays

    要点索引: JSON More ... 练习 1.补:js字符串的表达方式有三种: "" 和 '' 没什么区别,唯一区别在于 "" 中写 "要转义字符 ...

  5. Eloquent JavaScript #03# functions

    索引: let VS. var 定义函数的几种方式 more... 1.作者反复用的side effect side effect就是对世界造成的改变,例如说打印某些东西到屏幕,或者以某种方式改变机器 ...

  6. Eloquent JavaScript #02# program_structure

    第一章中作者介绍了各种值,但是这些独立的值是没有意义的,只有当值放在更大的框架的时候才会彰显它们的价值.所以第二章开始介绍程序结构. 1.var VS. let 以及 const 作者推荐用 let ...

  7. Eloquent JavaScript #01# values

    When action grows unprofitable, gather information; when information grows unprofitable, sleep.      ...

  8. Eloquent JavaScript #12# Handling Events

    索引 Notes onclick removeEventListener Event objects stopPropagation event.target Default actions Key ...

  9. Eloquent JavaScript #09# Regular Expressions

    索引 Notes js创建正则表达式的两种方式 js正则匹配方式(1) 字符集合 重复匹配 分组(子表达式) js正则匹配方式(2) The Date class 匹配整个字符串 Choice pat ...

随机推荐

  1. os.path.join路径拼接

    #import os print("0:", os.path.join('/aaa', 'bbb', 'ccc.txt')) #0: /aaa\bbb\ccc.txt 多数这种用法 ...

  2. Number (float bool complex)浮点型、bool 布尔型 True、False 、complex 复数类型

    # Number (float bool complex) # ### float 浮点型 就是小数 # (1) 表达形式一 floatvar = 3.14 print(floatvar) #获取类型 ...

  3. windows下使用sed和tee命令

    最近需要在winowds slave上设置构建app和sdk,至于如何在windows slave上构建c/c++代码生成sdk(dll,lib之类)和apk(exe文件),请参考我的另外一篇博客,即 ...

  4. [LeetCode] 339. Nested List Weight Sum_Easy tag:DFS

    Given a nested list of integers, return the sum of all integers in the list weighted by their depth. ...

  5. Linux系统文件目录

    下面的示例是我个人的亚马逊云服务器,查看了几个关键目录的文件信息. 可以注册一个账号,免费试用一年,自己用来玩,还是很不错的 .https://aws.amazon.com/cn/ec2/ 根目录下面 ...

  6. IIS预编译提升加载速度

    当我们把网站部署在IIS7或IIS6S的时候,每当IIS或是ApplicationPool重启后,第一次请求网站反应总是很慢,原因大家都知道(不知道可以参考这个动画说明ASP.NET网页第一个Requ ...

  7. python使用cx_Oracle在Linux和Windows下的一点差异

    1. 主要是线程方面的差异. Windows下,把cx_Oracle.connect(connectedId)得到的handle传给定时器线程,主线程和和定时器可以用同一个handle. 但Linux ...

  8. eclipse的调试模式以及断点运行

    先在代码序号处打个点. 点击debug调试模式 然后再点击 如果有打断点,则会在断点处结束,如果没有,会一直一步一步向下直至结束.

  9. ob

    可以利用ob_get_contens生成静态页面,应用场景 后台生成商品的时候 可以生成对应的前台页面,其他页面直接调用. $result = $goods->create(); if ($re ...

  10. python基础-abstractmethod、__属性、property、setter、deleter、classmethod、staticmethod

    python基础-abstractmethod.__属性.property.setter.deleter.classmethod.staticmethod