错误类型与严格模式
## 错误类型有哪几种?
- 语法错误
- 引用错误
- 类型错误
- 范围错误
- URI错误
- eval函数错误
- 共6种
## uncaught SyntaxError的含义
- 未捕获的,即被系统自动抛出来的语法错误
JS错误信息类型,
1. SyntaxError 语法错误;
//变量名不规范,var 1 = 1; -> Uncaught SyntaxError: Unexpected number; //数字作变量名
// 未捕获的语法错误,意外的数字;
//变量名不规范 var 1ab = 1; -> Uncaught SyntaxError: Invalid or unexpected token; //数字开头做变量名
// 非法的(无效的) 或意外的 标记(1ab)
//关键字不能赋值 function = 1; -> Uncaught SyntaxError: Unexpected token =
//
//基本语法错误 var a = 5: -> Uncaught SyntaxError: Unexpected token :
//
2. ReferenceError 引用错误
//变量或者函数未被声明的时候, my_function() -> Uncaught ReferenceError: my_function is not defined at 作业集.html:354
// 未捕获的引用错误, my_function 未被定义
// console.log(a) -> Uncaught ReferenceError: a is not defined
//给无法赋值的对象赋值的时候,var a = 1 = 2; -> Uncaught ReferrenceError: Invalid left-hand side in assignment
// 语法错误, 无效的左侧的赋值 / 赋值的左侧是无效的;
3. RangeError 范围错误
//数组长度赋值为负数的时候, arr.length = -1; -> Uncaught RangeError: Invalid array length
// 范围错误: 无效的数组长度
//对象方法参数超出可行范围, num.toFixed(-1); -> Uncaught RangeError: toFixed() digits argument must be between 0 and 100 at Number.toFixed (<anonymous>)
// 范围错误, 数字参数必须在0到100的范围内
4. TypeError 类型错误
//调用不存在的方法 123() -> Uncaught TypeError 123 is not a function
// 先判断类型,判断123是不是function命名的方式, 类型是不是属于一个function,是function才能跟括号
// var obj = {}; obj.say(); -> Uncaught TypeError obj.say is not a function
// 调用函数中不存在的方法,会报类型错误; TypeError;
//实例化原始值 var a = new 'string'; -> Uncaught TypeError: "string" is not a constructor
// new一定要跟函数/构造器 类型错误, string不是一个构造器, //构造器至少要是test(){}函数类型的样子;
5. URIError, URI错误
// var str = decodeURI('%ddwedfs%'); //随机输入中文编码
// Uncaught URIError: URI malformed at decodeURI (<anonymous>)
// URI错误, URI是畸形的, 匿名的
6. EvalError eval函数执行错误;
// eval('var a = 0; console.log(1);'); //eval的作用之一,程序可以写成字符串,写到eval里面就能执行; 但不推荐使用;
// eval最大的作用,把json字符串转换成可访问的json对象;
// eval的错误,现在不容易出现; - 有时代码压缩和混淆的时候出错;
6种错误的人为抛出:
var error = new ReferenceError('引用错误');
console.log(error); //人为实例化错误对象,输出自定义错误;
错误类型有哪几种?
错误类型有6种,分别是语法错误,引用错误,范围错误,类型错误,URI错误,eval错误;
这六种错误都分别对应了一个构造函数,可以通过人为实例化错误对象,来抛出自定义错误;
(还有一个Error错误类型,var error = new Error(); )
try catch 手动抛出错误的方法:
try catch finally throw
示例:
var jsonStr = '';
try{
if(jsonStr == ''){
throw 'JSON字符串为空';
//throw 可以自定义抛出的错误信息;
//作用是修改e中的信息;
//throw后的语句不执行; 直接进入catch部分;
}
console.log(a);
}catch(e){
//e是一个错误对象, 里面放的是 { name:'', message:'' }
//可直接打印e, 得到具体的错误信息;
//e.name 是具体的错误名
//e.message 是具体的错误信息
console.log(e);
console.log('catch里的出错后执行');
}finally{
//finally中, catch中, 和 外面的代码都可以在发生错误后继续执行;
//其中, finally和 外层效果一样, 都一定会执行;
//finally里的主要放 一定要执行的代码;
console.log('finally 一定执行');
}
console.log('外层一定执行');
ES5严格模式历史
//EC MA Script的历史:
97 1.0
98 2.0
99 3.0 JS通行标准,
07 4.0草案,mozilla公司支持-fire fox, Branden Eich作者
08 4.0中止了, 把一部分容易改善的,放到3.1版本里面; 剩下部分放在代号Harmony版本里面 - 和谐的;
之后3.1直接更名为ECMAScript5,但还未公布
09 5.0正式发布, Harmony的内容分成了两部分,1/2 -> JS.NEXT, 1/2 -> JS.next.next; 下一版的下一版
11 5.1发布,成为了ISO国际标准; (和3.0同等地位);
13 ES6草案发布,
// ES6 = js.next , 直接是js.next里面的东西;
// 7.0 的草案直接用的是,js.next.next里面的东西;
15 ES6正式发布,也叫做ECMAscript2015;
ES5严格模式
ES5分为 正常模式 和 严格模式;
"use strict"
一般在函数内写严格模式,禁止在全局写严格模式;
如with()函数禁止使用,with()可以改变函数的作用域, 改变AO;
ES5严格模式中不能用的,及改变的内容:
with(){} //改变作用域函数,消耗性能
callee, 和caller,不可以用;
a = 1; 隐式声明全局变量,报全局报错; var a = b = 1; 也会报错;
严格模式下,函数内的this是undefined,不指向window了; 所以要手动给this赋值; 用test.call(window);
函数的参数不能重复; function test(a, a){}; 会报错,因为参数重复了;
!! 对象的相同属性名是可以重复覆盖的,在严格模式下也一样;
严格模式下,eval是有自己独立的作用域的:而非严格模式下,作用域是全局;
(对象的相同属性名是可以覆盖的, 在严格和非严格下都可以 )
(非严格模式下,test.call(1), call里面填原始值,会包装类number(1);)
严格模式的作用
让代码运行在ES5.0的语法规范下;
解决一些3.0语法不规范的问题;
严格模式兼容性:
//IE9以下是不支持严格模式的;
obj中对方法与属性的理解:
//var obj = {}
// obj.say 没有括号的时候是不报错的,因为javascript认为这是一个属性, 只是没有赋值:
// obj.say()会报类型错误, -> 因为如果对象里面没有.say()方法,JS会认为。say是一个属性,而属性被执行了,所以会报一个类型错误; 属性不能被执行,只有函数才能被执行;
URI, URL, URN
- 实际上,URI包括了URL和URN
URI : uniform resource identifier
// 统一资源标识符
URL : uniform resource locator
// 统一资源定位符,
URN : uniform resource name
// 统一资源名称, 就是URL不哟啊协议名,就下名称id就是URN
URL: http://www.baidu.com/news#today // URL就像地址一样,能够通过URL访问到你家里
ftp://www.baidu.com/ftp#developer //有协议,有域名,还有资源空间;
URN: www.baidu.com/ftp#developer //就是资源的唯一标识,就像一个id名称一样:
// href="tel:15200000000"; //这是个urn,不是url,tel是一个方法,用来打电话;
// href="mailto:1234567@qq.c om" //同样,mailto也是系统调用的方法,后面的qq号是urn,统一资源名称,也称资源名称或id;
把url中的中文转成中文编码字符的形式
var myUrl = 'http://baidu.com?name=小刘';
var newUrl = encodeURI(myUrl); //用encodeURI 方法,把中文转成中文编码字符
console.log(newUrl);
var newNewUrl = decodeURI(newUrl); //用decodeURI 方法,把中文编码字符转回来
console.log(newNewUrl);
json和对象的区别:
json里的属性名是双引号, "name":123;
json里面的属性不能带有方法function; //区别
(json字符串和json对象);
(如果带有方法,那么就是普通对象,不是json对象);
(json是用来存储数据的, 不能带方法的原因);
(json的样子: var jsonData = '[ {"name":123},{"name":321} ]'; //这个是json字符串
var jsonData = [ {"name":123},{"name":321} ]; //这个是json对象 )
(用eval()可以把json字符串转换成json对象);
( var data = eval('('+jsonData+')'); //eval转换的用法; )
为什么不然用eval?
1. 语法规范不好,参数带字符串能执行,变量也能执行;
2. 不好调试,断点调试不友好;
3. 性能问题;
4. 代码压缩或混淆的时候会出错。
5. 安全性问题,可能会引起XSS攻击;
笔试题:严格模式下:
'use strict';
var obj ={
a:1,
a:2
}
console.log(obj.a);
function test(a, a){
console.log(a);
}
test();
//2 , 报语法错误,函数参数不能重复;
// 对象属性重复覆盖不报错,打印2
// 严格模式下,参数名重复会报错;非严格模式下不报错, 会覆盖;
笔试题:
有'use strict'和非严格模式下,执行结果是怎样的?为什么?
eval('var a =1; console.log(a)');
consoe.log(a);
//非严格执行结果,1, 1
//严格实行结果,1,报错;
//原因,因为严格模式下,eval是有自己独立的作用域的:而非严格模式下,作用域是全局;