写出更好的JavaScript程序之undefined篇(中)


Posted in Javascript onNovember 23, 2009

写在前面的依然是消歧义声明:本文中JavaScript是指一般意义上的JavaScript,并不只限定“自称是JavaScript”的运行环境;“全局变量”和“全局对象的属性”是指同样的东西,只是因为要配合上下文才用了不同的说法,正文中我就不再另外解释了;“声明”指通过“var”语句声明变量和/或对函数及其签名的定义;“变量”指通过“var”语句声明过或者在函数体中试图访问的命名参数;“undefined”指名为“undefined”的值(全局或本地变量),而“未定义”指type(...) == “undefined”的概念值;“output”是向我们显示传入参数的函数,其实就是“alert”的同类。

首先介绍的是和void(0)具有异曲同工之妙的一种办法,我们知道在JavaScript中尝试访问任何一个“没有返回值”的函数的执行结果,都会得到“未定义”这个概念值,所以我们可以这样做:
myVar = function(){}();
这个方法的原理是创建一个空函数,并且获取其(根本不存在的)返回值。很明显,我们会得到“未定义”这个概念值,这个原理是和void(0)一样的。
需要特别注意的是,只有当function关键字不在语句之首的时候,才可以使用这种调用方式;如果需要直接调用一个匿名函数,应该这样做:

(function(){
// code here
})();
假如我们不想污染全局作用域,我们就可以用这种方式来创造一个闭包——很多现有的JavaScript库就是这样做的。
这种办法是在不了解void(0)的执行效果的情况下诞生的,既然我们知道void(0),也就不需要这种办法了。

第二种不常见的办法是访问window.undefined,就像下边这样:
output(myVar === window.undefined);
myVar = window.undefined;
这种办法的原理是:
如果JavaScript的运行环境预定义了undefined这一值,window.undefined就可以直接访问到;
如果没有预先定义undefined这一值,window.undefined就会返回“未定义”这一概念值——还是我们想要的东西。
访问形式从“全局变量”变成“属性”以后,脚本引擎就不会认为这是一个意外操作了,因此代码可以正确执行。

然而这种办法还是存在不足:
undefined在所有的JavaScript引擎中都不是保留字,也就是说它是可以被污染的,这会影响我们的程序的运行效果;
直接访问全局对象的属性效率是很差的,应该避免这么做。

因此,接下来就要介绍我所见过的最为有趣的办法——在本地声明undefined变量!
它的做法是这样的:
function myFunc(){
var undefined;
// some code here
output(myVar === undefined);
myVar = undefined;
}
说到这里我要提一下,有的人对“早期的浏览器上没有undefined”这一说法有不同的理解,认为上面这样的做法是行不通的。
而我认为这种观点是不对的,在我的印象中(大约是2003年),IE5虽然没有预定义undefined,但并不影响我们的不指派声明。
不过毕竟是很多年前的事情,记忆模糊,为了避免想当然造成的错误,我特地装了Windows 98来实验一下:
写出更好的JavaScript程序之undefined篇(中)
写出更好的JavaScript程序之undefined篇(中)

上面两幅是用了QQ屏幕截取 ,不知道为什么变成了JPG,下边这幅是用OneNote截取的。

写出更好的JavaScript程序之undefined篇(中)

由此可以得出,为这样不指派声明undefined变量担忧是多余的。
前一篇解释过,在JavaScript中,如果尝试读取一个没有预定义也未声明过的变量,会引发一个“不存在(未定义)”异常,因此在早期的浏览器上如果直接访问undefined的操作可能会失败。
这种(引发异常的)现象可能是为了方便排除故障而有意设计的;而对于声明过的变量,即使是未经赋值,也不会在读取的时候引发异常——经过声明就表示开发人员确定有“这个东西”。

上面这种在函数作用域内声明本地变量undefined的做法,既解决了引用未声明变量会引发异常的问题,又避免了受全局变量污染的影响,还取代了void(0)这种乍看之下意味不明的小把戏,不仅没有造成难以觉察的拼写错误的隐患,还能提高运算效率——真是一举N得的妙招!
所以了解了这么多之后就发现,最后介绍的这种办法实在是居家旅行、杀人灭口的首选
如果有人问:“undefined应该怎么用?”我们现在就可以回答:就这么用!

终于到了结尾,有的人可能忍不住要问了:为什么在这个系列中我的代码示例都用三个等号的“严格相等”来比较?两个等号的普通的“相等”有什么问题吗?
这就是这个系列的下篇要讲解的内容:undefined及其各种等价形态的适用场合。

