类型转换与错误处理

2020-08-29  本文已影响0人  Scincyc

错误处理机制

1、Error 实例对象

js所有抛出的错误都是Error构造函数的实例,参数表示错误提示,可以从实例的message属性读到

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

整个程序就中断在发生错误的地方,不再执行后面代码

function throwit() {
  throw new Error('');//抛出
}

function catchit() {
  try {
    throwit();
  } catch(e) {
    console.log(e.stack); // print stack trace
  }
}

catchit()
// Error
//    at throwit (~/examples/throwcatch.js:9:11)
//    at catchit (~/examples/throwcatch.js:3:9)
//    at repl:1:5

错误堆栈的最内层是throwit函数,然后是catchit函数,最后是函数的运行环境

2、自定义错误

function UserError(message) {
  this.message = message || '默认信息';
  this.name = 'UserError';
}
//自定义错误对象
throw new UserError('出错了!');

3、throw语句

用来手动中断程序执行,抛出一个错误

实际上,throw可以抛出任何类型的值

4、try...catch语句

允许对错误进行处理,选择是否往下执行

try {
  throw "出错了";
} catch (e) {
  console.log(111);
}
console.log(222);
// 111
// 222

catch代码块捕获try中抛出的错误之后,程序不会中断(除非return),会继续执行下去

可以嵌套使用try...catch结构

5、finally代码块

try...catch最后添加finally,不管是否出现错误,最后必需运行的语句

try {
    throw new Error('出错了……');
    console.log('此行不会执行');
  } finally {
    console.log('完成清理工作');
  }
// 完成清理工作
// Error: 出错了……

类型转换

强制转换

1、Number()

2、String()

3、Boolean()

自动转换

1、布尔值

预期为布尔值的地方(比如if语句的条件部分),会自动转换为布尔值

将一个表达式转为布尔值

// 写法一
expression ? true : false

// 写法二
!! expression

2、字符串

字符串的加法运算,一个值为字符串,一个非字符串

具体规则是,先将复合类型的值转为原始类型的值,再将原始类型的值转为字符串

'5' + {} // "5[object Object]"
'5' + [] // "5"
'5' + function (){} // "5function (){}"
'5' + undefined // "5undefined"
'5' + null // "5null"

3、数值

'5' * []    // 0
false / '5' // 0
'abc' - 1   // NaN
null + 1 // 1
undefined + 1 // NaN
+'abc' // NaN
-'abc' // NaN
+true // 1
-false // 0

set数据结构

// 
// 1.接收一个数组参数, 将数组去重再保存
// 2.set.clear()清空set 无返回值 返回undefined
// 3.set.add(val)添加某个值,返回set对象本身{1,2,3,4,5}
// 4.set.delete(val)删除某个值,返回是否删除成功
// 5.set.has(val)查找某个值,返回是否包含
// 6.set.size属性 值的个数
// 数组的去重
let arr = [1,2,3,4,5,1,2];
let set = new Set(arr);
arr = [...set];

map数据结构

// map数据结构 :类似于对象
// 1.接收一个二维数组,将数组转化成key-value的形式
// 2.map.clear()清空 map变为{}
// 3.map.get(key)获取key对应的value值
// 4.map.has(key) 返回是否包含
// 5.map.set(key,val)修改或增加key
// 6.map.delete(key) 返回是否删除成功
// 7.map.size属性 值的个数
let arr=[
    ['a',1],
    ['a2',2],
    ['a3',3]
]
let map = new Map(arr);
console.log(map);
// {'a'=>1,'a'=>2,'a'=>3} 

数组键名

1、数组的键名可以是整数或字符串?

arr = [1,2,3];
arr[0] //1
arr['0']  //1
arr.0//报错

之所以可以用数值读取,是因为非字符串的键名会被转为字符串

(方括号是运算符,可以接受数值,点结构不能)

2、数组的本质

是个对象

arr = [];
typeof arr;//object

3、length属性是可写的

可用来清空数组,将length属性设为0

var arr = [ 'a', 'b', 'c' ];
arr.length = 0;
arr // []

人为设置length大于当前元素个数,会自动新增,新增位置为空

