1. JS错误信息类型

1.1 SyntaxError 语法错误

1.1.1 变量名不规范,如

  1. var 1 = 1;//Uncaught SyntaxError: Unexpected number 未被捕获的语法错误,翻译就是被抛出的错误:具体的类型是意外的数字
  2. var 1ab = 1;//Uncaught SyntaxError: Invalid or unexpected token 非法的、无效的标记

1.1.2 关键字赋值,javascript当中,关键字是无法赋值的

  1. new = 5;//Uncaught SyntaxError: Unexpected token '=' ,意外的标记
  2. function = 1;//Uncaught SyntaxError: Unexpected token '=' ,仍然是会报同样的错误

1.1.3 基本的语法错误

  1. var a = 5//Uncaught SyntaxError: Invalid or unexpected token,意外的一个冒号
  2. function 1test(){} //Uncaught SyntaxError: Invalid or unexpected token

2.1 ReferenceError 引用错误

所有函数或者变量未声明的一系列都是引用错误.

2.1.1 变量或者函数未被声明

  1. test();//Uncaught ReferenceError: test is not defined, test未被定义
  2. console.log(a);//Uncaught ReferenceError: a is not defined

2.1.2 给无法被赋值的对象赋值的时候

  1. var a = 1 = 2;//Uncaught SyntaxError: Invalid left-hand side in assignment,
  2. 赋值的左侧是无效的
  1. var a = 1;
  2. console.log(a) = 1; //Uncaught ReferenceError: Invalid left-hand side in assignment

3.1 RangeError 范围错误

3.1.1 数组长度赋值为负数的时候

  1. var arr = [1, 2, 3];
  2. arr.length = -1;//Uncaught RangeError: Invalid array length, 无效的数组的长度

3.1.2 对象方法参数超出可行范围

  1. var num = new Number(66.66);
  2. console.log(num.toFixed(-1));//Uncaught RangeError: toFixed() digits argument must be between 0 and 100,参数必须是0 ~ 100

4..1 TypeError 类型错误

4.1.1调用不存在的方法

  1. test();//Uncaught ReferenceError: test is not defined,test是未被定义的
  2. 123();//Uncaught TypeError: 123 is not a function,这就不是引用错误了,是类型错误

再例如

  1. var obj = {};
  2. obj.say();//Uncaught TypeError: obj.say is not a function,不存在这个方法,当不加括号的时候obj.say;是不会报错的,证明javascript把当作了一个属性,属性加了括号无法执行,所以报类型错误

4.1.2实例化原始值的问题

  1. var a = new 'string';//Uncaught TypeError: "string" is not a constructor,new后边必须是一个构造器,会报类型错误(同理,new一个number也不行)

5.1网络拓展

URI: UNIFORM RESOURCE IDENTIFIER
统一资源标识符
URL: UNIFORM RESOURCE LOCATOR
统一资源定位符
URN: UNIFORM RESOURCE NAME
统一资源名称

总结:URL和URN是URI的子集

  1. var myUrl = 'http://www.baidu.com?name=艾小野';
  2. var newUrl = encodeURI(myUrl);
  3. console.log(newUrl);//http://www.baidu.com?name=%E8%89%BE%E5%B0%8F%E9%87%8E,后面转的乱码就是中文编码字符
  4. var newNewUrl = decodeURI(newUrl);
  5. console.log(newNewUrl);//http://www.baidu.com?name=艾小野,还能转回来

5.2 URIError URI错误

  1. var str = decodeURI('%jierj%');//Uncaught URIError: URI malformed,翻译就是怪异的,畸形的,无法识别的。乱写,无法识别的就会报错

6.1 EvalError错误

eval()函数,不推荐使用。程序写成字符串,可以放在eval()里执行 ,例如

  1. eval('var a = 1;console.log(a);');//1

再例1

  1. var str = eval('1');
  2. console.log(str);//1

