Skip to content

04-语法专题

第四章 语法专题

统计信息:字数 6435 阅读13分钟

2021-11-16 2023-04-03

4.1 数据类型转换

JS 中的变量的数据类型可以自由转换,当变量运算比较时,会发生数据类型的转换(通常转化成布尔值或者字符串),这里可能出现很多问题。

强制数据类型转化:Number(), String(), Boolean() 转换的规则较复杂,转换规则很严格,很少用。如果传入的对象是复杂数据类型,规则更复杂。

Number('42test') // NaN

把一个数据类型转换成布尔值,两种办法都可以

expression ? true : false
!!expression

null 转化成数值是0,undefined转化成数值是 NaN(如果在计算中某个参数是上面两个值可能出错)

大项目中(多人,多组件)最好避免数据类型的弱类型转换(使用类型验证或者使用 TS,避免出错)

4.2 错误处理机制

Error 实例对象

可以手动创建一个实例对象,err.message 是其属性。程序运行中如果抛出 Error 实例对象后,整个程序会中断在发生错误的地方。

var err = new Error('code bug');
err.message; //错误信息
err.name; //错误名称(非标准属性)
err.stack; // 错误的堆栈(非标准属性)

function throwErr() {
  throw new Error('');
}

function catchErr() {
  try {
    throwErr();
  } catch (error) {
    console.log(error);
    console.log(error.stack);
  }
}

catchErr();

error.stack 说明:JS 代码执行时,如果有多层函数互相调用,那么就形成函数执行栈,例如从外到内调用 fn1 fn2 fn3 函数,在 fn3 内部报错,那么对应的执行栈就可以记录到 fn1 fn2 fn3 函数,这样便于排查错误等。这个属性非标准属性。

参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error%20%20/Stack

https://www.bookstack.cn/read/node-in-debugging/3.3ErrorStack.md

https://zhuanlan.zhihu.com/p/26637923

6种原生错误类型

SyntaxError 语法错误:括号缺失、变量名不正确

Reference 引用错误:直接使用未定义的变量,赋值号(=)左侧不能赋值,this不能手动赋值,invalid left-hand side in assignment

RangeError 范围错误:数组的长度是负数,Number方法的参数超出范围,函数堆栈超过最大值

TypeError 类型错误:对原始数据类型(字符串、布尔值、数值)创建类(构造函数)、函数的方法是 undefined

URIError:URL错误 encode decode escape 函数传入参数不正确(react-image-lightbox 有这个报错)

EvalError eval 函数没有正确执行(现在已经舍弃,这里兼容旧代码)

上面的6个原生错误,和统一的Error类,都可以手动生成错误的实例,然后通过Error.message 设置错误的提示类型。用户可以自定义一个UserError错误对象,这种情况很少用到。

throw

手动终止程序的运行,可以抛出一个错误(上面的7种错误或者自定义错误)或者一个变量

try-catch

在 try 部分运行的代码,如果出现错误(抛出异常),try部分的代码终止运行,程序会进入catch部分,处理错误情况。如果不确定代码是否出现问题,就使用这个结构(尽量减少不确定的代码)。在catch部分可以根据错误的类型分别进行处理(TypeError,EvalError)尽量个用户显示友好的错误,也便于开发者调试错误

try {
  foo.bar();
} catch (e) {
  if (e instanceof EvalError) {
    console.log(e);
  } else if (e instanceof RangeError) {
    console.log(e);
  } else {
    console.log(e);
  }
} finally {
  //  
}

不管代码是否出错,代码会执行这部分代码;通常用于代码运行结束后,清理环境或者保存代码

openFile();

try {
  writeFile(Data);
} catch(e) {
  handleError(e);
} finally {
  closeFile();
}

4.3 编程风格

容易产生歧义的地方,使用明确写法。

圆括号的两个用法:函数调用方法;或者运算优先级(小括号),函数调用方法中不能加空格,运算过程中前后最好加上空格。

代码行末尾需要加上分号,不要让代码自己加入分号,可能出错。

由于JS中没有块级作用域,存在变量提升,所以最好把变量的声明放在代码前面,避免块内部变量提升到全局变量。如果需要加全局变量,最好使用大写或者特殊标记。

不要使用 with 语句;尽量使用全等于,不全等于会进行数据类型转换,可能存在问题,会影响一点性能。

自增和自减运算符,放在前面或者后面效果不一样,如果使用 += 或者 -= ,可读性更好(如果在for循环中,使用 ++ -- 运算符更简洁)

4.4 控制台对象

console API

console 对象是JS中的原生对象,command+option+I 即可打开控制栏,用于调试程序。

console 对象的静态方法

console.log('test'); // 直接输出字符串
console.log('%s + %s', 1,2) // 输出占位符,类似于python输出 %s %d %i %f %c(CSS)
console.log('%cThis text is styled!', 'color: red; background: yellow; font-size: 24px;');

Console.info warnings error debug 
// 可以在 default levels 中设置,如果代码中很多 warnings 那么浏览器不会显示这部分问题。

console.table(); //可以把复杂数据类型以表格形式呈现
console.count(var); //可以输出代码执行的次数,如果加入变量会分类输出代码执行的次数
console.dir(DOM);  
console.dirxml(DOM); //把DOM节点树状显示

console.assert(true, 'bug');// 条件显示:如果满足第一个条件,那么显示第二个参数

console.time();
console.timeEnd(); // 测试代码执行的时间
console.trace(); // 显示当前代码在堆栈中调用路径
console.clear(); // 清除控制台的当前输出

控制台 $ API

控制台定义了一个$函数,可以直接使用,如果使用了jquery,就会覆盖原始函数的功能。

$_ // 返回上一个表达式的值
$0 ~ $4 // 返回之前选中的DOM元素
$(selector) // === document.querySelector()
$$(selector) // === document.querySelectorAll()
inspect(DOM) // 在界面中选中这个元素
clear(); // clear console
copy(dom); // copy DOM nodes into clipboard

debugger

代码运行到这里时,如果浏览器有断点功能,就会暂停代码执行(Chrome浏览器常用)


Last update: November 9, 2024