JavaScript之错误处理,函数对象

1.*错误处理:

        错误:程序执行过程中,发生的导致程序无法继续执行的状态

        错误处理:即使程序出错,也要保证程序不退出的机制

        Error对象:在发生错误时,*自动创建的封装错误信息的对象

                  属性:err.name:错误类型:6种

                            SyntaxError:语法错误

                            RefernceError: 引用错误,找不到对象或变量时

                            TypeError:类型错误,错误的使用了对象的*方法

                            RangeError:范围错误,参数超范围

                            EvalError:Eval错误

                            URIError:URI错误

        

         如何错误处理:语法:

  try{
      可能出错的语句;
  }catch(err){
      一旦出错,执行的错误处理代码;
  }[finally{
  无论是否出错,都要执行的代码;  
}]
  

            强调:被try包裹的代码,执行效率会降低;所以,try应尽量少的包裹代码

     #笔试题:***js中如何解决浏览器兼容性问题:3种

                1.不兼容的类型或方法:2种:

                       if else

                       try catch

                 2.不兼容的值:短路逻辑中的||:

                      值1||值2

  

        IETester问题:

                1.只支持document.write输出

                 2.只要出错,当前窗口不能继续使用,必须重新打开窗口

                 3.将网页文件拖拽到窗口内,自动加载

***案例:异常处理中的return

                 1.finally中的return,会替换try catch中的return

                  2.即使finally中没有return,finally中的代码一定会在return前执行,但无法影响已确定的return结果

 不报错时:

/*笔试题:错误处理中的return*/
var n=1;
function fun() {
    try {
        return n;//return --等待
    } catch (err) {
        n++;
    } finally {
        n++;//2
       // return n;
    }
}
console.log(fun());//1
console.log(n);//2
报错时:

 var n=1;
function fun() {
    try {
          m++;
        return n;//3
    } catch (err) {
        n++;
    } finally {
        n++;//3
        return n;//3
    }
}
console.log(fun());//3
console.log(n);//3

抛出:自定义错误:

             何时使用:方法定义者向方法调用者抛出使用错误

             如何抛出:throw new Error(“错误消息”)             


1*****函数对象:

           执行环境栈:ECS,保存全局以及每个函数的执行环境的栈结构

           执行环境:EC 调用函数时,创建的引用函数资源的对象

                       窗口一打开,默认ECS中压入一个全局EC;全局EC应用了window对象VO;window对象中的变量都是全局变量

            变量对象:VO,专门存储变量的对象

     函数的生命周期:

            定义时:仅创建一个函数对象,封装了函数的定义,不会读取函数的内容

            调用时:创建函数的EC对象压入ECS中,函数的EC对象引用了,当前函数的活动对象AO

                   活动对象:AO,专门保存本次函数调用时的局部变量;AO中有一个属性始终指向window对象

                   变量使用的规则:优先在AO中找,找不到,才去window对象找

           调用后:函数的EC对象出栈,AO对象失去引用,被回收;AO对象中的局部变量一起被释放

  ***重载:overload

        相同名称,不同参数列表的多个函数

        在调用时,可根据传入的参数的不同,动态选择对应的函数执行

    js语法默认不支持重载,但是可用arguments对象模拟重载的效果

   arguments对象:调用时,自动接收所有传入的参数值,类(like)数组(的)对象

               2点:1.arguments[i]   2.argument.length获得个数

function calc(){
      if(arguments.length>=2){
          return arguments[0]+arguments[1];
      }else {
          return arguments[0]*arguments[0];
      }
  }
    console.log(calc(12,23));
    console.log(calc(13));
           何时使用:今后只要多个操作,公用一个函数名时,皆能使用

         ***类数组对象      vs      数组对象

             类型不同:类数组对象的父类型时Object;数组对象的父类型是Array   -->导致类数组对象无法使用数组类型的方法

           类数组对象 to Array固定套路:

               var arr=Array.prototype.slice.apply(arguments);

           为什么还要定义参数:作用:2个

                  1.提示调用者,改如何传入参数

                  2.简化函数定义,在函数内使用参数值

             结论:今后大部分方法依旧要定义参数,只有不确定传入值个数时,才省略参数,用arguments


****匿名函数:定义时,没有任何变量引用的函数

         何时使用:2种情况:

         1.如果一个函数只执行一次         --匿名函数自调

             语法:(function(参数变量){函数体:return 返回值})(参数值)

         2.如果一个函数作为对象交给其他函数使用时     --回调

             创建一个比较函数:3种:

              1.声明方式定义函数:function compare(a,b){return a-b}

                     ***只有声明方式定义的函数才能被声明提前

                     ***以下两种方式定义的函数都不能被提前

              2.函数直接量方式定义:var compare=function(a,b){return a-b};

              3.使用new 关键字:var compare=new Function("a","b","return a-b");   --ps:引号必须要加

