Notes

1、strict mode

strict mode优势:更严格的检查、删除了一些有问题的语言特性。

把 "use strict" 放在文件顶部(必须是文件顶部,放在其它地方就被当成字符串了)或者函数顶部开启js strict模式。

示例1:没启用strict模式,js就会给你悄摸摸地加一个let上去...

  1. function canYouSpotTheProblem() {
  2. "use strict";
  3. for (counter = 0; counter < 10; counter++) {
  4. console.log("Happy happy");
  5. }
  6. }
  7.  
  8. canYouSpotTheProblem();
  9. // → ReferenceError: counter is not defined

示例2:没启用strict模式,name被悄悄地绑定到一个全局对象上而没报错。

  1. function Person(name) { this.name = name; }
  2. let ferdinand = Person("Ferdinand"); // oops
  3. console.log(name);
  4. // → Ferdinand
  5. console.log(window.name);
  6. // → Ferdinand
  7.  
  8. // - -- - --修改↓分割线------------------------------------
  9.  
  10. "use strict";
  11. function Person(name) { this.name = name; }
  12. let ferdinand = Person("Ferdinand"); // forgot new
  13. // → TypeError: Cannot set property 'name' of undefined

PS. 上述情况,用class定义类具有和采用strict模式一样的效果,所以尽量用class定义类。

2、js类型

js在在运行时才会涉及到类型。许多语言在编译期就考虑类型了。

为了减少js类型带来的一些问题,有两个简单的解决方案:

① 注释

  1. // (VillageState, Array) → {direction: string, memory: Array}
  2. function goalOrientedRobot(state, memory) {
  3. // ...
  4. }

② TypeScript

可以进行类型检查,并编译成js

3、js测试

采用第三方测试套件或者如下所示:

  1. function test(label, body) {
  2. if (!body()) console.log(`Failed: ${label}`);
  3. }
  4.  
  5. test("convert Latin text to uppercase", () => {
  6. return "hello".toUpperCase() == "HELLO";
  7. });
  8. test("convert Greek text to uppercase", () => {
  9. return "Χαίρετε".toUpperCase() == "ΧΑΊΡΕΤΕ";
  10. });
  11. test("don't convert case-less characters", () => {
  12. return "مرحبا".toUpperCase() == "مرحبا";
  13. });

4、Debugging

console.log或者debugger关键字:

  1. function add(a, b) {
  2. console.log(`add ${a} and ${b}`);
  3. return a + b;
  4. }
  5.  
  6. debugger; // 从这一行开始进入浏览器debug模式
  7.  
  8. let x = add(1, 3);
  9. prompt("只有在开发者模式下,debug模式才生效");

5、Exceptions

异常的一大优势:几乎无耦合地在多个函数中(调用栈)传递,中间函数什么都不需要知道,仅在最外层处理就行了。

  1. function promptDirection(question) {
  2. let result = prompt(question);
  3. if (result.toLowerCase() == "left") return "L";
  4. if (result.toLowerCase() == "right") return "R";
  5. throw new Error("Invalid direction: " + result);
  6. }
  7.  
  8. function look() {
  9. if (promptDirection("Which way?") == "L") {
  10. return "a house";
  11. } else {
  12. return "two angry bears";
  13. }
  14. }
  15.  
  16. try {
  17. console.log("You see", look());
  18. } catch (error) {
  19. console.log("Something went wrong: " + error);
  20. }

6、finally

  1. function transfer(from, amount) {
  2. if (accounts[from] < amount) return;
  3. let progress = 0;
  4. try {
  5. accounts[from] -= amount;
  6. progress = 1;
  7. accounts[getAccount()] += amount;
  8. progress = 2;
  9. } finally {
  10. if (progress == 1) {
  11. accounts[from] += amount;
  12. }
  13. }
  14. }
  15.  
  16. //Writing programs that operate reliably
  17. //even when exceptions pop up in unexpected places
  18. //is hard. Many people simply don’t bother,
  19. //and because exceptions are typically reserved
  20. //for exceptional circumstances, the problem may
  21. //occur so rarely that it is never even noticed.
  22. //Whether that is a good thing or a really bad thing
  23. //depends on how much damage the software will do when it fails.

7、异常分支

js不支持catch分支,而在try-catch的时候,同样会捕获undefined.call等造成的异常。

