18-错误信息、try_catch、严格模式

(一)、JS错误信息类型

1、SyntaxError 语法错误
(1)变量名不规范

var 1 = 1;

var 1ab = 1;

(2)关键字赋值(在JavaScript中关键字是不允许赋值的)

new = 5;

function = 1;

(3)基本的语法错误

var a = 5:

function 1test(){}

2、ReferenceError 引用错误
(1)变量或函数未被声明

test();

console.log(a);

(2)给无法被赋值的对象赋值的时候

var a = 1 = 2;

3、范围错误

RangeError 范围错误

(1)数组的长度赋值为负数

var arr = [1, 2, 3];

arr.length = -1;

console.log(arr);

(2)对象方法参数超出可行范围

var num = new Number(66.66);

console.log(num.toFixed(-1));

4、TypeError 类型错误
(1)调用不存在的方法

123();

var obj = {};

obj.say();

如果没有相对应的方法,JavaScript会认为它是一个属性。

对象的属性被执行了,这肯定是一个类型错误

obj.say;没有括号不报错,证明JavaScript认为这是一个属性,只是没有赋值,

一旦后面打了括号,它就认为这是一个属性,属性后面做了一个执行,就会报类型错误。

(2)实例化原始值

var a = new ‘string’;

5、URIError URI错误

URI:UNIFORM RESOURCE IDENTIFER 统一资源标识符

URL: UNIFORM RESOURCE LOCATOR 统一资源定位符

URN: UNIFORM RESOURCE NAME 统一资源名称

URL就像一个地址一样,通过这个地址可以拜访到你家里,

换做网页来说其实就是通过URL能访问到特定的页面

URL: http://www.baidu.com/news#today

​ ftp://www.baidu.com/ftp#developer

URN其实就相当于一个ID,代表资源的唯一标识

​ www.baidu.com/ftp#developer

href="tel:13900000000"这也是URN但是它不是URL,它并不指代一个特定的可访问的资源

前面的tel是一个途径,在程序编程里代表一个方法

href=“mailto:523579987@qq.com” 这个也代表的是URN,是一个资源的名称,通过它是无法访问一个特定的地址或者执行特定的程序的。别看点击a标签以后弹出一个写邮件的界面,不是它弹出来的,这是程序自执行依靠URN这个标识去执行去调用的,而不是它自己去访问的。

//encodeURI中文字转换为中文编码字符
//var myUrl = 'http://www.baidu.com?name=张三';
var myUrl = '张三'; //下面这种写法也能转化 URN的定义是唯一标识,这个唯一标识写什么都可以
                     //下面是URI不是URL,是因为URL必须是网址。URI是资源标识,只要是你自己自定义的资源标											//识,URI也不能判断这里面有没有资源
var newUrl = encodeURI(myUrl);
console.log(newUrl);

//encodeURI中文编码字符转换为中文字
var newNewUrl = decodeURl(newUrl);
console.log(newNewUrl);

var str = decodeURI(’%fdsdf%’); //自己乱写一个URI就会报错

malformed畸形的怪异的,不符合常规的。

6、EvalError eval函数执行错误
eval('var a = 1; console.log(a)');//程序可以写成一个字符串,放在eval里面就能执行(这是最牛的地方)
//------------------------
var str = eval('1');
console.log(str); //1
//------------------------
var obj = {
  a: 1,
  b: 2
}

console.log(eval('obj')); //{a: 1, b: 2}   打印出来的是对象
console.log(eval(obj)); //不加引号也会打印出相同的结果,这个代码的规范不对,
                        //eval里面其实是字符串,不放字符串也行,es3.0就不建议用,5.0就更不建议用了

eval最大的作用:

json数据一般都是用双引号,这跟后端的转译有关系,

后端传回来的JSON字符串都是用双引号,所以前端都是用双引号

<!--在JavaScript中JSON又是一个对象,下面这种形式就是一个JSON对象,用引号括起来就变成JSON字符串了-->
<script>

