有很多博客说hasOwnProperty
每当使用循环时都应该使用检查for..in
,但我不明白为什么会这样。无论有没有检查,我们都会得到相同的结果。
看看这个小提琴。
如果您使用 来创建一个基本对象{}
,或者使用 来从 JSON 中获取它JSON.parse
,那么hasOwnProperty
全局无用。
但是,如果您正在扩展“类”(使用原型),那么它可以帮助您了解您是否正在访问“自己的属性”(直接属性,包括直接函数)。
请注意,一个基本对象至少有一个(不是直接的)属性,您可能会用console.log({});
or发现它,console.log({}.toString)
但它不是可枚举的,也不能在for... in
循环中看到:
for...in 循环不会迭代不可枚举的属性。从 Array 和 Object 等内置构造函数创建的对象从 Object.prototype 和 String.prototype 继承了不可枚举的不可枚举属性,例如 String 的 indexOf 方法或 Object 的 toString 方法。循环将遍历对象的所有可枚举属性,或者它从其构造函数的原型继承(包括任何覆盖内置属性的属性)。
没有hasOwnProperty
您不知道该属性是对象的本机属性还是继承自它的原型。
var obj1 = {a:"10",b:"20"};
Object.prototype.c = "prototype:30";
var i;
for(i in obj1) {
document.getElementById("div1").innerHTML += obj1[i]+" ";
}
// result 10 20 prototype:30
for(i in obj1) {
if(obj1.hasOwnProperty(i)) {
document.getElementById("div2").innerHTML += obj1[i] +" ";
}
}
// result 10 20
在这种情况下,从它的 Prototypeobj1
继承该属性,您将错误地在您的第一个循环中列出它。c
Object
通常你会得到相同的结果有或没有hasOwnProperty
,但后者会忽略继承而不是直接存在于相关对象上的属性。
考虑这个基本的继承系统。狗继承自主 Animal 类。
function Animal(params) { this.is_animal = true; }
function Dog(params) { for (var i in params) this[i] = params[i]; }
Dog.prototype = new Animal();
var fido = new Dog({name: 'Fido'});
如果我们查看fido
,hasOwnProperty
可以帮助我们确定哪些是它自己的属性(名称),哪些是继承的。
for (var i in fido) if (fido.hasOwnProperty(i)) alert(i+' = '+fido[i]);
...警报name=Fido
但不是is_animal=true
。
这就是为什么我们需要在 for..in 语句中使用 hasOwnProperty() 方法:这不是无用的,这对于使您的代码安全并使其始终做正确的事情非常重要。因为某些库或某些依赖项可能会触及 Object.prototype在您的程序上下文中,如果没有 hasOwnProperty 检查,您的 for...in 语句可能会迭代意外的键。因此,您需要使用 hasOwnProperty() 使您的 for...in 语句安全。
var obj = {
a: 1,
b: 2
};
Object.prototype.haha = 3;
for (var k in obj) {
if (obj.hasOwnProperty(k)){
console.log(k); // prints a, b
}
}
var obj = {
a: 1,
b: 2
};
Object.prototype.haha = 3;
for (var k in obj) {
console.log(k); // prints a, b, haha
}