有些人可能会想只要比对e里面的信息就可以知道哪儿出现问题了,但是异常信息不是一个稳定的东西,一旦抛出的异常信息的表达改变,程序就不会正常工作,更可靠的解决方案如下(自定义空异常,只为了利用class区分,不加任何东西):

  1. class InputError extends Error {}
  2.  
  3. function promptDirection(question) {
  4. let result = prompt(question);
  5. if (result.toLowerCase() == "left") return "L";
  6. if (result.toLowerCase() == "right") return "R";
  7. throw new InputError("Invalid direction: " + result);
  8. }
  9.  
  10. for (;;) {
  11. try {
  12. let dir = promptDirection("Where?");
  13. console.log("You chose ", dir);
  14. break;
  15. } catch (e) {
  16. if (e instanceof InputError) {
  17. console.log("Not a valid direction. Try again.");
  18. } else {
  19. throw e;
  20. }
  21. }
  22. }

Exercises

① Retry

  1. class MultiplicatorUnitFailure extends Error {}
  2.  
  3. function primitiveMultiply(a, b) {
  4. if(Math.random() < 0.2) {
  5. return a * b;
  6. } else {
  7. throw new MultiplicatorUnitFailure("Klunk");
  8. }
  9. }
  10.  
  11. function reliableMultiply(a, b) {
  12. let result = undefined;
  13. for (; result == undefined;) {
  14. try {
  15. result = primitiveMultiply(a, b);
  16. } catch(e) {
  17. if (e instanceof MultiplicatorUnitFailure) {
  18. } else {
  19. throw e;
  20. }
  21. }
  22. }
  23. return result;
  24. }
  25.  
  26. console.log(reliableMultiply(8, 8));
  27. // → 64

————-- - ---  -- - -  -------—-- - -—-- - -

② The locked box

  1. const box = {
  2. locked: true,
  3. unlock() { this.locked = false; },
  4. lock() { this.locked = true; },
  5. _content: [],
  6. get content() {
  7. if (this.locked) throw new Error("Locked!");
  8. return this._content;
  9. }
  10. };
  11.  
  12. function withBoxUnlocked(body) {
  13. let locked = box.locked;
  14. if (!locked) {
  15. return body();
  16. }
  17.  
  18. box.unlock();
  19. try {
  20. return body();
  21. } finally {
  22. box.lock();
  23. }
  24. }
  25.  
  26. withBoxUnlocked(function() {
  27. box.content.push("gold piece");
  28. });
  29.  
  30. try {
  31. withBoxUnlocked(function() {
  32. throw new Error("Pirates on the horizon! Abort!");
  33. });
  34. } catch (e) {
  35. console.log("Error raised:", e);
  36. }
  37.  
  38. console.log(box.locked);
  39. // → 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. nodejs, vue, webpack 项目实践

    vue 及 webpack,均不需要与nodejs一期使用,他们都可以单独使用到任何语言的框架中. http://jiongks.name/blog/just-vue/ https://cn.vuej ...

  2. python web框架介绍对比

    Django Python框架虽然说是百花齐放,但仍然有那么一家是最大的,它就是Django.要说Django是Python框架里最好的,有人同意也有人 坚决反对,但说Django的文档最完善.市场占 ...

  3. Ajax 传包含集合的JSON

    通过ajax给后台传json对象,当json中含对象集合时,如 $.ajax({ url : , type : "POST", dataType : "json" ...

  4. Linux 网络编程之 Select

    /*server*/ #include <stdio.h> #include <string.h> #include <unistd.h> #include < ...

  5. JAVA_POI 操作Excel

    转自: http://rensanning.iteye.com/blog/1538591# Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API ...

  6. 数据分析与挖掘 - R语言:多元线性回归

    一个简单的例子!环境:CentOS6.5Hadoop集群.Hive.R.RHive,具体安装及调试方法见博客内文档. 线性回归主要用来做预测模型. 1.准备数据集: X Y 0.10 42.0 0.1 ...

  7. django 【form表单】

    #########################根据类来生成表单################# ''' django form类 通模型类的属性映射到数据库的字段一样,表单类的字段会映射到HTM ...

  8. JAVA8方法引用

    方法引用:若Lambda方法体已经实现,我们可以使用方法引用* 主要有三种语法格式:* 对象::实例方法名* 类::实例方法名* 类::静态方法名** 注意:Lambda体中调用的方法的参数列表与返回 ...

  9. LeetCode104.二叉树最大深度

    给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例:给定二叉树 [3,9,20,null,null,15,7], ...

  10. Unity shader学习之屏幕后期处理效果之Bloom效果

    Bloom特效是游戏中常见的一种屏幕效果.这种特效可以模拟真实摄像机的一种图像效果,它让画面中较亮的区域“扩散”到周围的区域中,造成一种朦胧的效果. Bloom的实现原理很简单,首先根据一个阈值提取出 ...