Javascript基础巩固系列——错误处理机制+编程风格+console对象与控制台

全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/13712246.html, 多谢,=。=~(如果对你有帮助的话请帮我点个赞啦)

重新学习JavaScript是因为当年转前端有点儿赶鸭子上架的意味,我一直在反思我的知识点总是很零散,不能在脑海中形成一个完整的体系,所以这次想通过再次学习将知识点都串联起来,结合日常开发的项目,达到温故而知新的效果。与此同时,总结一下我认为很重要但又被我遗漏的知识点~

错误处理机制

Error实例对象

JavaScript 原生提供Error构造函数,所有抛出的错误都是这个构造函数的实例。

var err = new Error('出错了');
err.message // "出错了"

原生错误类型

Error实例对象是最一般的错误类型,在它的基础上,JavaScript 还定义了其他6种错误对象,即Error的6个派生对象。

  • SyntaxError对象
    解析代码时发生的语法错误,在语法解析阶段就可以发现,例如变量名错误、缺少括号。
// Uncaught SyntaxError: Invalid or unexpected token
// Uncaught SyntaxError: Unexpected string
  • ReferenceError对象
    引用一个不存在的变量时发生的错误,或者将一个值分配给无法分配的对象,例如对函数的运行结果赋值。
// Uncaught ReferenceError: unknownVariable is not defined
// Uncaught ReferenceError: Invalid left-hand side in assignment
  • RangeError对象
    一个值超出有效范围时发生的错误,例如数组长度为负数、Number对象的方法参数超出范围、函数堆栈超过最大值。
// Uncaught RangeError: Invalid array length
  • TypeError对象
    变量或参数不是预期类型时发生的错误,例如对原始类型的值使用new命令、调用对象不存在的方法。
// Uncaught TypeError: number is not a func
// Uncaught TypeError: obj.unknownMethod is not a function
  • URIError对象
    URI 相关函数(encodeURI()decodeURI()encodeURIComponent()decodeURIComponent()escape()unescape())的参数不正确时抛出的错误。
// URIError: URI malformed
  • EvalError对象
    eval函数没有被正确执行时抛出错误,该错误类型已经不再使用,只是为了保证与以前代码兼容,才继续保留。

自定义错误

可以定义自己的错误对象,让它继承至Error对象,然后就可以生成这种自定义类型的错误了。

function UserError(message) {
  this.message = message || '默认信息';
  this.name = 'UserError';
}

UserError.prototype = new Error();
UserError.prototype.constructor = UserError;

new UserError('这是自定义的错误!');

throw语句

  • 手动中断程序执行并抛出一个错误。
var x = -1
if (x <= 0) {
  throw new Error('x 必须为正数');
}
// Uncaught Error: x 必须为正数
  • throw可以抛出任何类型的值,它的参数可以是任何值。
// 抛出一个字符串
throw 'Error!';
// Uncaught Error!

// 抛出一个对象
throw {
  toString: function () {
    return 'Error!';
  }
};
// Uncaught {toString: ƒ}

try...catch语句

允许对错误进行处理,选择是否往下执行,catch接受一个参数,表示try代码块抛出的值,catch代码块捕获错误之后,程序不会中断,会按照正常流程继续执行下去,catch代码块中可继续抛出错误或嵌套try...catch语句。

try {
  throw new Error('出错了!');
} catch (e) {
  console.log(e.name + ": " + e.message);
  console.log("task:" + e.stack);
}
console.log("继续执行了")
// Error: 出错了!
// task:Error: 出错了!
//   at <anonymous>:3:9
// 继续执行了

finally语句

try...catch允许在最后添加一个finally代码块,表示不管是否出现错误,都必需在最后运行的语句。

var count = 0;
function countUp() {
  try {
    return count;  // return语句里面的count值是在finally代码块运行之前就获取了。
  } finally {
    count++;
  }
}

countUp()
// 0
count
// 1

编程风格

区块

终于明白为什么区块起首的大括号的位置通常建议跟在关键字的后面了,下面这种本来是要返回一个对象,但实际上返回的是undefined,因为 JavaScript 自动在return语句后面添加了分号,这就导致了难以察觉的错误。

return
{
  key: value
};

// 相当于
return;
{
  key: value
};
// 推荐写法
return {
  key : value
};

行尾的分号

除了forwhile循环、ifswitch以及try分支语句、函数的声明语句这三种情况,所有语句都应该使用分号,否则大多数情况下Javascript会进行“分号的自动添加”(Automatic Semicolon Insertion,简称 ASI),但会出现应该添加却没添加的情况以及不该添加却添加了的情况,难以预测;还有一个原因是有的代码压缩器是不会自动添加分号的;另外不写结尾的分号,可能会导致脚本合并出错,可以在句首自己额外添加一个分号避免这种问题。