var arr=[2,12,123,33,23,3,1];
  /*用三种方法定义比较器函数对象 */
/*  function compare(a,b){return a-b};*/
 /* var compare=function(a,b){return a-b};*/
  var compare=new Function("a","b","return a-b");
arr.sort(compare);
    console.log(arr);
     惯例写法:回调               

arr.sort(function(a,b){return a-b;});
       匿名函数优点:节约内存空间;调用前和调用后,内存中不创建任何函数对象

       2.自调

/*自调*/
  (function(){
      alert("开始加载。。。");
  })();
     案例:运用遍历和累加

/*定义add函数,可接受任意个数字参数,求所有数字参数的和*/
function add(){
    //遍历arguments中每个参数值,同时声明sum=0
    for(var i= 0,sum=0;i<arguments.length;i++){
        sum+=arguments[i];
    }
    //将当前参数值累计到sum中

    //返回sum
    return sum;
}
  console.log(add(1,2,3));
  console.log(add(1,2,3,5,2,9,7));
  console.log(add(1,2,3,8,7,5,3,2));

****作用域和作用域链:

        作用域:一个变量的可用范围,其实就是变量的实际存储位置;只能是window中或AO中

             window:全局作用域  ---全局变量

            AO:函数作用域           ---局部变量

            本质:EC对象的一个scope属性,引用了window或AO对象

       作用域链:已当前EC的scope属性为起点依次应用每个AO,直到window结束,形成的多级引用关系;只要在作用域链上存在的变量,当前函数都可以使用


*****闭包:

     问题:全局变量  vs  局部变量

        全局变量:

               优:反复使用,且共享使用

               缺:可能随时在任意位置被篡改   --全局污染

              建议:尽量避免使用全局变量

       局部变量:特点:不可反复使用,方法调用完自动释放

       解决方案:闭包:反复使用一个局部变量,且不会被污染

       何时使用:想反复使用一个局部变量,且不希望被污染时,就要用闭包结构保护局部变量

       如何使用:3步:

        1.定义外部函数(工厂函数)

               特点:2步:

                    1.定义了受保护的局部变量

                    2.返回一个专门操作局部变量的内部函数对象

        2.调用外层函数(工厂函数),获得返回的内部函数对象

        3.使用获得的内部函数对象,操作受保护的局部变量      --ps:唯一途径

//定义工厂函数保护局部变量
    function factory(){
        var n=0;//受保护局部变量
        return function (){ return ++n;}
    }
var ccb=factory();
    //ccb:function(){return ++n;}
    console.log(ccb());//使用变量
       

   判断闭包输出结构:

       1.找受保护的局部变量

       2.外层函数被调用几次,就创建了几个受保护的变量副本

       3.同一次外层函数调用返回的内层函数,总使用同一个局部变量

function fun(){
    for(var i= 0,arr=[];i<3;i++){
        arr[i]=function(){return i;}
        //i=3
    }
    return arr;
}
    var funs=fun();//外层函数调用1次,只有一个受保护的变量i=3
/*funs=[
 function(){return i;}
 function(){return i;}
 function(){return i;}
 同一次外层函数调用,返回的所有函数对象,使用相同一个受保护的局部变量
]

* */
  console.log(funs[0]());//3
  console.log(funs[1]());//3
  console.log(funs[2]());//3

 过程图: 

      

笔试题:

/*汇率转换:定义外层函数,创建人民币对指定汇率的转换器函数*/
function factory(rate){
     return function (money){ //返回一个函数对象,接收一个参数
        return (money/rate).toFixed(2);//函数体:返回money/rate,保留2位小数
    }
}
var rmb2$=factory(6.1);
console.log(rmb2$(6000));


    var rmb2euro=factory(10);
    console.log(rmb2euro(8684));

 例2:

/*getter/setter访问器:
* 获取或设置一个变量的值专门方法
* get变量名/set变量名
* */

     var getSalary,setSalary;//专门操作salary变量的访问器
    function factory(){
        //保护一个局部变量salary,初始为0
        var salary=0;
        //为getSalary变量赋值一个函数对象
        getSalary=function(){
            //函数体:返回salary的值,前面加“¥”,后面保留两位小数
            return "¥"+salary.toFixed(2);
        };
        //为setSalary变量赋值函数对象,接收一个value参数
        setSalary=function(value){
            //函数体:如果value不是数字
            if(isNaN(value)){
                //则抛出异常“工作必须是数字”
                throw  new  Error("工资必须是数字");
            }else{
                //将value赋值个salary
                 salary=value;
            }
        }
    }
    factory();
    salary=5000;
    console.log(getSalary());
    setSalary(6000);
    console.log(getSalary());
    console.log(salary);
    setSalary("hello");

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值