var a = ['a'];
a.length = 3;
a[1] // undefined

小于,则会自动删除多余元素

注意:使用delete命令删除数组元素,会形成空位,length不变

类似数组的对象

一个对象的所有键名都是正整数或零,并有length属性,这个对象就很像数组,但不是数组。

1、和数组的区别

var obj = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3
};

obj[0] // 'a'
obj[1] // 'b'
obj.length // 3
obj.push('d') // TypeError: obj.push is not a function

2、有哪些例子

以下例子可以:使用[ ]获取元素,用length获取长度,但instanceof Array为false

3、转换为真正数组

有以下几种方法:

对象

obj = {
    age: 18,
    name: "ccc"
}
var a = "sex";
obj[a] = "female";//name: "female"
obj.a = "female";//a: "female"

(方括号是运算符,可以接受变量,点结构不能)

函数新增方法

// 函数新增方法
// 箭头函数
// 1.箭头函数使用()=>返回值,可以直接接收返回值,不用return
// 2.箭头函数没有不定参数arguments,可以使用(...arg)剩余参数接收多个参数,组成一个数组来获取参数
// 3.箭头函数没有this 调用箭头函数的this,指向声明时的作用域的this

数组新增方法

// 数组新增方法
// 1.flat(depth) 参数为递归层数,不改变原数组
let arr = [1,[2,3,[4],5],6];
let arr2 = arr.flat(Infinity);
console.log(arr2);

// 2.flatMap(callback) 只能递归一层,返回新组成的数组
let arr = [['a1',['11','11']],['a2','15']];
let arr2 = arr.flatMap((item, index) => {
    console.log(item,index);
    // 这里return item相当于flat递归一层,将第一层元素为数组的转为元素
    item = item.filter((item,index) => {
        return index == 0;
    })
    return item;
})
console.log(arr2);

// 3.find(callback)返回第一个满足要求的值 都没有就是undefined
let arr = [1,2,3,4,5,1,2];
let val = arr.find((item,index)=>{
    if(item>3){
        return true;
    }
});
// 或者
val = arr.find(item => item > 2);
console.log(val);

// 4.findIndex(callback)
let i = arr.findIndex(item => item > 2);

对象新增的方法

// 对象新增的方法
// 1.简洁表示法
// 1.1属性简洁表示
// 1.2方法简洁表示
// 2.属性名表达式[]
let age = 10;
let name = 'ccc';
let a = 'sex';
let person = {
    name,
    age,
    [a]: 'man',
    say(){
        console('say:function() => say(){}');
    }
}
console.log(person);

// 对象合并
let obj = {a:1,b:2};
let obj2 = {c:3,d:4};
obj2 = Object.assign(obj2, obj);
console.log(obj2);
let obj2 = {
    ...obj,
    c: 3,
    d: 4
};
console.log(obj3);


//is()对象比较
// 1.和===大部分相同,例如以下都是true
// 两个值都是undefined
// 两个值都是null
// 两个值都是true或者false
// 两个值都是相同字符串
// 两个值都是同一个对象(地址相同)
// 两个值都是数字
// 2.区别:
// +0 -0
// NaN NaN
console.log(Object.is(+0,-0))//false
console.log(+0 === -0)//true
console.log(NaN === NaN)//false
console.log(Object.is(NaN,NaN))//true

var与let

区别:块级作用域

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10
var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

for循环作用域

循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域

for (let i = 0; i < 3; i++) {
  let i = 'abc';
  console.log(i);
}
// abc
// abc
// abc
//说明各自单独的作用域

Babel的使用

<!-- babel -->
<!-- 一个js的编译器,可以把es6里面的语法糖转换为浏览器可以识别的js语法 -->
<!-- 具体的使用 -->
<!-- 1.引入babel文件 -->

<script src = "js/babel.min.js"> </script>
<script type = "text/babel">
    let obj = {a:1};
    let obj2 = {
        c:3,
        ...obj,
        c(){
            console.log("babel编译器 看浏览器代码是否变了");
        }
    }
</script>
上一篇 下一篇

猜你喜欢

热点阅读