I have some code that adds properties to an object like this:
var MyObject = new Object();
if (....) { MyObject.prop1 = .... ; }
if (....) { MyObject.prop2 = .... ; }
if (....) { MyObject.prop3 = .... ; }
After going through all these if statements, I want to test and see whether MyObject has properties. I don't want to test if it has prop1 || prop2 || prop3 because there are 12 properties that can be added.
How do I test to see if it has at least one? I tried if (MyObject) but of course that doesn't work because that only tests the existence of the object. Is these something like a simple one-liner like (MyArray.length) for objects?
If you're working in a pre-ECMAScript5 environment, it's easy enough with a small loop:
var found = false, name;
for (name in MyObject) {
if (MyObject.hasOwnProperty(name)) {
found = true;
break;
}
}
Or since you're using var MyObject = new Object(); to create it (BTW, you can just use var MyObject = {};), you don't actually need the hasOwnProperty call:
var found = false, name;
for (name in MyObject) {
found = true;
break;
}
for..in loops through the enumerable properties of an object, both its own and ones it inherits from its prototype; hasOwnProperty tells you whether the property comes from the object itself or its prototype. All of the properties you're adding will be enumerable, so they'll show up in the loop. Raw objects ({}) have no enumerable properties initially unless someone has been mucking about with Object.prototype (which is a Really Bad Idea), hence the second loop above.
ECMAScript5 (released a couple of years ago, not supported by older browsers and support varies a bit even in more recent ones) adds a couple of functions you could use for this. Probably the most relevant is Object.keys, which returns an array of the names of the object's "own" properties (not properties it inherits from its prototype). That would mean you wouldn't need the loop:
if (Object.keys(MyObject).length) { // Only on ES5-compliant browsers
// Yes it has at least one
}
Try
Object.getOwnPropertyNames(MyObject).length;
This will give you number of object's own properties.
See documentation.
Object.getOwnPropertyNames returns an array whose elements are strings corresponding to the enumerable and non-enumerable properties found directly upon obj.
If you want to support older browsers that don't have Object.getOwnPropertyNames use this:
var getPropertyNames = Object.getOwnPropertyNames || function(obj) {
var propNames = [];
for (var propName in obj) {
if(obj.hasOwnProperty(propName)) {
propNames.push(propName);
}
}
return propNames;
}
getPropertyNames(MyObject).length; // number of own properties
Related
I'm new to JS. I'm reading a javascript book and get confused with the concept of prototype. The book says
JavaScript objects have a link to another object, known as the prototype, from which they inherit properties and methods.Object is the prototype for most objects, but it also provides some methods that are used directly, rather than through inheritance and below is an example:
let hat = {
name: "Hat",
price: 100,
getPriceIncTax() {
return Number(this.price) * 1.2;
}
};
let hatPrototype = Object.getPrototypeOf(hat);
I'm confused, since Object is the prototype of hat, so when we try to get the prototype of hat, isn't that the prototype is just the Object itself? why we still need to get it like:
let hatPrototype = Object.getPrototypeOf(hat);
isn't that just as simple as :
let hatPrototype = Object?
A prototype is just another object that is used as a fallback source of properties and methods and all objects in javascript derive from "Object.prototype". As you know, "Object.getPrototypeOf" returns the prototype of an object, because you didn't give your "hat" object a prototype, it's prototype will derive from "Object.prototype" by default, if you want to give your "hat" object a prototype, you can use "Object.create" like this.
let hatPrototype = {
getprice: function getPriceIncTax() {
return Number(this.price) * 1.2;
}
}
let hat = Object.create(hatPrototype);
hat.price = 100;
hat.name = "hat";
console.log(hat.getprice()); // returns 120
console.log(Object.getPrototypeOf(hat) == hatPrototype); // returns true
console.log(Object.getPrototypeOf(hatPrototype) == Object.prototype); // returns true
Yes, getPrototypeOf doesn't have that many usecases. Usually you do not care about the prototype chain of a certain object, and if you do, you are usually debugging and then you can find these information in your debugger.
I am new in javascript.
Here I am wondering about how many nested or inner object could i
define in javascript
how to find first 2 nested object's key in js.
i also search it on google but i didn't get any solution.
here is example what i want!
var obj = {
a:{
b:{
c:{
//so on
}
}
}
}
thanks in advance.
Here I am wondering about how many nested or inner object could i define in javascript
There is no specified limit.
In the case of an object initializer such as the one you've shown, eventually you'll run into some sort of limitation of a particular JavaScript engine running the code, e.g., around its parsing / processing of the initializer, but nothing defined in the specification.
If you build objects dynamically on your own, for instance like this:
// Don't run this code!
var obj = {};
while (true) {
obj.child = {};
obj = obj.child;
}
...there's no reason to believe you'll run into anything other than a memory limit related to the number of objects you're creating (not their nesting).
how to find how many objects keys are defined in js
In one particular object, you can get an array of its own (not inherited) properties via Object.getOwnPropertyNames and Object.getOwnPropertySymbols, then take the length of the array. To find out how many properties the object has and how many the objects its properties refer to have, you'd use a recursive search — but beware of cyclic structures.
For instance:
const obj = {
a: {
b: {
c: {
}
}
}
};
function countProps(target, recursive = false) {
const ownProperties = [
...Object.getOwnPropertyNames(target),
...Object.getOwnPropertySymbols(target)
];
let count = ownProperties.length;
if (recursive) {
for (const key of ownProperties) {
const value = target[key];
if (value && typeof value === "object") {
count += countProps(value, true);
}
}
}
return count;
}
console.log(countProps(obj, true));
answer for first question.
There is not any restriction for nested object. you can define nested object as per you want until your memory limit exceed.
answer for second question.
here is a code to find keys from nested objects but it is work for only 2nd nested object.
for (var key in ob) {
if (!ob.hasOwnProperty(key))
continue;
var obj = ob[key];
help += "</br>"
for (var prop in obj) {
// skip loop if the property is from prototype
if(!obj.hasOwnProperty(prop)) continue;
help += " ---) \""+key+" "+prop+"\"</br>"
}
}
tell me if you got what you want.
Here I am wondering about how many nested or inner object could i define in javascript?
In the specification of JS it is not defined.
You can define nested or inner object how many you want.
But: do not forget: every object in your code need place in PC memory. And if you have to many objects you browser will not work correctly.
How to find how many objects keys are defined in JS?
With following metods:
Object.getOwnPropertyNames
Returns an array containing the names of all of the given object's own enumerable and non-enumerable properties.
Object.getOwnPropertySymbols
Returns an array of all symbol properties found directly upon a given object.
you will find the length of how many objects keys are defined in your object.
I'm trying to do a bit of browser object discovery, figuring out browser built-ins etc...
I noticed different results when trying to get at the window object's properties (just FYI I'm using Chrome Version 41.0.2272.89 (64-bit)).
Object.keys(window).length;
returns 7 keys. From the docs Object.keys() returns the enumerable properties of an object.
But the docs also say that for ... in iterates over the enumerable properties of an object. However:
var i = 0;
for (var propertyName in window) {
i++;
}
returns a count of 177.
Why is this different? Shouldn't they both only be returning the count of enumerable properties?
for-in loops over the object's own enumerable properties and the enumerable properties of its prototype (and its prototype, etc.). Object.keys only lists the object's own enumerable properties.
So Object.keys builds an array something like this:
var keys = [];
var key;
for (key in object) {
if (object.hasOwnProperty(key)) { // But using an internal, non-overrideable
// operation, not literally the method
keys.push(key);
}
}
Note the hasOwnProperty check (it's not really a call to the method, it's an internal check that can't be tricked by replacing the method or similar).
I was looking at a clone object function here:
http://jsperf.com/cloning-an-object/2
the function is:
function clone(obj) {
var target = {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
target[i] = obj[i];
}
}
return target;
}
and i was wondering why is the check
if (obj.hasOwnProperty(i))
needed ?
Because if property i is not in the object obj, it wouldn't be iterated in the first place in the for loop.
Am I missing something ?
The for...in construct also loops over inherited properties.
If you create an object with a constructor, for example like this :
var s = new String();
then you have all enumerable String functions listed among the properties, but not as own properties (i.e. direct properties). For example try this in the console :
for (var k in s) console.log(k)
You'll discover a few interesting functions that were probably indispensable to SO developers like formatUnicorn.
This check lets you clone direct enumerable properties without cloning the prototype properties.
See documentation on the MDN.
Because the original loop will also show properties from the prototype object, which you wouldn't want.
It's worth mentioning that as of JavaScript 1.8.5 you can use Object.keys(obj) to get an Array of properties defined on the object itself
(ones that return true for obj.hasOwnProperty(key)).
This is better (and readable) than using for-in loop.
Its supported on these browsers:
Firefox (Gecko): 4 (2.0)
Chrome: 5
Internet Explorer: 9
More info on
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
I've subscribed to the common idiom:
for(var key in obj){
if(obj.hasOwnPropery(key)){
// do stuff
}
}
but if I do something like:
var obj = {a: 'a', b: 'b'};
Do I need to worry about obj having properties other than "a" and "b" when I loop?
Or is the above idiom primarily for objects that you the developer did not create?
Technically yes, the Object.prototype can be modified (for a good or bad reason). These show up as enumerable properties (which will show up while enumerating).
When the Object.prototype is modified, it affects all instances of objects, so your obj is included in that. For example, if some other script/library executes this:
Object.prototype.keyLength = function () {
var count = 0;
for (var key in this) {
if (this.hasOwnProperty(key)) count++;
}
return count;
};
Then this will be the results of iterating over your obj (without using hasOwnProperty):
a
b
keyLength
(not necessarily in that order)
If you used hasOwnProperty, you'd only see "a" and "b".
It's not ideal to modify the Object prototype (for several reasons), but a "safer" way to do so is with Object.defineProperty - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty . You are able to describe it as enumerable or not. It's a newer method, so it's not globally available in browsers. Of course, you can't force other libraries to use this as you don't have control over them. But if you can, it's advisable for your own use.
Your use of hasOwnProperty is to make sure the key you're looking at is an actual property and not a property on the prototype chain and isn't enumerable. Which does solve the prototype "problem". Just for reference - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty