有关简单的示例,请参见http://jsfiddle.net/FDhQF/1/.
未定义的内容与Javascript中未定义的内容之间有什么区别?例如,尝试访问未定义的对象的属性(实际上,尝试访问变量)将返回undefined.但你也可以设置一些东西= undefined.当你这样做,尝试访问它仍然返回undefined,但指针仍然存在.如上所示,一个例子是如何迭代对象仍然遍历您已经(重新)声明为未定义的属性.看起来有两种不同的未定义.任何人都可以对这种情况有所了解吗?
CMS*_*CMS 42
访问未在对象上定义的属性和包含原始undefined值的属性都将返回给您undefined.
例如:
var obj = {
a: undefined
};
obj.a; // undefined
obj.b; // undefined
Run Code Online (Sandbox Code Playgroud)
不同的是,这a是一个自己的财产,而b不是:
obj.hasOwnProperty('a'); // true
obj.hasOwnProperty('b'); // false
Run Code Online (Sandbox Code Playgroud)
在第一种情况下a是一个自己的属性,即使它包含undefined其值.在第二种情况下,b不是自己的属性,访问obj.b将b在原型链中寻找一个名为的属性.
当原型链结束时(当它到达带有a的对象时null [[Prototype]]),属性查找结束并undefined显式返回.
您应该知道该hasOwnProperty方法只检查该对象是否物理存在于对象(自己的属性)上,但我们还继承了属性,对于这种情况,我们可以使用in运算符,例如:
function Test () {}
Test.prototype.a = 'foo'; // instances of Test will inherit from Test.prototype
var obj = new Test(); // { a="foo", b="bar"}
obj.b = 'bar';
obj.hasOwnProperty('a'); // false
'a' in obj; // true
obj.a; // 'foo'
obj.hasOwnProperty('b'); // true
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,obj继承自Test.prototype,并且a属性不是自己的属性,但它可以通过原型链获得.这就是hasOwnProperty返回false和in运营商返回的原因true.
您可以看到[[Get]]内部操作如何解析内部属性
笔记:
undefined在ECMAScript 3(语言标准的最广泛实现版本)上访问作为标识符不被认为是安全的,因为不是语言关键字(null例如),它只是全局对象的属性,它是在此版本的规范中可写,这意味着如果有人替换其值(例如window.undefined = 'LOL';),它将破坏您的代码.可以使用@strager提及的typeof运算符,例如:
if (typeof obj.prop == 'undefined') { /*....*/ }
Run Code Online (Sandbox Code Playgroud)
此运算符始终返回一个字符串(可以安全使用==:),其值取决于其操作数的类型,此处描述了可能的值.
解决此问题的另一种常见方法是声明您自己的undefined变量,可在函数范围内使用,例如,某些库使用以下模式:
(function(undefined) {
// code here
})();
Run Code Online (Sandbox Code Playgroud)
该函数有一个名为的参数undefined,它立即执行而不传递任何值(最后一对或者是parens进行调用).
也许值得一提的是,undefined全局属性最终在ECMAScript 5中被描述为不可写(不可变,以及不可枚举和不可配置 - 非可删除 - ).
hasOwnProperty直接从对象实例使用该方法也不被认为是安全的,因为如果某个对象具有相同名称的属性,则原始方法将被遮蔽.例如:
var obj = { hasOwnProperty: function () { /* evil code :) */ } };
Run Code Online (Sandbox Code Playgroud)如果你打电话:
obj.hasOwnProperty('prop');
Run Code Online (Sandbox Code Playgroud)
将执行在对象上定义的方法(并且您不希望这样,因为您确切地知道要调用哪个方法...),因为它会影响该方法Object.prototype,但是可以通过以下方式安全地调用它:
Object.prototype.hasOwnProperty.call(obj, 'prop');
Run Code Online (Sandbox Code Playgroud)