利用try-catch判断变量是已声明未赋值还是未声明
目的是如果一个变量是已声明未赋值,就可以直接赋值,并且不能改变变量的作用域;
如果未声明的话,就重新声明,
在网上搜了下,常见的方法是if(typeof(a)=='undefined'){var a='ss';},
但是这种方法对未声明或已声明未赋值的变量都会返回true。而且如果是这样:
var a; function f(){ if(typeof(a)=='undefined') {var a=1;} } f(); console.log(a);
会显示undefined,因为f()里面只是声明了一个同名的局部变量。
但是如果是已声明未赋值的变量:if(noValueV==null),会返回true;
未声明的变量:if(noDeclareV==null),会报错。
所以可以这样:
function f( ){ if(typeof(v)=='undefined'){ try{ if(v==null)//说明v是已声明未赋值 v=1; //如果v是全局变量,这样不会改变它的作用域 } catch(err){//说明v是未声明 var v;v=2; } } console.log(v); } f( );
这样也是不对的,因为js有‘声明提前'的特性,即函数内声明的变量在这个函数里和这个函数的子函数里都是可见的,不管它具体是在函数内的哪个位置声明的。
所以由于上面里的var v;导致不管哪种情况都是只走try。
修改一下:
function f( ){ if(typeof(v)=='undefined'){ try{ if(v==null)//说明v是已声明未赋值 v=1; //如果v是全局变量,这样不会改变它的作用域 } catch(err){//说明v是未声明 eval('var v');v=2; //这里不一样 } } console.log(v); } f( );
这样就可以了。
写成一个判断函数,返回'noDeclare'表示变量未声明,'noValue'表示变量已声明未赋值,'hasValue'表示变量已声明已赋值:
function f(v){ if(typeof(v)=='undefined'){ try{ if(v==null) return 'noValue'; } catch(err){ return 'noDeclare'; } } else if(v==null) return 'noValue';//这种var v=null; else return 'hasValue'; } var a; console.log(f(a)); a=0; console.log(f(a)); console.log(f(b));
又错了......console.log(f(b));时会报错......