例2

  1. var obj = {
  2. a: 1,
  3. b:2
  4. }
  5. console.log(eval('obj'));//{a: 1, b: 2},打印出来的是对象
  6. console.log(eval(obj));//不打引号仍然可以执行,语法并不规范

注意,Json字符串和Json对象里面是不可以嵌有function的
例如,与后端之间对接数据:

  1. var jsonData = '['+
  2. '{'+
  3. '"name": "abc"'+
  4. '},'+
  5. '{'+
  6. '"name": "bcd"'+
  7. '},'+
  8. '{'+
  9. '"name": "efg"'+
  10. '},'+
  11. ']';
  12. console.log(jsonData);//[{"name": "abc"},{"name": "abc"},{"name": "abc"},],打印出来是这种格式
  13. var data = eval('('+ jsonData +')');
  14. console.log(data);//打印出来是完完整整的对象,eval函数最大的作用就在与此,能把Json字符串打印成Json对象
  15. for(var i in data){
  16. var item = data[i];
  17. console.log(item.name);//能够把每一项给循环打印出来
  18. }

从ES3开始就不推荐使用eval,总结不好用的几个点
1. 性能问题,带来一些小的性能问题也不是很理想,JSON.parse完全能够替代
2. 写法上语法规范不太好
3. 不好调试
4. 压缩混淆易出错
5. 容易引起xss攻击
6. 可读性差

7.1 总结

7.1.1 上述六种所有的错误都是可以手动抛出的,例如

  1. var error = new Error('代码错误了');//这是总的错误构造器
  2. console.log(error);//Error: 代码错误了,
  3. var error2 = new SyntaxError('代码出错');
  4. console.log(error2);//SyntaxError: 代码出错
  5. var error3 = new ReferenceError('代码出错了');
  6. console.log(error3);//ReferenceError: 代码出错了

7.1.2系统自动为我们抛出错误,如

  1. console.log('正常执行1');//执行
  2. console.log(a);//报错
  3. console.log('正常执行1');//无法执行到

手动抛出错误的方法 try catch finally throw

  1. try{
  2. console.log('正常执行1');
  3. console.log(a);
  4. console.log('正常执行1');
  5. }catch(e){//try正常执行,没有错误的时候,是不走catch的。catch的作用是捕获错误
  6. console.log(e);//ReferenceError: a is not defined
  7. console.log(e.name);//ReferenceError,打印的是错误的类型
  8. console.log(e.message);//a is not defined
  9. }finally{//不管try有无报错,finally都会正常执行
  10. console.log('正常执行3');//正常执行3
  11. }
  12. console.log('正常执行4');//正常执行4,还是能正常执行的,try里面报错不影响外面的程序执行

2. ECMAscript 发展历程

  1. 年份 版本<br /> 97 1.0<br /> 98 2.0<br /> 99 3.0 JS通行标准<br /> 07 4.0草案 <br /> 08 4.0中止 容易改善的部分放到3.1 激进部分另著Harmony<br /> 09 5.0发布 Harmony -> 其中1/2 JS.next ,另1/2JS.next.next<br /> 11 5.1 ISO国际标准<br /> 13 ES6 = js.next js.next.next ES7<br /> 13 ES6草案发布 <br /> 15 ES6正式发布,ESMAScript2015

3.ES5严格模式

3.1

ES3.0 加了严格模式
IE9及以下不支持严格模式

直接用字符串表示,启动就写在脚本的最上面一行

  1. 'use strict'

但在函数内部写是被推荐的

  1. function test(){
  2. 'use strict'
  3. }

3.2 with()

with()方法能改变作用域,(能改变作用域链的顶端)例如

  1. var a = 1;
  2. var obj = {
  3. a: 2
  4. }
  5. function test(){
  6. var a = 3;
  7. with(test){//填obj,打印2;填window,打印1;也就是说with里面填哪个作用域,就会去找相应作用域里面的a
  8. console.log(a);//3
  9. }
  10. }
  11. test();

