In Javascript to find all the values in a hash I have seen the following code:
var myHash = {};
myHash['one'] = 1;
myHash['two'] = 2;
for (var key in myHash) {
if (myHash.hasOwnProperty(key)) {
//do something
}
}
What is the point of having the hasOwnProperty check here?
The point is to make sure that key is a property defined directly on myHash and not one that was inherited through a prototype chain. Using in doesn't automatically filter out inherited properties, so you get to do it yourself.
But, as others have said, it isn't necessary for your particular example.
Source: hasOwnProperty on MDN.
It may be more to the point if myHash is a new instance of an object with enumerable properties, so that methods and other inherited properties will not be listed.
In that particular case there's no difference, but if myHash had "inherited" properties then those would be looped over too, without the hasOwnProperty check.
This is most likely a prevention thing, or even a copy-paste where the coder didn't worry about checking if every line was necessary, just that it worked.
Related
I read that we should always use hasOwnProperty when looping an object, because the object can be modified by something else to include some keys we don't want.
But is this always required? Are there situations where it's not needed? Is this required for local variables too?
function my(){
var obj = { ... };
for(var key in obj){
if(obj.hasOwnProperty(key)){
safe
}
}
}
I just don't like adding an extra if inside the loop if I don't have to.
Death to hasOwnProperty
This guy says I shouldn't use it at all any more.
Object.hasOwnProperty determines if the whole property is defined in the object itself or in the prototype chain.
In other words: do the so-called check if you want properties (either with data or functions) coming from no other place than the object itself.
For example:
function A() {
this.x = "I'm an own property";
}
A.prototype.y = "I'm not an own property";
var instance = new A();
var xIsOwnProperty = instance.hasOwnProperty("x"); // true
var yIsOwnProperty = instance.hasOwnProperty("y"); // false
Do you want to avoid the whole check if you want own properties only?
Since ECMAScript 5.x, Object has a new function Object.keys which returns an array of strings where its items are the own properties from a given object:
var instance = new A();
// This won't contain "y" since it's in the prototype, so
// it's not an "own object property"
var ownPropertyNames = Object.keys(instance);
Also, since ECMAScript 5.x, Array.prototype has Array.prototype.forEach which let’s perform a for-each loop fluently:
Object.keys(instance).forEach(function(ownPropertyName) {
// This function will be called for each found "own property", and
// you don't need to do the instance.hasOwnProperty check any more
});
When you're using for (var key in obj) it will loop through the given object + its parent objects' properties on the prototype chain until it reaches the end of the chain. As you want to check only a specific object's properties, you need to use hasOwnProperty.
This is not needed in for (var i = 0; i < length; i++) or data.forEach().
YES, use it always with for ... in
There are some nice answers here describing what hasOwnProperty() does and offering other solutions.
But none do provide an answer to what this question and #João in comments asks.
Is this always required?
In other words,
if the object is mine, if I have control over it, if the object is defined as my own local variable,
do I still need to use hasOwnProperty()?
The complication with this question is, that the control over the variable of Object type is not what's important in this consideration.
What's important is the control over the Object type itself.
If the question is slightly rephrased to: "Is the use of hasOwnProperty() required if I have full control over the JS script, where it's used and everything in its or parent scopes?"
Then no, you don't need to use the hasOwnProperty().
But the full control over the environment is not something you should count on.
Consider this example
var variableCreatedByInocentUser = { amisane: 'yes' };
for (let key in variableCreatedByInocentUser) {
console.log(key +'? '+ variableCreatedByInocentUser[key]);
}
console.log('-----');
Object.prototype.amicrazy = 'yes, you redefined Object type';
for (let key in variableCreatedByInocentUser) {
console.log(key +'? '+ variableCreatedByInocentUser[key]);
}
console.log('-----');
for (let key in variableCreatedByInocentUser) {
if (!variableCreatedByInocentUser.hasOwnProperty(key)) { continue; }
console.log(key +'? '+ variableCreatedByInocentUser[key]);
}
It's fine to drop the hasOwnProperty() only until someone somewhere redefines the Object type.
Before or even after your script is started.
The effect is retroactive. Even if you declared your variable "using original Object type",
it does not work as expected in JS and the redefined Object type will also affect such variables created before.
Even though the redefining of base types is discouraged, it's being done in some frameworks.
Such framework could be included and introduced into your global scope and break your script.
There might also be a safety issue. The Object could be redefined with malicious intention, making your loops perform additional tasks.
If you want to follow good practices, you should always consider all possible scenarios, like that the code you're writing could be reused or inserted, or joined with another project.
Use hasOwnProperty() even when it might seem not necessary and wasteful.
hasOwnProperty expects the property name as a string.
When you call Test.hasOwnProperty(name) you are passing it the value of the name variable (which doesn't exist), just as it would if you wrote alert(name).
Every object descended from Object inherits the hasOwnProperty method. This method can be used to determine whether an object has the specified property as a direct property of that object;
I know a lot of ways to create JS objects but I didn't know the Object.create(null)'s one.
Question:
is it exactly the same as:
var p = {}
vs
var p2 = Object.create(null);
?
They are not equivalent. {}.constructor.prototype == Object.prototype while Object.create(null) doesn't inherit from anything and thus has no properties at all.
In other words: A javascript object inherits from Object by default, unless you explicitly create it with null as its prototype, like: Object.create(null).
{} would instead be equivalent to Object.create(Object.prototype).
In Chrome Devtool you can see that Object.create(null) has no __proto__ property, while {} does.
They are definitely not equivalent. I'm writing this answer to more fully explain why it makes a difference.
var p = {};
Creates an object that inherits the properties and methods from Object.
var p2 = Object.create(null);
Creates an object that doesn't inherit anything.
If you are using an object as a map, and you create an object using method 1 above, then you have to be extra careful when doing lookups in the map. Because the properties and methods from Object are inherited, your code may run into a case where there are keys in the map that you never inserted. For example, if you did a lookup on toString, you would find a function, even though you never put that value there. You can work around that like this:
if (Object.prototype.hasOwnProperty.call(p, 'toString')) {
// we actually inserted a 'toString' key into p
}
Note that it is fine to assign something to p.toString, it will simply override the inherited toString function on p.
Note that you can't just do p.hasOwnProperty('toString') because you may have inserted a key "hasOwnProperty" into p, so we force it to use the implementation in Object.
On the other hand, if you use method 2 above, then you won't have to worry about things from Object appearing in the map.
You can't check for the existence of a property with a simple if like this:
// Unreliable:
if (p[someKey]) {
// ...
}
The value might be an empty string, might be false, or null, or undefined, or 0, or NaN, etc. To check whether a property exists at all, you would still need to use Object.prototype.hasOwnProperty.call(p, someKey).
Creating objects by using {} will create an object whose prototype is Object.prototype which inherits the basic functions from Object prototype while creating objects by using Object.create(null) will create an empty object whose prototype is null.
If someone is looking for implementing Object.create(null), just to know how it works. It is written using __proto__ which is non-standard and hence, I do not recommend it.
function objectCreateMimic()
{
/*optional parameters: prototype_object, own_properties*/
var P = arguments.length>0?arguments[0]:-1;
var Q = arguments.length>1?arguments[1]:null;
var o = {};
if(P!==null && typeof P === "object")
{
o.__proto__ = P;
}
else if(P===null)
{
o.__proto__ = null;
}
if(Q!==null && typeof Q === "object")
{
for(var key in Q)
{
o[key] = Q[key];
}
}
return o;
}
Note: I wrote this, out of curiosity, and it is only written in simple terms, for instance, I am not transferring the property descriptors from the second object to the return object.
When you create an Object with Object.create(null) that means you are creating an Object with no prototype.null here means end of prototype chain. Nevertheless when you create an object like {} Object prototype will be added.
Hence these are two different objects, one with prototype another without prototype.Hope this helps
Somewhat old question and seems like all valid answers, but what #Royi Namir may have been also getting at, and what might be good to understand here is SHOULD I use it? Rather than just ask the question, I'll take a gander.
{} is simple, and straightforward and well-known, ubiquitous code.
Object.create(null) is less well-known, and less often used, as we can surmise from the sheer fact of the question being asked.
Why would you use Object.create(null) over {}? The other answers here answer that question by pointing out the difference between the two approaches, which is simply that Object.create(null) does not inherit Object.prototype prototype while {} does, and that may be of value in your particular circumstance.
Aside from that, the only reason you might want to use one over the other would be performance, memory use, or ease of use.
If we run some simple tests to measure the time it takes to create objects both ways, we can see that there are indeed both performance and memory differences.
Note: for the sake of simplifying my comment, I'm only showing the tests that include assigning attributes but I've done the tests both with and without attribute assignments and the metrics are similar.
console.time("create curly");
let objects = [];
for (let i = 0; i < 100000; i++) {
objects.push({ attr1: i, attr2: i*2, attr3: i*5});
}
console.log(objects.length);
console.timeEnd("create curly");
console.log("Memory", process.memoryUsage().heapUsed);
Output (several runs, best time, not precise):
create curly: 24.152ms
Memory 11280760
console.time("create object");
let objects = [];
for (let i = 0; i < 100000; i++) {
const obj = Object.create(null)
obj.attr1 = i;
obj.attr2 = i*2;
obj.attr3 = i*5;
objects.push(obj);
}
console.log(objects.length);
console.timeEnd("create object");
console.log("Memory", process.memoryUsage().heapUsed);
Output (several runs, best time, not precise):
create object: 41.106ms
Memory 23766400
Performance
While the time output is not a fully scientific, precise metric, I think it's pretty safe to say that Object.create(null) is SLOWER than {}. Depending on the number of objects you need to create, however, it may be a relatively insignificant difference.
Memory
From the tests results shown, creating objects with Object.create(null) and assigning a few attributes to the objects takes about twice as much memory as creating the objects with {} with attributes inline. About 10MB more for 100,000 objects. That's significant!
Ease of Use
It is readily apparent that {} with inline attributes is significantly easier to use and allows for attribute assignment that is streamlined.
Bottom line, use {} for better performance, memory use, and to ease finger stress, unless you have a real reason to create an object that does not inherit the Object.prototype prototype.
I read that we should always use hasOwnProperty when looping an object, because the object can be modified by something else to include some keys we don't want.
But is this always required? Are there situations where it's not needed? Is this required for local variables too?
function my(){
var obj = { ... };
for(var key in obj){
if(obj.hasOwnProperty(key)){
safe
}
}
}
I just don't like adding an extra if inside the loop if I don't have to.
Death to hasOwnProperty
This guy says I shouldn't use it at all any more.
Object.hasOwnProperty determines if the whole property is defined in the object itself or in the prototype chain.
In other words: do the so-called check if you want properties (either with data or functions) coming from no other place than the object itself.
For example:
function A() {
this.x = "I'm an own property";
}
A.prototype.y = "I'm not an own property";
var instance = new A();
var xIsOwnProperty = instance.hasOwnProperty("x"); // true
var yIsOwnProperty = instance.hasOwnProperty("y"); // false
Do you want to avoid the whole check if you want own properties only?
Since ECMAScript 5.x, Object has a new function Object.keys which returns an array of strings where its items are the own properties from a given object:
var instance = new A();
// This won't contain "y" since it's in the prototype, so
// it's not an "own object property"
var ownPropertyNames = Object.keys(instance);
Also, since ECMAScript 5.x, Array.prototype has Array.prototype.forEach which let’s perform a for-each loop fluently:
Object.keys(instance).forEach(function(ownPropertyName) {
// This function will be called for each found "own property", and
// you don't need to do the instance.hasOwnProperty check any more
});
When you're using for (var key in obj) it will loop through the given object + its parent objects' properties on the prototype chain until it reaches the end of the chain. As you want to check only a specific object's properties, you need to use hasOwnProperty.
This is not needed in for (var i = 0; i < length; i++) or data.forEach().
YES, use it always with for ... in
There are some nice answers here describing what hasOwnProperty() does and offering other solutions.
But none do provide an answer to what this question and #João in comments asks.
Is this always required?
In other words,
if the object is mine, if I have control over it, if the object is defined as my own local variable,
do I still need to use hasOwnProperty()?
The complication with this question is, that the control over the variable of Object type is not what's important in this consideration.
What's important is the control over the Object type itself.
If the question is slightly rephrased to: "Is the use of hasOwnProperty() required if I have full control over the JS script, where it's used and everything in its or parent scopes?"
Then no, you don't need to use the hasOwnProperty().
But the full control over the environment is not something you should count on.
Consider this example
var variableCreatedByInocentUser = { amisane: 'yes' };
for (let key in variableCreatedByInocentUser) {
console.log(key +'? '+ variableCreatedByInocentUser[key]);
}
console.log('-----');
Object.prototype.amicrazy = 'yes, you redefined Object type';
for (let key in variableCreatedByInocentUser) {
console.log(key +'? '+ variableCreatedByInocentUser[key]);
}
console.log('-----');
for (let key in variableCreatedByInocentUser) {
if (!variableCreatedByInocentUser.hasOwnProperty(key)) { continue; }
console.log(key +'? '+ variableCreatedByInocentUser[key]);
}
It's fine to drop the hasOwnProperty() only until someone somewhere redefines the Object type.
Before or even after your script is started.
The effect is retroactive. Even if you declared your variable "using original Object type",
it does not work as expected in JS and the redefined Object type will also affect such variables created before.
Even though the redefining of base types is discouraged, it's being done in some frameworks.
Such framework could be included and introduced into your global scope and break your script.
There might also be a safety issue. The Object could be redefined with malicious intention, making your loops perform additional tasks.
If you want to follow good practices, you should always consider all possible scenarios, like that the code you're writing could be reused or inserted, or joined with another project.
Use hasOwnProperty() even when it might seem not necessary and wasteful.
hasOwnProperty expects the property name as a string.
When you call Test.hasOwnProperty(name) you are passing it the value of the name variable (which doesn't exist), just as it would if you wrote alert(name).
Every object descended from Object inherits the hasOwnProperty method. This method can be used to determine whether an object has the specified property as a direct property of that object;
If you create a regular javascript object using say var obj = {}; it will have the object prototype. Same goes for objects created using var obj = new MyClass(); Before Object.create was introduced there was no way around this. However nowadays it's possible to create an object with no prototype (respectively null as its prototype) using var obj = Object.create(null);.
Why is this important? What advantages does it bring? Are there any real world use cases?
It's a completely empty object (nothing inherited from any .prototype including Object.prototype), so you can be guaranteed that any property lookup will only succeed if the property was explicitly added to the object.
For example, if you want to store some data where you won't know the keys in advance, there's a possibility that a provided key will have the same name as a member of Object.prototype, and cause a bug.
In those cases, you need to do an explicit .hasOwnProperty() check to rule out unexpected inherited values. But if there's nothing inherited, your testing can be simplified to a if (key in my_object) { test, or perhaps a simple truthy test if (my_object[key]) { if appropriate.
Also, with no prototype chain, I would imagine that lookups of properties that turn out to not exist would be faster, since only the immediate object would need to be checked. Whether or not this pans out in reality (due to optimizations) would be determined with performance testing.
The only difference here between creating an object with {} and Object.create(null) is that the Object prototype will not be inherited from.
This means that any of the methods we typically assume we can call on any object will not exist, such as toString and valueOf. A list of these can be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype
From a performance perspective, creating an object simply by {} is actually much faster, so unless you specifically cannot have the functions under the Object prototype you should not create objects in that manner.
http://jsperf.com/null-vs-empty-object-performance
I don't know how to extend the map object with prototype and hope you can help.
I have something like this:
var map = {'one':1, 'two':2};
and I would like to have a method to check for the existence of a key:
if (map.containsKey('one')){...}
How would I extend the map object?
It's dangerous to modify Object.prototype, because it affects all objects and will usually break other libraries you may be using. In general, if you want to add methods to a dictionary-like object, you should create an object for your hash instances to inherit from, like the Prototype Hash object.
For this specific instance, you should really just use either if (key in map) or if (map.hasOwnProperty(key)).
There is already an operator to test the existence of a key inside an object.
(In JavaScript, objects are implemented as maps so actually there is no real map.)
if( 'one' in map )
{
alert(map['one']);
}
These are not "maps" they are objects. Building on Maurice's answer, if you want this to apply to all objects:
Object.prototype.containsKey = function(key) {
return this.hasOwnProperty(key);
};
The simplest way to do this is to add a function directly in the object:
map.containsKey = function(key) {
return this[key] ? true : false;
};
In Javascript, you do not need such method really.
if ( map['one'] ) {
// do something
}
should do it
As other's have said, extending Object.prototype might not be a good idea if your code has to play nice with code written by people ignorant of hasOwnProperty().
Anyway, there are three 'correct' ways I know of to check if a property is available:
obj.hasOwnProperty(name)
checks if a property with given name exists in the object.
name in obj
additionally includes properties inherited via an object's prototype chain.
typeof obj[name] !== 'undefined'
will additionally evaluate to false if the property is present but has been set to undefined.
Some non-JS object's (e.g. window.external in IE) might not implement hasOwnProperty(), so one of the other checks has to be used.