1. hasOwnProperty()
The hasOwnProperty() method can be used to detect whether an attribute exists in an object instance or in its prototype. This method (don't forget that it inherits from Object) returns true only if the given attribute exists in the object instance. See the following sample code:
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
var person2 = new Person();
alert(person1.hasOwnProperty("name")); //false, because the name attribute read at this time comes from the prototype
person1.name = "Greg";
alert(person1.hasOwnProperty("name")); //true, because the name attribute read at this time comes from the instance attribute
delete person1.name;
alert(person1.hasOwnProperty("name")); //false, because the name attribute read at this time comes from the prototype
2. Use the in operator alone
When used alone, the in operator returns true when a given attribute can be accessed through an object, whether it exists in an instance or in a prototype. See the following sample code:
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
var person2 = new Person();
alert(person1.hasOwnProperty("name")); //false, read attributes from the prototype
alert("name" in person1); //true, accessible to this property
person1.name = "Greg";
alert(person1.hasOwnProperty("name")); //true, read attributes from instances
alert("name" in person1); //true, accessible to this property
delete person1.name;
alert(person1.hasOwnProperty("name")); //false, read attributes from the prototype
alert("name" in person1); //true, accessible to this property
3. Summary
The hasOwnProperty() method and in operator are used to determine whether the property exists in the object or in the prototype. In fact, the in operator avoids an attribute in an object, which is undefined either in an instance or in a prototype. The hasOwnProperty() method results in a false value, which is mistaken for the case of the attribute in the prototype.
4. In operator in for-in loop
When the in operator is used in the for-in loop, the loop returns all enumerable attributes that can be accessed by objects, including both attributes that exist in instances and attributes that exist in prototypes. Instance attributes that shield the non-enumerable attributes in the prototype will also be returned in the for-in loop, because all developers define attributes that are enumerable by rule.
Solution:
-
To obtain only all enumerable attributes on an object without returning enumerable attributes on the object prototype, you can use the Object.keys() method of ECMAScript 5. This method takes an object as a parameter and returns an array of strings containing all enumerable properties. See the following sample code:
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var keys = Object.keys(Person.prototype); alert(keys); //"name,age,job,sayName" var p1 = new Person(); p1.name = "Rob"; p1.age = 31; var p1keys = Object.keys(p1); alert(p1keys); //"name,age"
The sequence of string arrays returned by the Object.keys() method is also the order in which they appear in the for-in loop.