var obj = {
   "a": 1,
   "b": 2
}
/*如果添加了方法,就不再是JSON对象或着JSON字符串了,JSON对象和JSON字符串是不可以嵌有方法的
这么写就变成一个普通的对象了。
这也是JSON对象跟普通对象的区别。JSON对象是不可以有方法的
JSON对象JSON数据是干嘛用的?是用来存储数据的*/
var obj = {
   "a": 1,
   "b": 2,
   "say": function(){
   
   }
}
</script>
<script type="text/javascript">
    	var jsonData = '['+
    		'{'+
    			'"name" : "abc"'+
    		'},'+
    		'{'+
    			'"name" : "bcd"'+
    		'},'+
    		'{'+
    			'"name" : "efg"'+
    		'}'+
    	']';

    	console.log(jsonData); //[{"name" : "abc"},{"name" : "bcd"},{"name" : "efg"}]
    	
</script>

eval可以将JSON字符串变为对象形式

<script type="text/javascript">
    	var jsonData = '['+
    		'{'+
    			'"name" : "abc"'+
    		'},'+
    		'{'+
    			'"name" : "bcd"'+
    		'},'+
    		'{'+
    			'"name" : "efg"'+
    		'}'+
    	']';

    	var data = eval('('+jsonData+')');
    	console.log(data);
</script>
   <script type="text/javascript">
    	var jsonData = '['+
    		'{'+
    			'"name" : "abc"'+
    		'},'+
    		'{'+
    			'"name" : "bcd"'+
    		'},'+
    		'{'+
    			'"name" : "efg"'+
    		'}'+
    	']';

    	var data = eval('('+jsonData+')');

    	for(var i in data){
    		var item = data[i];
    		console.log(item.name);
    	}
   </script>

为什么不建议使用eval?

1、语法规范不好,加字符串可以,不加字符串也能执行

2、eval不好调试,以后学到断点调试会发现eval非常难调试

3、性能问题,eval带来一些小的性能问题,也是不太理想的,

现在JSON.parse也可以做到相同的事情。

4、eval有时候代码压缩混淆会出错,这是不太理想的事情,因为现在基本上

都会做代码压缩或者混淆,eval老是报错就不太理想了,当然也不一定,它是意外错误,报意外错误

5、些许的安全性问题,比较容易引起XSS的攻击,

这不是eval函数本身的问题,可能跟写的代码本身不安全也有关系

eval跟input标签合用的时候,input获取的值和eval相绑定的话就会出一些安全性的隐患

6、可读性差

六种错误都可以人为地抛出

 <script type="text/javascript">
    var error = new Error('代码错误了');
    console.log(error);
 </script>

 <script type="text/javascript">
    var error = new SyntaxError('代码错误了');
    console.log(error);
 </script>

<script type="text/javascript">
    var error = new ReferenceError('代码错误了');
    console.log(error);
</script>
<script type="text/javascript">
    var error = new TypeError('代码错误了');
    console.log(error);
</script>

(二)、try_catch

手动抛出异常的方法

try catch finally throw

finally throw可以不写

<script type="text/javascript">
    try{
    	console.log('正常执行1');
    	console.log(a);
    	console.log(b);
    	console.log('正常执行2');
    }catch(e){
    	console.log(e.name + ':' +e.message);
    }finally{
    	console.log('正常执行3'); // 会执行
    }
    console.log('正常执行4'); // 也会执行
</script>

不管try里面有错没错,finally都会执行,这就多了一种可能性,

多了一种处理程序的可能性,try里面的内容和finally里面的内容是不太相关的,

把可能会出错的部分放到try,一定要执行的放到finally,这样错误就不会影响下面程序的执行。

finally的意义也就是外界的意义,写在外面和写在finally里面没有区别。