// 引擎解释为 c(d+e)
var a = b + c
(d+e).toString();

// 引擎解释为 a = b/hi/g.exec(c).map(d)
// 正则表达式的斜杠,会当作除法运算符
a = b
/hi/g.exec(c).map(d);

// 解释为'b'['red', 'green'],
// 即把字符串当作一个数组,按索引取值
var a = 'b'
['red', 'green'].forEach(function (c) {
  console.log(c);
})

// 解释为 function (x) { return x }(a++)
// 即调用匿名函数,结果f等于0
var a = 0;
var f = function (x) { return x }
(a++)

// 如果continue、break、return和throw这四个语句后面,直接跟换行符,则会自动添加分号。
return
{ first: 'Jane' };

// 解释成
return;
{ first: 'Jane' };

switch...case结构

在每一个case的最后一行必须是break语句,否则会接着运行下一个case,这样不仅易忘还会造成代码的冗长,而且该结构不使用大括号,不利于代码形式的统一,结构类似于goto语句,容易造成程序流程的混乱,不符合面向对象编程的原则,建议采用对象结构替代。

function doAction(action) {
  var actions = {
    'hack': function () {
      return 'hack';
    },
    'slash': function () {
      return 'slash';
    },
    'run': function () {
      return 'run';
    }
  };

  if (typeof actions[action] !== 'function') {
    throw new Error('Invalid action.');
  }

  return actions[action]();
}

console对象与控制台

console对象是 JavaScript 的原生对象,可以输出各种信息到控制台,并且还提供了很多有用的辅助方法。

console 对象的静态方法

  • console.log()
    可以接受一个或多个参数,将它们连接起来输出;也可以使用格式占位符,参数会依次填充输出。
    %s:字符串
    %d:整数
    %i:整数
    %f:浮点数
    %o:对象的链接
    %c:CSS 格式字符串
var number = 11 * 9;
var color = 'red';
console.log('%d %s balloons', number, color);

console.log(
  '%cThis text is styled!',
  'color: red; background: yellow; font-size: 24px;'
)

// console对象的所有方法都可以被覆盖,因此可以自定`console.log`方法。
['log', 'info', 'warn', 'error'].forEach(function(method) {
  console[method] = console[method].bind(
    console,
    new Date().toISOString()
  );
});

console.log("出错了!");
// 2014-05-18T09:00.000Z 出错了!
  • console.table()
    可以将某些复合类型的数据转为表格显示。
var languages = [
  { name: "JavaScript", fileExtension: ".js" },
  { name: "TypeScript", fileExtension: ".ts" },
  { name: "CoffeeScript", fileExtension: ".coffee" }
];

console.table(languages);
  • console.count()
    用于计数,输出它被调用了多少次,可以接受一个字符串作为参数,作为标签,对执行次数进行分类。
function greet(user) {
  console.count(user);
  return "hi " + user;
}

greet('bob')
// bob: 1
// "hi bob"

greet('alice')
// alice: 1
// "hi alice"

greet('bob')
// bob: 2
// "hi bob"
  • console.assert()
    进行条件判断,如果不满足条件,就显示一个错误,但不会中断程序执行。
console.assert(list.childNodes.length < 500, '节点个数大于等于500')
  • console.time()console.timeEnd()
    用于计时,可以算出一个操作所花费的准确时间,参数是计时器的名称。调用timeEnd方法之后,控制台会显示“计时器名称: 所耗费的时间”。
console.time('Array initialize');

var array= new Array(1000000);
for (var i = array.length - 1; i >= 0; i--) {
  array[i] = new Object();
};

console.timeEnd('Array initialize');
// Array initialize: 1914.481ms

控制台命令行 API

  • $(selector)
    返回第一个匹配的元素,等同于document.querySelector(),如果页面脚本对$有定义,则会覆盖原始的定义。
  • $$(selector)
    返回选中的 DOM 对象,等同于document.querySelectorAll。
  • inspect(object)
    打开相关面板,并选中相应的元素(打开Elements面板,高亮并选中指定的Dom元素)。
inspect(document.querySelector('.panel-block'))
  • getEventListeners(object)
    返回一个对象,该对象的成员为object登记了回调函数的各种事件(比如click或keydown),每个事件对应一个数组,数组的成员为该事件的回调函数。

参考资料

JavaScript 语言入门教程 :https://wangdoc.com/javascript/index.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章