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;
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.
Lets say I want to check whether a property exists within an Object or not. I was looking at two methods:
if(object.hasOwnProperty(key)) { /* do this */ }
OR
if(object[key]) { /* do this */ }
Assuming that we'll never have object = { key: false };
What are the tradeoffs of using one over the other ?
object[key] checks the entire object chain, including the prototype chain.
object.hasOwnProperty(key) checks to see if the key property is assigned directly to the object and does not look in the prototype chain.
So, which one to use depends upon which result you want.
See a simple demonstration using the hasOwnProperty property: http://jsfiddle.net/jfriend00/6zhv87rk/ which is on the prototype for an object.
You would typically use object.hasOwnProperty(key) when your key can be any arbitrary string and you want to make absolutely sure that it will never conflict with a built-in property on the Object prototype. In fact, if you really want to protect yourself, you even use this Object.prototype.hasOwnProperty.call(object, key) so even the hasOwnProperty property could be used with your object. Cases like this would be when you're using a Javascript object as a hash lookup or dictionary-type object with arbitrary key values.
You would typically use object[key] when you are not concerned about such a conflict because you know what types of keys will be on your object and you know they won't conflict because this version is just shorter and a bit easier to read.
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.
I have a Javascript object that I want to pass in more parameters, but the documentation is non-existant. My only option seems to be to reverse engineer the Javascript object to see what parameters and values I can pass in.
For example, I want to see if there is a "zoom" parameter for the object and what values I can pass into the "mapType" parameter:
<script type="text/javascript" src="http://maps.google.com/maps?oe=utf-8&file=api&v=2&key=your-gmap-key"></script>
<script type="text/javascript" src="https://share.findmespot.com/spot-widget/js/SpotMain.js"></script>
<script type="text/javascript">
var widget = new Spot.Ui.LiveWidget({ renderTo: "spot-live-widget",
feeds: [ "0Wl3diTJcqqvncI6NNsoqJV5ygrFtQfBB" ],
height: 400,
width: 500,
mapType: "physical"
});
</script>
<div id="spot-live-widget"/>
Any ideas on how to do that?
Well... you could look at the source...
Your code leads to https://share.findmespot.com/spot-widget/js/SpotMain.js
which leads to https://share.findmespot.com/spot-widget/js/Spot.js, which you unpack using http://jsbeautifier.org/ which shows you that no, it cannot take a 'zoom' parameter in its constructor, but it does have a setZoomAndCenter method
setZoomAndCenter: function (C) {
var B = new GLatLngBounds;
for (var A = 0; A < C.length; A++) {
B.extend(C[A].getPoint())
}
this._map.setZoom(this._map.getBoundsZoomLevel(B));
this._map.setCenter(B.getCenter())
},
And from this we can see that it has a 'private' member _map, which has a setZoom method.
Does this help?
UPDATE
The above method was actually a member of Spot.Ui.MapRenderer, not the LiveWidget.
The MapRenderer is used internally by LiveWidget but is not exposed...
Function#toString
Most Javascript implementations will return the source code of a function if you call the function instance's toString method:
function foo() {
return a;
}
alert(foo.toString()); // Alerts "function foo() { return a; }"
This is non-standard behavior, but widely-supported; you may find it quite useful for reverse-engineering. Calling it on the Spot.Ui.LiveWidget function may be interesting, as well as on functions bound to the properties of the object it returns. Which brings us to...
Edit Of course, if unobfuscated source is available (shout out to Sean), you don't need this...
Looping through Properties: for..in
If it's really a Javascript object, you can do this to find out what properties it has:
var name, own;
for (name in obj) {
own = obj.hasOwnProperty(name);
alert(name + " (" + (own ? "own" : "inherited") + ")");
}
That will tell you the names of its (enumerable) properties and whether those are properties of the instance itself, or its prototype object.
for..in Example
function Thingy() {
}
Thingy.prototype.alpha = "a";
var t = new Thingy();
t.beta = "2";
The loop above would show:
alpha (inherited)
beta (own)
(In no particular order.)
Further Information
Enumerable vs. Non-Enumerable properties
Note that not all properties are "enumerable". For instance, all (or nearly all) of the properties specified by the spec on objects like Array, String, etc. are non-enumerable. But until recently that was just something that could be done by the Javascript implementation itself; there was no mechanism for marking your own properties as being non-enumerable. The new 5th edition spec provides a means of doing that, but it isn't widely supported or used (yet).
Non-Existent Properties
The object you're querying may change its behavior based on whether a property is present or not; in that situation, you'd have no way of knowing, since a non-existent property doesn't show up in the for..in loop (unlike a property that exists but has an undefined value, which does). E.g.:
function doSomething(options) {
if (options.foo) {
// There's a `foo` and it has a value; do something with it
}
The foo property may not exist at all on options, so this reverse-engineering wouldn't reveal that the code did something with it.
Warning
Do not try the for..in loop above on host objects, such as DOM nodes. It may work in some implementations, but usually not, and in some cases (IE6) it'll crash the browser. It's totally safe for Javascript objects, though.
There is no guarantee that the properties listed in a configuration parameter will match those of the resulting object, or that they will be copied to the resulting object even if they are.
The only way to find out is to look at the code in the LiveWidget "constructor" function, and see what properties it expects from the configuration parameter.