finally存在的意义也不是特别的大,只是说看起来比较工整一些,有一种序列化的感觉。

  <script type="text/javascript">
    var jsonStr = '';

    try{
    	console.log('我要执行啦!!!!');
    	var json = JSON.parse(jsonStr); //JSON.parse里面是不能给空字符串的
    	console.log(json);
    }catch(e){
    	console.log(e);
    }
  </script>

 <script type="text/javascript">
    var jsonStr = '';

    try{
    	console.log('我要执行啦!!!!');
    	var json = JSON.parse(jsonStr);
    	console.log(json);
    }catch(e){
    	var errorTip = {       //如果做过微信、QQ登录第三方的API接入 这是提示信息集合(对象的形式)
         name: '数据传输失败',
         errorCode: '10010'
      }
      console.log(errorTip);
    }
   </script>

throw

可以通过throw去自定义错误信息,e的抛出实际上是可以自定义的,throw就是抛出错误信息的意思。

 <script type="text/javascript">
    var jsonStr = '';

    try{
      if(jsonStr == ''){
         throw 'JSON字符串为空'
      }
    	console.log('我要执行啦!!!!');
    	var json = JSON.parse(jsonStr);
    	console.log(json);
    }catch(e){
      console.log(e);
    }
   </script>

try catch在比较大型的程序插件里面用得比较多,自定义这些错误,能够让使用插件的开发者详细了解

里面的错误机制是什么。这种用try catch做是最好的。一般开发程序中,try catch用得不是太多,但是千万不要认为它没有用,非常有用,只是应用场景可能没有其他的东西那么多,也不是说它不用,或者说用得少。

(三)、严格模式

ECMAScript 其实就是JavaScript的语法规范和方法规范

1997年 1.0 1998年 2.0 1999年 3.0

3.0到现在为止都统治着JavaScript ES5所有的语法基础所有的方法所有的JavaScript基础部分

都是基于3.0的。ES5实际上并没有对3.0进行十分多的修改与更新。

3.0是JS的通行标准,3.0在99年已经奠定了它是一个标准了。

这门语言的雏型已经完全定下来了。

2007年

​ 出的4.0是一个草案,因为每个版本发布要跟各个浏览器厂商和机构进行讨论

这次讨论出现了问题,ECMA在制定这个草案的时候非常激进,有很多功能很前卫很复杂,

让很多浏览器不能接受。改一次浏览器的版本,升级一次,要让用户去更新,相当困难,历程久。

所以说一个版本的更新如果太过激进对于各个浏览器厂商的利益是有巨大的损害的。

这个时候雅虎、微软、谷歌就相当反对,只有一个公司是支持的Mozilla,就是现在的firefox公司

mozilla 之所以支持是 JavaScript的作者 Branden Eich在这个公司

2008年

​ 的时候 4.0就终止了,终止不代表废除,将容易改善的部分放在了3.0中,发布了3.1

那些不容易改善的激进的部分专门给了一个版本代号 Harmony(和谐的意思),这个版本没有发布。

07年因为4.0吵架吵的非常厉害。

这个会开了以后,3.1更名为ECMAScript5 其实是3.0变成3.1,直接更名为5,但是更名

为5以后,这个版本还是没发布,因为就3.1中的东西没有达成一致。

2009年

​ ECMAScript5.0正式发布。harmony分成了两部分,一部分是激进当中不是那么激进的一部分更名为JS.NEXT,另外一部分叫JS.next.next。

2011年

​ 5.1发布,成为ISO国际标准,这是继3.0以来,唯一一个和3.0地位相同的版本,

而且5.1几乎是基于3.0的

2013年

​ ES6不再增添任何的东西,它就等于js.next

​ Js.next.next ->7

2013年

​ ES6草案发布

2015年

​ ES6正式发布 也叫ECMAScript2015

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uVlY5ctJ-1638971643904)(/Users/liruize/Library/Application Support/typora-user-images/image-20211008235516555.png)]

​ 从ES5开始,运行方式有两种,一种是正常模式,另一种是严格模式。

提醒大家:ie 9 及以下是不支持严格模式的。

3.0太早了,语法的严谨和合理性有不足的地方,还有一些怪异的行为,

ES5对效率问题非常关注,JavaScrip效率t在5.0发布以后是一个质的飞跃,那个时候JavaScript已经火起来了

