关于javascript:JavaScript未定义变量检测undefined-null-detection

18次阅读

共计 4344 个字符,预计需要花费 11 分钟才能阅读完成。

HTML5 自十多年前(2010 年前后)被推举以来,逐步大放异彩,只管过来十年是属于 Native APP 的高光时刻,但 HTML5 的一些新个性和性能还是带来了大量的新网络 / 网页利用,尤其是在 JavaScript 的加持下,网页利用有极其令人着迷的便当与弱小。

JavaScipt 是网页利用默认编程语言,让人又爱又恨。

笔者已经在《中国计算机学会通信》上刊发了一篇认识文章《JavaScript 或成主导的编程语言》(https://dl.ccf.org.cn/institu…),其后两个开源我的项目 GTAjax (https://ufqi.com/dev/gtajax) 和 Hanjst (https://ufqi.com/dev/hanjst/H…) 又别离是应用 JavaScript 做了实现,甚至 Base62x(https://ufqi.com/dev/base62x/) 的编解码办法,都有 JavaScript 语言版本,堪称是 JavaScript 的重度用户、开发者。

即便如此“资深”,仍经常感觉 JavaScript 用起来让人不那么释怀,为了写出更牢靠的代码,咱们甚至在 JavaScript 中显示地申明用严格查看模式: use strict.

即便如此“审慎”,咱们也会遇到 object/variable is null or undefined 的异样抛出,使得程序异样终止,为用户带来了很不好的体验。随着咱们在 UfqiWork/ 有福工坊 (https://ufqi.com/work) 的开发推动,咱们尝试寻找一种检测 JavaScript 变量或者对象是否 null 或 undefined 办法的致力,有了新播种,兹分享如下。

从 JavaScript 自身来说,要检测某个对象或变量是否为 null/undefined,次要有两个工具可用:typeof 操作符 和 window.hasOwnProperty 办法。咱们所创制的办法,代码 1,也是基于这两个基本操作。

//- _isDefined
//- @param: $var, to be tested;
//- @param: global_or_local:‘global|local’, optional
//- return true | false
//- usage: test whether a global variable($var): _isDefined(“$var”) , _isDefined($var)
//- test a variable($var) declared nearby/locally: _isDefined($var) , _isDefined(“$var”,“local”)
function _isDefined($var, global_or_local){
var isDef = false;
if($var != null){
var myTp = typeof $var;
if(myTp ==‘string’){
if(window.hasOwnProperty($var)){
isDef = true;
}
else if(global_or_local != null && global_or_local ==‘local’){
isDef = true;
}
else{
//- @todo
}
}
else if(myTp !=‘undefined’){
isDef = true;
}
}
return isDef;
}

这些代码曾经部署在 Hanjst/ 汉吉斯特,UfqiWork/ 有福工坊 相干模块中,经实测,运行良好,合乎预期。

在编制这些代码之前,咱们也已经在多个利用中写了大量的检测某个 JavaScript 是否为 null/undefined,无一例外地都是应用 typeof 或者 window.hasOwnProperty 办法,甚至再带着对 null 和 empty 的判断。代码显得异样繁琐和臃肿。置信尔后,这些代码将陆续失去简化和修改,新写的代码也将引入该性能 _isDefined .

在编制这些代码之前,咱们也在网络上进行了 code review,翻阅了大量针对此问题的解决思路和方法,可能面对不同运行时环境,给出的解决办法也各个不同,实际上并没有一种办法能够通用到“放之四海而皆准”。

比方最靠近本办法的一个尝试是定义一个 isDefined2, 代码 2,而后在办法体内应用 typeof 操作符判断传入的 $var 是否 null/undefined , 以此来进行判断变量或者对象 $var 是否为 null/undefined .

//- _isDefined2, WRONG!
//- @param: $var, to be tested
//- return true | false
function _isDefined2($var){
var isDef = false;
if(typeof $var !=‘undefined’){
isDef = true;
}
return isDef;
}

这段代码通常状况下,可能进行运行,并对一些变量实现 null/undefined 的探测。然而这个状况只局限在本地变量或者以后曾经申明的变量,如果待探测的变量 $var 没有在 _isDefined2 调用之前被申明,则调用探测语句 _isDedined2($var) 自身就会报错说 $var is null/undefined .

问题进一步地被延申到 JavaScript 的函数办法调用的参数传递是 pass-by-value 传值,还是 pass-by-reference 传援用。通常状况下,JavaScript 的办法调用都是 pass-by-value, 所以在执行语句 _isDefined($var) 时,先要对 $var 进行取值操作,而 $var 如果自身 undefined 时,喜剧谬误就产生了,检测是否为 null/undefined 之前曾经产生了 undefined .

当咱们判断了 $var 为 String 类型的数据对象时,同时引发了另外一个问题,就是当某一个数据变量或对象其自身就是字符串时,如果其自身是一个本地变量,而 String 类型会被视为检测全局变量,这里就会产生异样谬误,把本该返回本地变量为 true 的后果,谬误地解释为全局变量为 false。因而须要进一步地对办法自身做修改,使之可能兼容本地变量、String 类型,改良的做法是针对 _isDefined 引入第二个参数,显示地通知程序,以后尽管引入了 String 类型的变量,但不是默认检测全局变量,而是要检测本地变量。

进一步地修改这个问题,咱们创制了样例代码 1. 能够兼容全局变量和本地变量,不论 $var 是否被什么,都可能进行检测。只是,在调用的时候须要辨别,待检测的变量或者对象是全局变量或者是局部变量:
如果是全局变量,调用形式是:_isDefined(“$var”) , _isDefined($var)
如果是局部变量,调用办法是:_isDefined($var,‘local’) , _isDefined(“$var”,‘local’)

变量 $var 在被检测之前,咱们可能晓得它是全局变量或者局部变量吗?
答案应该是明确的。

测试样例:

var a;
console.log(“UfqiWork/Hanjst: a:”+_isDefined(a));
var b = null;
console.log(“UfqiWork/Hanjst: b:”+_isDefined(b));
var c = 0;
console.log(“UfqiWork/Hanjst: c:”+_isDefined(c));
console.log(“UfqiWork/Hanjst: global-c:”+_isDefined(“c”));
var dd =“d_string”;
console.log(“UfqiWork/Hanjst: local-dd:”+_isDefined(dd,‘local’));
console.log(“UfqiWork/Hanjst: global-dd:”+_isDefined(dd));
console.log(“UfqiWork/Hanjst: global-dd:”+_isDefined(“dd”));
console.log(“UfqiWork/Hanjst: local-dd:”+_isDefined(“dd”,‘local’));

预期输入:

UfqiWork/Hanjst: a:false
UfqiWork/Hanjst: b:false
UfqiWork/Hanjst: c:true
UfqiWork/Hanjst: global-c:false
UfqiWork/Hanjst: local-dd:true
UfqiWork/Hanjst: global-dd:false
UfqiWork/Hanjst: global-dd:false
UfqiWork/Hanjst: local-dd:true


Hanjst

Hanjst 汉吉斯特 Logo

🙋Hanjst 汉吉斯特 是一种基于 JavaScript 的模板语言及模版解析引擎,她运行在客户端或服务器端。

🙋Hanjst 汉吉斯特 可能表述逻辑管制,可能实现与服务器端模版语言雷同的弱小性能。

Hanjst 当齐全在客户端解析时,节俭服务器端计算资源;

Hanjst 模板语言独立,不与服务器端资源做任何绑定;

纯正的 MVC,层间数据用 JSON 格局传递;

常见模板语言性能全反对,附带简单而弱小的 JavaScript 编程能力;

无学习老本,间接应用 JavaScript 书写模板语言;

….

Hanjst is a JavaScript-based templating language and parsing engine that runs on both the client-side and/or server-side.

Hanjst can express logical controls and achieve the same functionalities as the server-side templating languages.

Hanjst’s Run-time in client-side, reduce computing render in server-side;

Hanjst is Language-independent, not-bound with back-end scripts or languages;

Totally-isolated between MVC, data transfer with JSON;

Full-support template tags with built-in logic and customized JavaScript functions;

No more tags languages to be learned, just JavaScript;

….

https://ufqi.com/blog/javascr…

正文完
 0