1. JS错误信息类型
1.1 SyntaxError 语法错误
1.1.1 变量名不规范,如
var 1 = 1;//Uncaught SyntaxError: Unexpected number 未被捕获的语法错误,翻译就是被抛出的错误:具体的类型是意外的数字var 1ab = 1;//Uncaught SyntaxError: Invalid or unexpected token 非法的、无效的标记
1.1.2 关键字赋值,javascript当中,关键字是无法赋值的
new = 5;//Uncaught SyntaxError: Unexpected token '=' ,意外的标记function = 1;//Uncaught SyntaxError: Unexpected token '=' ,仍然是会报同样的错误
1.1.3 基本的语法错误
var a = 5://Uncaught SyntaxError: Invalid or unexpected token,意外的一个冒号function 1test(){} //Uncaught SyntaxError: Invalid or unexpected token
2.1 ReferenceError 引用错误
2.1.1 变量或者函数未被声明
test();//Uncaught ReferenceError: test is not defined, test未被定义console.log(a);//Uncaught ReferenceError: a is not defined
2.1.2 给无法被赋值的对象赋值的时候
var a = 1 = 2;//Uncaught SyntaxError: Invalid left-hand side in assignment,赋值的左侧是无效的
var a = 1;console.log(a) = 1; //Uncaught ReferenceError: Invalid left-hand side in assignment
3.1 RangeError 范围错误
3.1.1 数组长度赋值为负数的时候
var arr = [1, 2, 3];arr.length = -1;//Uncaught RangeError: Invalid array length, 无效的数组的长度
3.1.2 对象方法参数超出可行范围
var num = new Number(66.66);console.log(num.toFixed(-1));//Uncaught RangeError: toFixed() digits argument must be between 0 and 100,参数必须是0 ~ 100
4..1 TypeError 类型错误
4.1.1调用不存在的方法
test();//Uncaught ReferenceError: test is not defined,test是未被定义的123();//Uncaught TypeError: 123 is not a function,这就不是引用错误了,是类型错误
再例如
var obj = {};obj.say();//Uncaught TypeError: obj.say is not a function,不存在这个方法,当不加括号的时候obj.say;是不会报错的,证明javascript把当作了一个属性,属性加了括号无法执行,所以报类型错误
4.1.2实例化原始值的问题
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的子集
var myUrl = 'http://www.baidu.com?name=艾小野';var newUrl = encodeURI(myUrl);console.log(newUrl);//http://www.baidu.com?name=%E8%89%BE%E5%B0%8F%E9%87%8E,后面转的乱码就是中文编码字符var newNewUrl = decodeURI(newUrl);console.log(newNewUrl);//http://www.baidu.com?name=艾小野,还能转回来
5.2 URIError URI错误
var str = decodeURI('%jierj%');//Uncaught URIError: URI malformed,翻译就是怪异的,畸形的,无法识别的。乱写,无法识别的就会报错
6.1 EvalError错误
eval()函数,不推荐使用。程序写成字符串,可以放在eval()里执行 ,例如
eval('var a = 1;console.log(a);');//1
再例1
var str = eval('1');console.log(str);//1
例2
var obj = {a: 1,b:2}console.log(eval('obj'));//{a: 1, b: 2},打印出来的是对象console.log(eval(obj));//不打引号仍然可以执行,语法并不规范
注意,Json字符串和Json对象里面是不可以嵌有function的
例如,与后端之间对接数据:
var jsonData = '['+'{'+'"name": "abc"'+'},'+'{'+'"name": "bcd"'+'},'+'{'+'"name": "efg"'+'},'+']';console.log(jsonData);//[{"name": "abc"},{"name": "abc"},{"name": "abc"},],打印出来是这种格式var data = eval('('+ jsonData +')');console.log(data);//打印出来是完完整整的对象,eval函数最大的作用就在与此,能把Json字符串打印成Json对象for(var i in data){var item = data[i];console.log(item.name);//能够把每一项给循环打印出来}
从ES3开始就不推荐使用eval,总结不好用的几个点
1. 性能问题,带来一些小的性能问题也不是很理想,JSON.parse完全能够替代
2. 写法上语法规范不太好
3. 不好调试
4. 压缩混淆易出错
5. 容易引起xss攻击
6. 可读性差
7.1 总结
7.1.1 上述六种所有的错误都是可以手动抛出的,例如
var error = new Error('代码错误了');//这是总的错误构造器console.log(error);//Error: 代码错误了,var error2 = new SyntaxError('代码出错');console.log(error2);//SyntaxError: 代码出错var error3 = new ReferenceError('代码出错了');console.log(error3);//ReferenceError: 代码出错了
7.1.2系统自动为我们抛出错误,如
console.log('正常执行1');//执行console.log(a);//报错console.log('正常执行1');//无法执行到
手动抛出错误的方法 try catch finally throw
try{console.log('正常执行1');console.log(a);console.log('正常执行1');}catch(e){//try正常执行,没有错误的时候,是不走catch的。catch的作用是捕获错误console.log(e);//ReferenceError: a is not definedconsole.log(e.name);//ReferenceError,打印的是错误的类型console.log(e.message);//a is not defined}finally{//不管try有无报错,finally都会正常执行console.log('正常执行3');//正常执行3}console.log('正常执行4');//正常执行4,还是能正常执行的,try里面报错不影响外面的程序执行
2. ECMAscript 发展历程
年份 版本<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及以下不支持严格模式
直接用字符串表示,启动就写在脚本的最上面一行
'use strict'
但在函数内部写是被推荐的
function test(){'use strict'}
3.2 with()
with()方法能改变作用域,(能改变作用域链的顶端)例如
var a = 1;var obj = {a: 2}function test(){var a = 3;with(test){//填obj,打印2;填window,打印1;也就是说with里面填哪个作用域,就会去找相应作用域里面的aconsole.log(a);//3}}test();
但是开启严格模式with()就会报错
'use strict';var a = 1;var obj = {a: 2}function test(){var a = 3;with(test){//填obj,打印2;填window,打印1console.log(a);//3}}test();//Uncaught SyntaxError: Strict mode code may not include a with statement,严格模式的代码是不能包含with方法的
关闭严格模式,不报错
//'use strict';var a = 1;var obj = {a: 2}function test(){var a = 3;var b = 4;with(window){//填obj,打印2;填window,打印1。(括号里面必须填值,否则报错)console.log(a);//1console.log(b);//4,b也能打印出来}}test();
3.3 严格模式下caller和callee会报错,例如
callee
'use strict';function test(){//console.log(arguments);//arguments严格模式下能用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}test1();
caller
'use strict';function test1(){test2();}test1();function test2(){console.log(test1.caller)//报错同上}
3.4 严格模式的变量声明
严格模式下不写var 声明变量会报错,报引用错误
'use strict';a = 1;//Uncaught ReferenceError: a is not defined
声明变量写在下面,变量提升是不报错的
'use strict';a = 1;var a;
这样写也是会报错(写在函数内部也是如此)
'use strict';var a = b = 1;//b is not defined
3.5 严格模式下的this
严格模式下的this是指向window的
'use strict';console.log(this);//Window
写在函数内部的this非严格模式是指向window,开启严格模式是undefined
'use strict';function test(){console.log(this);//undefined}test();
但是构造函数不报错,下面的this指向test1了(所以严格模式下this必须赋值,不赋值就是undefined)
'use strict';function test(){console.log(this);}var test1 = new test();//test {}
3.6 严格模式下的参数不能重复
例如,非严格模式下
function test(a, a){console.log(a);//2}test(1, 2);
严格模式下,报错
'use strict';function test(a, a){console.log(a);//Uncaught SyntaxError: Duplicate parameter name not allowed in this context,在严格模式下,重复的参数名是不能被通过的}test(1, 2);
3.7 严格模式下对象的属性名也是不能重复的
'use scrict';var obj = {a: 1,a: 2}console.log(obj.a);//2
3.8 严格模式下的eval()
'use strict';eval('var a = 1; console.log(a);');//1
这样写是不报错的。
———————————————————————分隔符—————————————————————————
不开启严格模式这样写是不报错且能打印的
eval('var a = 1; console.log(a);');console.log(a);//1
但是开启严格模式会报错
'use strict';eval('var a = 1; console.log(a);');console.log(a);//Uncaught ReferenceError: a is not defined
实际上在严格模式下eval()是有自己独立的作用域的,eval的代码块的作用域不再是全局的了,第三行的a是访问不到的。在非严格模式下eval里面写的代码块的作用域是在全局中定义的
4. 重点
function test(){console.log(this);//Number {1}}test.call(1);
this的赋值必须要通过call来赋值, call里面写的即使不是对象是原始值,会变成对象。因为call本身就是改变this指向,this肯定是个对象,所以call填任何的值都会做相应的做包装类的形式来改变,所以填1就包装类成Number对象了