ES5已经具有前瞻性,为以后的版本做铺垫,推出了一种模式叫严格模式,也就是说按照ES5语法的规范来运行程序,在3.0的基础上增加了严格模式,也就是说有些时候在正常模式下运行没有问题的,但是在ES5底下会报错,或者运行不正常。

严格模式的表现非常简单,就是在脚本里写
'use strict';
为什么要写个字符串呢?
写'123'; 123;不会报错,因为它们在JavaScript中是表达式,怎么写都有道理。
为什么用这种形式来写呢?
如果浏览器不支持,不至于报错,综上所述用字符串是最合理的。

如果是整个脚本启动,在脚本的最上一行写’use strict’;

还有一种是在函数内部或模块启动严格模式,这种是推荐的。

with()方法在3.0就有了,可以改变作用域。记住有这么个东西,以后用不到。

<script type="text/javascript">
    // 'use strict';

    var a = 1;
    var obj = {
      a: 2
    }

    function test(){
      var a = 3;
      var b = 4;
      with(window){
        console.log(a);//1
        console.log(b);//4
      }
    }
    test();
   </script>

开启严格模式会报错:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xufxGqYs-1638971643905)(/Users/liruize/Library/Application Support/typora-user-images/image-20211009083627721.png)]

命名空间

用原生JS做模块化开发

  <script type="text/javascript">
     
    window.onload = function(){
      init();
    } 

    function init(){
      initSlider;
      initSideBar;
    }

     var initSlider = (function(){
      var a = 1;
      console.log(a);
     })();


     var initSideBar = (function(){
      var a = 2;
      console.log(a);
     })();
   </script>

以前的做法:

实际上以前是用对象来做的

   <script type="text/javascript">
     
    var namespace = {
      header:{
        Jenny: {
          a: 1,
          b: 2
        },
        Ben:{
          a: 3,
          b: 4
        }
      },
      sideBar:{
        Crystal: {
          a: 5,
          b: 6
        }
      }
    }
  
    with(namespace.header.Ben){
      console.log(a);
    }

   </script>

现在基本上是用webpack来做,完全地模块化组件化来写。

with是改变作用域的,正因为它改变作用域的作用域链,所以引起了很大的性能问题,

因为建立一个作用域消耗性能,在ES5的严格模式下是不支持with的使用的。

caller(调用方) callee(被调用方)以及arguments的部分属性在严格模式下不能使用。

   // 'use strict';
    
    function test(){
     console.log(arguments.caller);
    }
    test();
    // 'use strict';
    
    function test1(){
      test2();
    }
    test1();

    function test2(){
      console.log(test2.caller);
    }

在严格模式下必须要声明变量

   'use strict';

    a = 1;

严格模式下变量也是会提升的

 'use strict';

  a = 1;
  var a;

严格模式下这种写法也是会报错的

 'use strict';

  var a = b = 1; // b is not defined

也会报错

function test(){
	var a = b = 1;
}
test();

在严格模式下

'use strict';
 console.log(this); // 指向window

函数内部的this必须赋值,否则就是undefined

'use strict';

function test(){
	console.log(this); // 非严格模式下指向window,严格模式下指向undefined
}
test();

在严格模式下this的赋值必须通过call来赋值

'use strict';

function test(){
  // this = 1;  错误的
	console.log(this); // 非严格模式下指向window,严格模式下指向undefined
}
test.call(1);

在非严格模式下,call里面写的不是对象,写的是原始值,也会给你变成一个对象

call本身是改变this的指向,this指向肯定是一个对象。

在非严格模式下,如果填的是原始值,会通过包装类,包装成对象。

     function test(){
        console.log(this);
     }
     test.call(1);

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

'use strict';
     
function test(a,a){
        console.log(a);
}
test(1,2);

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

虽然不报错,但是拒绝你使用重复的属性名

     'use strict';

     var obj = {
      a: 1,
      a: 2
     }

     console.log(obj.a);

在严格模式下,eval有自己独立的作用域

     'use strict';

     eval('var a = 1;console.log(a)'); //1
     console.log(a);//报错 a is not defined

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值