admin管理员组

文章数量:1325236

When is hasOwnProperty not required?

The book JavaScript: The Good Parts includes the following which says that "it is usually necessary":

The other form (called for in) enumerates the property names (or keys) of an object. On each iteration, another property name string from the object is assigned to the variable.

It is usually necessary to test object.hasOwnProperty(variable) to determine whether the property name is truly a member of the object or was found instead on the prototype chain.

for (myvar in obj) {
 if (obj.hasOwnProperty(myvar)) {
 ...
 }
}

More specifically I want to enumerate the properties of a simple dictionary-like object, which is created using Javsacript object literal syntax, for example:

var foo = { 'bar': 'baz' };

or a similar object which is created using JSON.parse:

var foo = JSON.parse("{ 'bar': 'baz' }");

Should I use hasOwnProperty when I do for in on the foo object?

Assume that this javascript is running in a random browser as part of a plex web page.

Is the answer, "In practice it is probably/usually not necessary. In theory it could be necessary if some framework or library added a property by changing Object.prototype, but changing Object.prototype like that would be an intrusive bad practice which any respectable framework is unlikely to do"?

When is hasOwnProperty not required?

The book JavaScript: The Good Parts includes the following which says that "it is usually necessary":

The other form (called for in) enumerates the property names (or keys) of an object. On each iteration, another property name string from the object is assigned to the variable.

It is usually necessary to test object.hasOwnProperty(variable) to determine whether the property name is truly a member of the object or was found instead on the prototype chain.

for (myvar in obj) {
 if (obj.hasOwnProperty(myvar)) {
 ...
 }
}

More specifically I want to enumerate the properties of a simple dictionary-like object, which is created using Javsacript object literal syntax, for example:

var foo = { 'bar': 'baz' };

or a similar object which is created using JSON.parse:

var foo = JSON.parse("{ 'bar': 'baz' }");

Should I use hasOwnProperty when I do for in on the foo object?

Assume that this javascript is running in a random browser as part of a plex web page.

Is the answer, "In practice it is probably/usually not necessary. In theory it could be necessary if some framework or library added a property by changing Object.prototype, but changing Object.prototype like that would be an intrusive bad practice which any respectable framework is unlikely to do"?

Share Improve this question edited Jan 9, 2017 at 0:11 ChrisW asked Jan 8, 2017 at 23:58 ChrisWChrisW 56.1k14 gold badges122 silver badges234 bronze badges 15
  • 1 You can do Object.keys(obj).forEach(key => ...) as it will get own properties only. – elclanrs Commented Jan 8, 2017 at 23:59
  • I too would remend Object.keys - with appropriate polyfill if you think you'll need to support IE8 or earlier – Jaromanda X Commented Jan 9, 2017 at 0:05
  • I believe some web pages do change Object.prototype, or something similarly important. I once found when my JavaScript was run inside SalesForce, that for.. in iterated over things other than just the intended items of my data structure (can't remember whether this was an Array or Object though). – Birchlabs Commented Jan 9, 2017 at 0:08
  • 1 @Birchlabs exactly that yes, but in ES5+ that code should be using Object.defineProperty to make those additions non-enumerable so that they don't appear when you do for ... in – Alnitak Commented Jan 9, 2017 at 0:25
  • 1 @ChrisW the one that says "Don't extend Object.prototype". That was correct then, but these days (when done correctly) it's perfectly safe. – Alnitak Commented Jan 9, 2017 at 0:42
 |  Show 10 more ments

3 Answers 3

Reset to default 6

IMHO, in modern JS interpreters it's almost[*] never required, and especially not for a plain object that's just being used as a dictionary.

jQuery manages just fine without it, because people have learnt that unsafely adding enumerable properties to Object.prototype is a bad idea.

ES5, of course, allows you to add non-enumerable properties to Object.prototype if you really want to, using Object.defineProperty.

[*] The exception to the above is if you're writing code that's specifically examining the prototype chain and really needs to know whether an enumerable property is inherited or not

hasOwnProperty is not required when iterating a plain object2 in a "sane, modernish, environment"1: this assumption means restricting legacy browser support.

All of the standard Object properties have been non-enumerable for a very long time and new core methods have always been non-enumerable.


1 If code decides to add to Object.prototype, which is questionable enough aside from polyfills, it SHOULD add it as a non-enumerable property. Adding a new enumerable property violates the "sane environment" constraint. IE 9+ (and FF/Chrome/Safari etc.) support Object.defineProperty sufficiently for this task. IE 8 does not and violates the "modernish" constraint as well.

2 Arrays do not qualify as plain objects. Using for..in is also ill-advised for most array iteration.

It's required only in absolutely predictable situations, that means - almost never.

In ECMAScript 5.1, Object.create was added, which enables the creation of objects with a specified [[Prototype]]. Object.create(null) is a mon pattern used to create objects that will be used as a Map. This can lead to errors when it is assumed that objects will have properties from Object.prototype. This rule prevents calling some Object.prototype methods directly from an object.

Additionally, objects can have properties that shadow the builtins on Object.prototype, potentially causing unintended behavior or denial-of-service security vulnerabilities. For example, it would be unsafe for a webserver to parse JSON input from a client and call hasOwnProperty directly on the resulting object, because a malicious client could send a JSON value like {"hasOwnProperty": 1} and cause the server to crash.

To avoid subtle bugs like this, it's better to always call these methods from Object.prototype. For example, foo.hasOwnProperty("bar") should be replaced with Object.prototype.hasOwnProperty.call(foo, "bar").

本文标签: javascriptWhen is hasOwnProperty not requiredStack Overflow