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 defined
console.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里面填哪个作用域,就会去找相应作用域里面的a
console.log(a);//3
}
}
test();
但是开启严格模式with()就会报错
'use strict';
var a = 1;
var obj = {
a: 2
}
function test(){
var a = 3;
with(test){//填obj,打印2;填window,打印1
console.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);//1
console.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对象了