Javascript 相关文章推荐
关于Ext中form移除textfield方法:hide(),setVisible(false),remove()
Dec 02 Javascript
Js中使用hasOwnProperty方法检索ajax响应对象的例子
Dec 08 Javascript
jQuery中[attribute]选择器用法实例
Dec 31 Javascript
微信小程序 条件渲染详解
Oct 09 Javascript
JS实现获取来自百度,Google,soso,sogou关键词的方法
Dec 21 Javascript
node.js中路由,中间件,ge请求和post请求的参数详解
Dec 26 Javascript
详解Vue2.0组件的继承与扩展
Nov 23 Javascript
mockjs+vue页面直接展示数据的方法
Dec 19 Javascript
vue-cli 3.x配置跨域代理的实现方法
Apr 12 Javascript
微信小程序上传多图到服务器并获取返回的路径
May 05 Javascript
vue项目引入ts步骤(小结)
Oct 31 Javascript
vue路由切换之淡入淡出的简单实现
Oct 31 Javascript
通过身份证号得到出生日期和性别的js代码
Nov 23 #Javascript
javascript 在网页中的运用(asp.net)
Nov 23 #Javascript
javascript DOM编程实例(智播客学习)
Nov 23 #Javascript
传智播客学习之java 反射
Nov 22 #Javascript
Javascript 刷新全集常用代码
Nov 22 #Javascript
写出更好的JavaScript之undefined篇(上)
Nov 22 #Javascript
COM中获取JavaScript数组大小的代码
Nov 22 #Javascript
You might like
php注入实例
2006/10/09 PHP
手把手教你使用DedeCms V3的在线采集图文教程
2007/04/03 PHP
php实现的验证码文件类实例
2015/06/18 PHP
PHP书写格式详解(必看)
2016/05/23 PHP
PHP命名空间与自动加载类详解
2018/09/04 PHP
微信支付之JSAPI公众号支付详解
2019/05/15 PHP
破解Session cookie的方法
2006/07/28 Javascript
JQuery的ajax基础上的超强GridView展示
2009/09/18 Javascript
将HTMLCollection/NodeList/伪数组转换成数组的实现方法
2011/06/20 Javascript
js中的数组Array定义与sort方法使用示例
2013/08/29 Javascript
JavaScript截取字符串的Slice、Substring、Substr函数详解和比较
2014/03/20 Javascript
js中substring和substr的定义和用法
2014/05/05 Javascript
node.js WEB开发中图片验证码的实现方法
2014/06/03 Javascript
Underscore.js常用方法总结
2015/02/28 Javascript
使用window.prompt()实现弹出用户输入的对话框
2015/04/13 Javascript
jQuery实现带分组数据的Table表头排序实例分析
2015/11/24 Javascript
jQuery解析XML 详解及方法总结
2016/09/28 Javascript
angular6 利用 ngContentOutlet 实现组件位置交换(重排)
2018/11/02 Javascript
JavaScript数据结构与算法之基本排序算法定义与效率比较【冒泡、选择、插入排序】
2019/02/21 Javascript
微信小程序渲染性能调优小结
2019/07/30 Javascript
微信小程序class封装http代码实例
2019/08/24 Javascript
在layui中对table中的数据进行判断(0、1)转换为提示信息的方法
2019/09/28 Javascript
js 递归json树实现根据子id查父id的方法分析
2019/11/08 Javascript
Vue包大小优化的实现(从1.72M到94K)
2021/02/18 Vue.js
[00:36]DOTA2风云人物相约完美“圣”典 12月17日不见不散
2016/11/30 DOTA
Python统计列表中的重复项出现的次数的方法
2014/08/18 Python
ubuntu环境下python虚拟环境的安装过程
2018/01/07 Python
Python实现的爬取百度文库功能示例
2019/02/16 Python
浅谈python标准库--functools.partial
2019/03/13 Python
Python3获取电脑IP、主机名、Mac地址的方法示例
2019/04/11 Python
Python Opencv实现图像轮廓识别功能
2020/03/23 Python
Python logging日志模块 配置文件方式
2020/07/12 Python
医学专业个人求职自荐信格式
2013/09/23 职场文书
环保建议书作文300字
2015/09/14 职场文书
Python import模块的缓存问题解决方案
2021/06/02 Python
Oracle 多表查询基本语法实例
2022/04/18 Oracle