但是开启严格模式with()就会报错

  1. 'use strict';
  2. var a = 1;
  3. var obj = {
  4. a: 2
  5. }
  6. function test(){
  7. var a = 3;
  8. with(test){//填obj,打印2;填window,打印1
  9. console.log(a);//3
  10. }
  11. }
  12. test();
  13. //Uncaught SyntaxError: Strict mode code may not include a with statement,严格模式的代码是不能包含with方法的

关闭严格模式,不报错

  1. //'use strict';
  2. var a = 1;
  3. var obj = {
  4. a: 2
  5. }
  6. function test(){
  7. var a = 3;
  8. var b = 4;
  9. with(window){//填obj,打印2;填window,打印1。(括号里面必须填值,否则报错)
  10. console.log(a);//1
  11. console.log(b);//4,b也能打印出来
  12. }
  13. }
  14. test();

3.3 严格模式下caller和callee会报错,例如

callee

  1. 'use strict';
  2. function test(){
  3. //console.log(arguments);//arguments严格模式下能用
  4. console.log(arguments.callee);//Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
  5. }
  6. test1();

caller

  1. 'use strict';
  2. function test1(){
  3. test2();
  4. }
  5. test1();
  6. function test2(){
  7. console.log(test1.caller)//报错同上
  8. }

3.4 严格模式的变量声明

严格模式下不写var 声明变量会报错,报引用错误

  1. 'use strict';
  2. a = 1;//Uncaught ReferenceError: a is not defined

声明变量写在下面,变量提升是不报错的

  1. 'use strict';
  2. a = 1;
  3. var a;

这样写也是会报错(写在函数内部也是如此)

  1. 'use strict';
  2. var a = b = 1;//b is not defined

3.5 严格模式下的this

严格模式下的this是指向window的

  1. 'use strict';
  2. console.log(this);//Window

写在函数内部的this非严格模式是指向window,开启严格模式是undefined

  1. 'use strict';
  2. function test(){
  3. console.log(this);//undefined
  4. }
  5. test();

但是构造函数不报错,下面的this指向test1了(所以严格模式下this必须赋值,不赋值就是undefined)

  1. 'use strict';
  2. function test(){
  3. console.log(this);
  4. }
  5. var test1 = new test();//test {}

3.6 严格模式下的参数不能重复

例如,非严格模式下

  1. function test(a, a){
  2. console.log(a);//2
  3. }
  4. test(1, 2);

严格模式下,报错

  1. 'use strict';
  2. function test(a, a){
  3. console.log(a);//Uncaught SyntaxError: Duplicate parameter name not allowed in this context,在严格模式下,重复的参数名是不能被通过的
  4. }
  5. test(1, 2);

3.7 严格模式下对象的属性名也是不能重复的

  1. 'use scrict';
  2. var obj = {
  3. a: 1,
  4. a: 2
  5. }
  6. console.log(obj.a);//2

不报错,但是ES5的严格模式下对象的属性名是不允许重复的

3.8 严格模式下的eval()

  1. 'use strict';
  2. eval('var a = 1; console.log(a);');//1

这样写是不报错的。
———————————————————————分隔符—————————————————————————
不开启严格模式这样写是不报错且能打印的

  1. eval('var a = 1; console.log(a);');
  2. console.log(a);//1

但是开启严格模式会报错

  1. 'use strict';
  2. eval('var a = 1; console.log(a);');
  3. console.log(a);//Uncaught ReferenceError: a is not defined

实际上在严格模式下eval()是有自己独立的作用域的,eval的代码块的作用域不再是全局的了,第三行的a是访问不到的。在非严格模式下eval里面写的代码块的作用域是在全局中定义的

4. 重点

  1. function test(){
  2. console.log(this);//Number {1}
  3. }
  4. test.call(1);

this的赋值必须要通过call来赋值, call里面写的即使不是对象是原始值,会变成对象。因为call本身就是改变this指向,this肯定是个对象,所以call填任何的值都会做相应的做包装类的形式来改变,所以填1就包装类成Number对象了