FED实验室 - 专注WEB端开发和用户体验

重新定义“undefined”

点滴Javascript 煦涵 2550℃ 0评论

如果你是Javascript开发者,你肯定知道Javascript中怪癖之一,可以为undefined关键字重新定义。虽然在某种情况下这是正确的,但是真实的情况确有些许复杂,本文的以下部分将详细描述undefined的相关问题:

我们看一个简单带你的例子:

undefined = "Benjamin";

// Outputs: Chrome/FF/IE9+ undefiend ; IE7/8 Benjamin
console.log(undefined);

事实证明,这段代码的结果取决于ECMAScript标准的JavaScript引擎支持的版本。在ES3的引擎(如IE8及以下)输出Benjamin,而在ES5引擎输出undefined。其原因是ES5阻止给undefined分配一个新的值。

当然,如果在ES5的严格模式下,结果可能又不同:

"use strict";

undefined = "Benjamin";

// Outputs: Uncaught TypeError: Cannot assign to read only property 'undefined' of [object Object] 
console.log(undefined);

到目前为止,有三种不同的情形,但是在老的浏览器(IE8及以下)undefined可以被重新赋值真实情况是什么?undefined不是Javascript内置类型之一吗?看下面一个例子:

undefined = "Benjamin";

var unassign;

//Outputs: Benjamin
console.log(undefined);

//Outputs: undefined
console.log(unassign);

请大家思考,为什么给undefined赋值Benjamin,unassign的值还是undefined?

这个结果可能和我们直觉产生的结果不一样,上面这种写法其实没有什么意思,因为在Javascript中undefined有多重不同的含义:

1) Undefined类型;
2) 不变值undefined仅仅是Undefined类型的一个实例;
3) 全局变量undefined是undefined值的一个映射。在ES3中这个变量是可变的,而ES5中是不可变的。

现在你可以看到为什么它是可以分配给undefined一个新值?这是因为undefined被赋予一个新的值到全局变量。unassign变量给我们一个映射到不变值undefined,而不是(潜在可变)变量。

这种情况似乎有点奇怪。是否真的有一个undefined全局变量?如果是的话,有没有办法来检测ES5引擎这个全局变量?

由于全局变量其实是全局对象(浏览器中window,Node.js中global)的属性,我们可以使用JavaScript的in运算符。

var isUndefinedAGlobalVariable = "undefined" in window;

// Outputs: true
console.log(isUndefinedAGlobalVariable);

undefined 与 null很相像,那么它们有何区别?

var isNullAGlobalVariable = "null" in window;

// Outputs: false
console.log(isNullAGlobalVariable);

为什么返回的结果不同?因为null和undefined不同,null是Javascript关键字,由于此,null本质上是不能重新赋值,而ES5不得不添加一个特殊的规则来覆盖undefined全局变量。

虽然现在随着时间的推移问题越来越少,为了支持旧的浏览器,常用库(如jQuery)必须对引入代码的页面重新定义undefined,为自己作用域所用。要做到这一点,他们经常用这个模式:

(function($, window, undefined) {

    // your code

})(jQuery, window);

声明一个匿名函数,在函数调用时没有传入undefined值, 而只是把undefined做为形参,这样在这个函数作用域内为定义的局部变量都将引用undefined值,即使没有undefined全局变量。

这就是对undefined的基本介绍,但是undefined和null应该还有很多区别没有讲,可参考其他文章。

感谢您的阅读,希望本篇文章对您有所帮助,文中不足之处还望批评斧正。

下面是「FED实验室」的微信公众号二维码,欢迎扫描关注:

FED实验室

行文不易,如有帮助,欢迎打赏!

赞赏支持or喜欢 (0)or分享 (0)
捐赠共勉
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(1)个小伙伴在吐槽