Javascript trivia: check for equality against the empty object - javascript

Probably a duplicate of this question.
Silly javascript question: I want to check if an object is the emtpy object.
I call empty object the object that results from using the empty object literal, as in:
var o = {};
As expected, neither == nor === work, as the two following statements
alert({}=={});
alert({}==={});
give false.
Examples of expressions that do not evaluate to the empty object:
0
""
{a:"b"}
[]
new function(){}
So what is the shortest way to evaluate for the empty object?

You can also use Object.keys() to test if an object is "empty":
if (Object.keys(obj).length === 0) {
// "empty" object
} else {
// not empty
}

function isEmpty(o){
for(var i in o){
if(o.hasOwnProperty(i)){
return false;
}
}
return true;
}

You can use this syntax
if (a.toSource() === "({})")
but this doesn't work in IE. As an alternative to the "toSource()" method encode to JSON of the ajax libraries can be used:
For example,
var o = {};
alert($.toJSON(o)=='{}'); // true
var o = {a:1};
alert($.toJSON(o)=='{}'); // false
jquery + jquery.json

There is not really a short way to determine if an object is empty has Javascript creates an object and internally adds constructor and prototype properties of Object automatically.
You can create your own isEmpty() method like this:
var obj={}
Object.prototype.isEmpty = function() {
for (var prop in this) {
if (this.hasOwnProperty(prop)) return false;
}
return true;
};
alert(obj.isEmpty());
So, if any object has any property, then the object is not empty else return true.

javascript:
cs = 'MTobj={ }; JSON.stringify(MTobj)=="{}"';
alert(cs+' is '+eval(cs));
cs = 'MTnot={a:2}; JSON.stringify(MTnot)=="{}"';
alert(cs+' is '+eval(cs));
says
MTobj={ }; JSON.stringify(MTobj)=="{}" is true
MTnot={a:2}; JSON.stringify(MTnot)=="{}" is false
Caveat! Beware! there can be false positives!
javascript:
cs = 'MTobj={ f:function(){} }; JSON.stringify(MTobj)=="{}"';
alert(cs+' is '+eval(cs));
alert("The answer is wrong!!\n\n"+
(cs="JSON.stringify({ f:function(){} })")+
"\n\n returns\n\n"+eval(cs));

Related

How to make a method that can affect any value type?

Warning: creating extensions to native object and/or properties is considered bad form, and is bound to cause problems. Do not use this if it is for code that you are not using solely for you, or if you don't know how to use it properly
I know you can use Object, String, Number, Boolean, etc. to define a method, something like this:
String.prototype.myFunction = function(){return this;} //only works on strings.
But what I need to be able to do is use that on any value, and access the value in the function.
I googled, and looked here, but couldn't find anything suitable.
2/18/15 Edit: Is there any workaround to having this be a property of any Object if I use Object.prototype?
Per Request, here is the current function that is used for isString()
function isString(ins) {
return typeof ins === "string";
}
Following on a few answers, I have come up with some code and errors caused by it.
Object.prototype.isString = function() {
return typeof this === "string";
}
"5".isString() //returns false
"".isString() //returns false
var str = "string"
str.isString() //returns false
A “dot operator function” is called a method. The cleanest way to create a method in JavaScript that can work on any data type is to create a wrapper. For example:
var Wrapper = defclass({
constructor: function (value) {
this.value = value;
},
isString: function () {
return typeof this.value === "string";
},
describe: function () {
if (this.isString()) {
alert('"' + this.value + '" is a string.');
} else {
alert(this.value + " is not a string.");
}
}
});
var n = new Wrapper(Math.PI);
var s = new Wrapper("Hello World!");
n.describe(); // 3.141592653589793 is not a string.
s.describe(); // "Hello World!" is a string.
function defclass(prototype) {
var constructor = prototype.constructor;
constructor.prototype = prototype;
return constructor;
}
By creating your own wrapper constructor you ensure that:
Your code doesn't mess with other peoples' code.
Other people's code doesn't mess with your code.
You keep the global scope and native prototypes clean.
Several popular JavaScript libraries like underscore and lodash create wrapper constructors for this very purpose.
First of all, why defining properties on Object (or other builtin types) is frowned upon - they show up in unexpected places. Here is some code that outputs the total number of feet some characters have:
var feetMap = {
jerry : 4,
donald : 2,
humpty: 0
}
function countFeet(feetMap) {
var allFeet = 0;
for (var character in feetMap) {
allFeet += feetMap[character];
}
return allFeet;
}
console.log('BEFORE DEFINITION', countFeet(feetMap));
Object.prototype.isString = function() {
return typeof this === "string";
};
console.log('AFTER DEFINITION', countFeet(feetMap));
Note how simply defining your isString function will influence the result of the countFeet function which now iterates over one unexpected property. Of course, this can be avoided if the iteration was protected with hasOwnProperty check, or if the property was defined as non-enumerable.
Another reason to avoid defining properties on builtin types it the possibility of collision. If everyone defined their own isNumber method that gave slightly different results depending on use cases - one could consider the string "42" a number and another could say it's not - subtile bugs would crop all over the place when people used multiple libraries.
The question is - why do you need a method that can affect any value type? A method should be something that is inherent to the class of objects it belongs to. Having an isString method makes no sense on a Number object - it simply doesn't have any relevance to Numbers.
What makes more sense is to have a function/method that can return the type of the value given to it as parameter:
var Util = Util || {};
Util.isString(value) {
return typeof value === "string";
}
Util.isString('test') // true
Util.isString(5) // false
The reason why your current code
Object.prototype.isString = function() {
return typeof this === "string";
}
"5".isString() //returns false
"".isString() //returns false
var str = "string"
str.isString() //returns false
isn't working is because when you access a property on a primitive value, JS creates a wrapper object of the apropriate types and resolves the property on that wrapper object (after which it throws it away). Here is an example that should elucidate it:
Object.prototype.getWrapper = function(){
return this;
}
console.log((5).getWrapper()); // Number [[PrimitiveValue]]:5
console.log("42".getWrapper()); // String [[PrimitiveValue]]:"42"
Note that the primitive value 5 and the object new Number(5) are different concepts.
You could alter your function to mostly work by returning the type of the primitive value. Also, don't forget to make it non-enumerable so it doesn't show up when you iterate over random Objects.
Object.defineProperty(Object.prototype, 'isString', {
value : function() {
return typeof this.valueOf() === "string";
},
enumerable : false
});
"5".isString() //returns true
"".isString() //returns true
var str = "string"
str.isString() //returns true
Object.prototype.isString = function() {
return typeof this === "string";
}
"5".isString() //returns false
"".isString() //returns false
var str = "string"
str.isString() //returns false
If anyone could explain a workaround for the function being a property of any object, and why the current method isn't working, I will provide 125 rep.
Answer:
Well in javascript, when you are calling a sub method/property of a object, like "myFunction" (object.myFunction or object["MyFunction"])
it will start to see if the object itself have it.
IF NOT: it will follow the prototype chain(like superclass in normal oop),
until it finds a "parent/superclass" with the method/property.
The last step in this prototype chain is Object.
If Object dosnt have the method, it will return "undefined".
When you extending the Object class itself it will alway look at
any object calling the method as a Object (In oop: All classes are also Object in addition the is own classtype)
This is like missing a "cast" in normal OOP.
So the reason why your function returns false is that its a "object" not a "string" in this context
Try making this function:
Object.prototype.typeString = function() {
return typeof this;
}
"5".typeString() //returns "object"
As everbody says it really bad idea to extend any of the native JS classes, but a workaround would start with something like this:
Object.prototype.objectTypeString = function(){
return Object.prototype.toString.call(this);
}
Here is a fiddle:
http://jsfiddle.net/fwLpty10/13/
Note that null dosnt have prototype and NaN (NotANumber) is condidered a Number!!!
This means that you will always need to check is a variable is null,
before calling this method!
Object.prototype.isString = function(){
return Object.prototype.toString.call(this) === "[object String]";
};
Final fiddle: http://jsfiddle.net/xwshjk4x/5/
The trick here is that this methods returns the result of the toString method, that are called with "this", which means that in the context of the toString method, the object you call it on, are its own class (not just any supertype in the prototype chain )
The code posted that extends the Object prototype will work, if corrected.
However, it makes an incorrect assumption about what this is inside the invoked method. With the posted code the following output is correct and to be expected (barring a few old implementation bugs);
"5".isString() //returns false
This is because JavaScript will "wrap" or "promote" the primitive value to the corresponding object type before it invokes the method - this is really a String object, not a string value. (JavaScript effectively fakes calling methods upon primitive values.)
Replace the function with:
Object.prototype.isString = function() {
return this instanceof String;
}
Then:
"5".isString() // => true (a string was "promoted" to a String)
(5).isString() // => false (`this` is a Number)
Another solution to this is also to use polymorphism; with the same "pitfalls"1 of modifying standard prototypes.
Object.prototype.isString = function () { return false; }
String.prototype.isString = function () { return true; }
1The concern of adding a new enumerable property to the global protoypes can be mitigated with using defineProperty which creates a "not enumerable" property by default.
Simply change
x.prototype.y = ..
to
Object.defineProperty(x.prototype, 'y', { value: .. })
(I am not defending the use of modifying the prototype; just explaining the original problematic output and pointing out a way to prevent the enumeration behavior.)
To show u some example:
String.prototype.myFunction = function() {
return this+"asd";
};
this function will add "asd" to each string when myFunction() is called.
var s = "123";
s = s.myFunction();
//s is now "123asd"
Before we start, few important statements to remember and be aware of (true for all string literal/primitive, String object, number literal/primitive, Number object etc.):
All objects in JavaScript are descended from Object and inherit methods and properties from Object.prototype – String, Number etc (much like Java).
JS has 6 primitive types – string, number, boolean, null, undefined and symbol
JS has their corresponding wrapper objects – String, Number, Boolean and Symbol
As you can see above, JS has string as a primitive as well an Object
Primitive is not of type Object.
String literal is a primitive and String object is of type Object.
The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor. (first condition to get TRUE here is that instanceof should be used against an Object or its subclass)
The typeof operator returns a string indicating the type of the unevaluated operand.
String as primitive:
String primitive or literal can be constructed in following ways:
var str1 = “Hello”;
var str2 = String(“Hello”);
typeof str1; //Output = "string"
typeof str2; //Output = "string"
str1 instanceof (String || Object) //Output = false because it is a primitive not object
str2 instanceof (String || Object) //Output = false because it is a primitive not object
String as Object:
String object can be constructed by calling its constructor from new object:
var str3 = new String(“Hello”);
typeof str3; //Output = "string"
str3 instanceof (String) //Output = true because it is a String object
str3 instanceof (Object) //Output = true because it is an Object
Above all may look little obvious but it was necessary to set the ground.
Now, let me talk about your case.
Object.prototype.isString = function() {
return typeof this === "string";
}
"5".isString() //returns false
"".isString() //returns false
var str = "string"
str.isString() //returns false
You are getting FALSE as o/p because of concept called as Auto-boxing. When you call any method on string literal then it gets converted to String object. Read this from MSDN - “Methods for String Literals”, to be sure in yourself.
So, in your prototype when you will check type using typeof then it will never be a literal (typeof == "string") because it is already converted into an object. That's the reason you were getting false, if you will check typeof for object then you will get true, which I am going to talk in detail below:
typeof will give information on what type of entity it is - an object or a primitive (string, number etc) or a function.
instanceof will give information on what type of JS Object it is - Object or String or Number or Boolean or Symbol
Now let me talk about solution which is provided to you. It says to do a instanceof check, which is 100% correct, but with a note that upon reaching your prototype it could be of object type or function type. So, the solution which I am providing below will give you a picture of the same.
My recommendation is to have a generic function which would return you the type of instance, and then you can do whatever you want based on if it is a Number or String etc. isString is good but then you have to write isNumber etc., so instead have a single function which will return you the type of instance and can even handle function type.
Below is my solution:
Object.prototype.getInstanceType = function() {
console.log(this.valueOf());
console.log(typeof this);
if(typeof this == "object"){
if(this instanceof String){
return "String";
} else if(this instanceof Boolean){
return "Boolean";
} else if(this instanceof Number){
return "Number";
} else if(this instanceof Symbol){
return "Symbol";
} else{
return "object or array"; //JSON type object (not Object) and array
}
} else if(typeof this == "function"){
return "Function";
} else{
//This should never happen, as per my knowledge, glad if folks would like to add...
return "Nothing at all";
}
}
Output:
new String("Hello").getInstanceType() //String
"Hello".getInstanceType() //String
(5).getInstanceType() //Number
(true).getInstanceType() //Boolean
Symbol().getInstanceType() //Symbol
var ddd = function(){}
var obj = {}
obj.getInstanceType() //object or array
var arr = []
arr.getInstanceType() //object or array
ddd.getInstanceType() //Function
($).getInstanceType() //Function, because without double quotes, $ will treated as a function
("$").getInstanceType() //String, since it came in double quotes, it became a String
To wrap up: Your 2 concerns as below
But what I need to be able to do is use that on any value, and access
the value in the function.
You can access the value in your function using this. In my solution you can see console.log(this.valueOf());
Is there any workaround to having this be a property of any Object if
I use Object.prototype?
You can achieve it from Object.prototype.getInstanceType as per above solution, and you can invoke it on any valid JS object and you will get the desired information.
Hope this helps!
From the MDN Description of Object:
All objects in JavaScript are descended from Object
So, you can add methods to Object.prototype, which can then be called on anything. For example:
Object.prototype.isString = function() {
return this.constructor.name === 'String';
}
console.log("hi".isString()); //logs true
console.log([].isString()); //logs false
console.log(5..isString()); //logs false
You could create this isX functions for each type of primitive there is, if you wanted. Either way, you can add methods to every type, since everything in JavaScript descends from an Object.
Hope that helps, and good luck :)
--edit--
I did want to point out that just because you can do this doesn't mean that you should. It's generally a bad practice to extend built-in functionality of JavaScript, even more so for a library that others will use. It depends on your use-case, though. Best of luck.
Discussions aside, that this is not good practice and not a common approach like the wrapper-constructor, you should achieve this with either asking for the constructor's name:
Object.defineProperty(Object.prototype, 'isString', {
value: function() { return this.constructor.name === "String"; }
});
or with the also already mentioned instanceof method:
Object.defineProperty(Object.prototype, 'isString', {
value: function() { return this instanceof String; }
});
Explanation why your method didn't work is taking care of in this post.
If you want your new defined property to be enumerable, configurable or writable, you should take a look at the docs for defineProperty.
As a few others have pointed out your code is almost correct expect for the typeof this === 'string' part which doesn't work due to JavaScript's quirky behavior when it comes to primitives vs. objects. One of the most robust ways to test if an object is a string is with Object.prototype.toString.call(this) === '[object String]' (check out this article). With that in mind you could simply write your implementation of isString like so:
Object.prototype.isString = function () {
return Object.prototype.toString.call(this) === '[object String]';
};
"abc".isString(); // ==> true
"".isString(); // ==> true
1..isString(); // ==> false
{}.isString(); // ==> false
This is because string literals are of native string type, not actually an instance of String object so, in fact, you cannot actually call any method from Object or String prototype.
What is happening is that when you try to call any method over a variable which type is string, Javascript is automatically coercing that value to a newly constructed String object.
So
"abc".isString();
Is the same as:
(new String("abc")).isString();
The side effect of that is that what you are receiving in your isString() method is an (variable of type) Object which, also, is an instance of the String object.
Maybe you could see it more clearly with a simplified example:
var a = "Hello";
console.log(typeof a); // string
var b = new String("Hello");
console.log(typeof b); // object
By the way, the best chance you have to detect string in your function, as many others said, is to check if it is an instance of the String object with:
foo instanceof String
If you want to also check over other possible types, you should do a double check like the following:
function someOtherFn(ins) {
var myType = typeOf ins;
if (myType == "object" && ins instanceof String) myType = "string";
// Do more stuf...
}

underscore.js every() with undefined

I wrote some code like this:
var a = new Array(10); // should be [undefined * 10]
var b = _.every(a, function(m){
if(_.isUndefined(m)){
return false;
}
return true;
});
I expect b is 'false', but it return 'true'.
Why it return 'true'?
Then, I change to this:
var c = [undefined, undefined];
var d = _.every(c, function(m){
if(_.isUndefined(m)){
return false;
}
return true;
});
it return 'false' in d.
Why they are different?
You can test this in http://jsfiddle.net/3qj4B/3/
When you create an array using the class initializer you are creating an array with 10 space of memory available to be used, but none of them is yet initialized. So you're not looping over anything.
Now look at the source of every:
_.every = _.all = function(obj, iterator, context) {
iterator || (iterator = _.identity);
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
each(obj, function(value, index, list) {
if (!(result = result && iterator.call(context, value, index, list))) return breaker;
});
return !!result;
};
result is set to be true and it is returned since each does no iterations. That's why you're returning true.
If, in your fiddle, you try to add a console.log(m) inside the handler you'll see no logs in the console since each iterates 0 times.
There's a subtle difference between initializing an array with the Array constructor and an initial size, and initializing with an explicit list of undefined entries. The former (the Array constructor) doesn't create properties corresponding to the indexes, while the explicit initialization does.
I suspect that Underscore is using the native .forEach() when it can, and that won't call its callback for uninitialized indexes. Thus, in the first test, the callback to _.every() is never being called at all.
edit — the Array constructor does something more-or-less the same as:
var a = []; a.length = 10;
When you extend an array by increasing its length like that, the new implicit index positions aren't initialized. It's the basic difference between the non-existence of a property, and the presence of a property with no value. In both cases, a dereference of the property results in undefined. Thus:
var o = {};
if (o.something == undefined) // this will be true
and then:
var o = { something: undefined };
if (o.something == undefined) // also true
One way to tell the difference between the two situations is the in operator:
if ('something' in o) // only true in the second case

How to identify anonymous types in JSON?

I am writing one function on Javascript which needs to address all the anynymous types in a JSON object.
For example,
Typed= {
emails: [{email:'a#a.com'}, {email:'b#a.com'}, {email:'c#a.com'}, {email:'d#a.com'}]
};
is an example of typed array in a JSON because each element inside the array is typed email
while,
Anon= {
emails: ['a#a.com', 'b#a.com', 'c#a.com', 'd#a.com']
};
is a JSON object where emails is collection of some anonymous objects.
Is there any ways that I can differentiate between both in JQuery or Javascript?
The simplest solution is to have the JSON source only return one of the two forms. Then you don't have to branch in your client.
If that's not an option, you could get the values out with JavaScript's handy lazy-evaluation of boolean expressions:
var em = json.emails[0].email || json.emails[0];
That statement will prefer the array-of-objects version, but use the array-of-strings version as a fallback.
(edited in response to clarifying comment below)
You can determine what properties a JS object has at runtime like this:
function enumerate(targetObject){
var props = [];
for (var propName in targetObject ){
props.push(propName);
}
return props;
}
console.log(enumerate({foo:1, bar:'baz'}),join(',')); //"foo, bar"
you could then modulate your logic on the basis of the properties you get back. You'll want to make sure you understand prototypes (specifically what Object.hasOwnProperty does and means), too.
You can use Array iteration methods to quickly check if all (or some) elements of the array have the desired type:
Anon.emails.every(function(e) { return typeof e == "object" }) // false
Typed.emails.every(function(e) { return typeof e == "object" }) // true
or a more generic solution
typeCheck = function(type) {
return function() {
return typeof arguments[0] == type
}
}
Anon.emails.every(typeCheck("object")) // false
Typed.emails.every(typeCheck("object")) // true
(An obligatory warning about iteration methods not being supported in ancient browsers)
How about this:
var istyped = function (a) {
if (typeof(a) !== 'object') {
return false;
}
var count = 0;
for (var key in a) {
count = count + 1;
}
return (count === 1);
}
I'm assuming here you just want to distinguish between regular variables (this would be your anonymous variable) and objects with just one key/value pair inside (this would be your typed variable).
To check if array contains only typed variables you'd just have to loop through it with that function. For example (in newer versions of JavaScript):
Typed.emails.every(istyped) = true
Anon.emails.every(istyped) = false
Why not do a map first:
emails = emails.map(function (email) {
if (typeof email.email === 'string')
return email.email;
});
That will make your emails array an array of just strings. Then you can just process it as usual. There aren't any side-effects if it is an array of strings (email.email will be undefined).
I do stuff like this when I have to make one client deal with multiple versions of an API. Alternatively, you could do the map the other way:
emails = emails.map(function (email) {
if (typeof email === 'string')
return {email: email};
});
This would work better if there could be other information in each object in your emails array.

How to check if object has any properties in JavaScript?

Assuming I declare
var ad = {};
How can I check whether this object will contain any user-defined properties?
You can use the built in Object.keys method to get a list of keys on an object and test its length.
var x = {};
// some code where value of x changes and than you want to check whether it is null or some object with values
if(Object.keys(x).length){
// Your code here if x has some properties
}
What about making a simple function?
function isEmptyObject(obj) {
for(var prop in obj) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
return false;
}
}
return true;
}
isEmptyObject({}); // true
isEmptyObject({foo:'bar'}); // false
The hasOwnProperty method call directly on the Object.prototype is only to add little more safety, imagine the following using a normal obj.hasOwnProperty(...) call:
isEmptyObject({hasOwnProperty:'boom'}); // false
Note: (for the future) The above method relies on the for...in statement, and this statement iterates only over enumerable properties, in the currently most widely implemented ECMAScript Standard (3rd edition) the programmer doesn't have any way to create non-enumerable properties.
However this has changed now with ECMAScript 5th Edition, and we are able to create non-enumerable, non-writable or non-deletable properties, so the above method can fail, e.g.:
var obj = {};
Object.defineProperty(obj, 'test', { value: 'testVal',
enumerable: false,
writable: true,
configurable: true
});
isEmptyObject(obj); // true, wrong!!
obj.hasOwnProperty('test'); // true, the property exist!!
An ECMAScript 5 solution to this problem would be:
function isEmptyObject(obj) {
return Object.getOwnPropertyNames(obj).length === 0;
}
The Object.getOwnPropertyNames method returns an Array containing the names of all the own properties of an object, enumerable or not, this method is being implemented now by browser vendors, it's already on the Chrome 5 Beta and the latest WebKit Nightly Builds.
Object.defineProperty is also available on those browsers and latest Firefox 3.7 Alpha releases.
You can loop over the properties of your object as follows:
for(var prop in ad) {
if (ad.hasOwnProperty(prop)) {
// handle prop as required
}
}
It is important to use the hasOwnProperty() method, to determine whether the object has the specified property as a direct property, and not inherited from the object's prototype chain.
Edit
From the comments: You can put that code in a function, and make it return false as soon as it reaches the part where there is the comment
With jQuery you can use:
$.isEmptyObject(obj); // Returns: Boolean
As of jQuery 1.4 this method checks both properties on the object itself and properties inherited from prototypes (in that it doesn't use hasOwnProperty).
With ECMAScript 5th Edition in modern browsers (IE9+, FF4+, Chrome5+, Opera12+, Safari5+) you can use the built in Object.keys method:
var obj = { blah: 1 };
var isEmpty = !Object.keys(obj).length;
Or plain old JavaScript:
var isEmpty = function(obj) {
for(var p in obj){
return false;
}
return true;
};
Most recent browsers (and node.js) support Object.keys() which returns an array with all the keys in your object literal so you could do the following:
var ad = {};
Object.keys(ad).length;//this will be 0 in this case
Browser Support: Firefox 4, Chrome 5, Internet Explorer 9, Opera 12, Safari 5
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
If you're using underscore.js then you can use the _.isEmpty function:
var obj = {};
var emptyObject = _.isEmpty(obj);
If you are willing to use lodash, you can use the some method.
_.some(obj) // returns true or false
See this small jsbin example
for (var hasProperties in ad) break;
if (hasProperties)
... // ad has properties
If you have to be safe and check for Object prototypes (these are added by certain libraries and not there by default):
var hasProperties = false;
for (var x in ad) {
if (ad.hasOwnProperty(x)) {
hasProperties = true;
break;
}
}
if (hasProperties)
... // ad has properties
for(var memberName in ad)
{
//Member Name: memberName
//Member Value: ad[memberName]
}
Member means Member property, member variable, whatever you want to call it >_>
The above code will return EVERYTHING, including toString...
If you only want to see if the object's prototype has been extended:
var dummyObj = {};
for(var memberName in ad)
{
if(typeof(dummyObj[memberName]) == typeof(ad[memberName])) continue; //note A
//Member Name: memberName
//Member Value: ad[memberName]
}
Note A: We check to see if the dummy object's member has the same type as our testing object's member. If it is an extend, dummyobject's member type should be "undefined"
var hasAnyProps = false; for (var key in obj) { hasAnyProps = true; break; }
// as of this line hasAnyProps will show Boolean whether or not any iterable props exist
Simple, works in every browser, and even though it's technically a loop for all keys on the object it does NOT loop through them all...either there's 0 and the loop doesn't run or there is some and it breaks after the first one (because all we're checking is if there's ANY...so why continue?)
ES6 function
/**
* Returns true if an object is empty.
* #param {*} obj the object to test
* #return {boolean} returns true if object is empty, otherwise returns false
*/
const pureObjectIsEmpty = obj => obj && obj.constructor === Object && Object.keys(obj).length === 0
Examples:
let obj = "this is an object with String constructor"
console.log(pureObjectIsEmpty(obj)) // empty? true
obj = {}
console.log(pureObjectIsEmpty(obj)) // empty? true
obj = []
console.log(pureObjectIsEmpty(obj)) // empty? true
obj = [{prop:"value"}]
console.log(pureObjectIsEmpty(obj)) // empty? true
obj = {prop:"value"}
console.log(pureObjectIsEmpty(obj)) // empty? false
When sure that the object is a user-defined one, the easiest way to determine if UDO is empty, would be the following code:
isEmpty=
/*b.b Troy III p.a.e*/
function(x,p){for(p in x)return!1;return!0};
Even though this method is (by nature) a deductive one, - it's the quickest, and fastest possible.
a={};
isEmpty(a) >> true
a.b=1
isEmpty(a) >> false
p.s.:
!don't use it on browser-defined objects.
You can use the following:
Double bang !! property lookup
var a = !![]; // true
var a = !!null; // false
hasOwnProperty
This is something that I used to use:
var myObject = {
name: 'John',
address: null
};
if (myObject.hasOwnProperty('address')) { // true
// do something if it exists.
}
However, JavaScript decided not to protect the method’s name, so it could be tampered with.
var myObject = {
hasOwnProperty: 'I will populate it myself!'
};
prop in myObject
var myObject = {
name: 'John',
address: null,
developer: false
};
'developer' in myObject; // true, remember it's looking for exists, not value.
typeof
if (typeof myObject.name !== 'undefined') {
// do something
}
However, it doesn't check for null.
I think this is the best way.
in operator
var myObject = {
name: 'John',
address: null
};
if('name' in myObject) {
console.log("Name exists in myObject");
}else{
console.log("Name does not exist in myObject");
}
result:
Name exists in myObject
Here is a link that goes into more detail on the in operator: Determining if an object property exists
Very late answer, but this is how you could handle it with prototypes.
Array.prototype.Any = function(func) {
return this.some(func || function(x) { return x });
}
Object.prototype.IsAny = function() {
return Object.keys(this).Any();
}
Object.hasOwn is a new static method (not fully supported by all browsers yet) which checks if the specified object has the indicated property as his own property and return true if that is the case. It will return false if the property is either inherited or does not exist on that object.
You can iterate through the object properties and check if they are indeed own properties
for (let property in ad) {
if (Object.hasOwn(ad, property)) {
// handle your code for object own properties here
}
}
More about Object.hasOwn - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/
Browser compatibility here - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn#browser_compatibility
I'm not sure if this is a good approach but I use this condition to check if an object has or hasn't any property. Could be easily transformed into a function.
const obj = {};
if(function(){for (key in obj){return true}return false}())
{
//do something;
}
else
{
//do something else;
}
//Condition could be shorted by e.g. function(){for(key in obj){return 1}return 0}()
How about this?
var obj = {},
var isEmpty = !obj;
var hasContent = !!obj

Check if an array item is set in JS

I've got an array
var assoc_pagine = new Array();
assoc_pagine["home"]=0;
assoc_pagine["about"]=1;
assoc_pagine["work"]=2;
I tried
if (assoc_pagine[var] != "undefined") {
but it doesn't seem to work
I'm using jquery, I don't know if it can help
Thanks
Use the in keyword to test if a attribute is defined in a object
if (assoc_var in assoc_pagine)
OR
if ("home" in assoc_pagine)
There are quite a few issues here.
Firstly, is var supposed to a variable has the value "home", "work" or "about"? Or did you mean to inspect actual property called "var"?
If var is supposed to be a variable that has a string value, please note that var is a reserved word in JavaScript and you will need to use another name, such as assoc_var.
var assoc_var = "home";
assoc_pagine[assoc_var] // equals 0 in your example
If you meant to inspect the property called "var", then you simple need to put it inside of quotes.
assoc_pagine["var"]
Then, undefined is not the same as "undefined". You will need typeof to get the string representation of the objects type.
This is a breakdown of all the steps.
var assoc_var = "home";
var value = assoc_pagine[assoc_var]; // 0
var typeofValue = typeof value; // "number"
So to fix your problem
if (typeof assoc_pagine[assoc_var] != "undefined")
update: As other answers have indicated, using a array is not the best sollution for this problem. Consider using a Object instead.
var assoc_pagine = new Object();
assoc_pagine["home"]=0;
assoc_pagine["about"]=1;
assoc_pagine["work"]=2;
var assoc_pagine = new Array();
assoc_pagine["home"]=0;
Don't use an Array for this. Arrays are for numerically-indexed lists. Just use a plain Object ({}).
What you are thinking of with the 'undefined' string is probably this:
if (typeof assoc_pagine[key]!=='undefined')
This is (more or less) the same as saying
if (assoc_pagine[key]!==undefined)
However, either way this is a bit ugly. You're dereferencing a key that may not exist (which would be an error in any more sensible language), and relying on JavaScript's weird hack of giving you the special undefined value for non-existent properties.
This also doesn't quite tell you if the property really wasn't there, or if it was there but explicitly set to the undefined value.
This is a more explicit, readable and IMO all-round better approach:
if (key in assoc_pagine)
var is a statement... so it's a reserved word... So just call it another way.
And that's a better way of doing it (=== is better than ==)
if(typeof array[name] !== 'undefined') {
alert("Has var");
} else {
alert("Doesn't have var");
}
This is not an Array.
Better declare it like this:
var assoc_pagine = {};
assoc_pagine["home"]=0;
assoc_pagine["about"]=1;
assoc_pagine["work"]=2;
or
var assoc_pagine = {
home:0,
about:1,
work:2
};
To check if an object contains some label you simply do something like this:
if('work' in assoc_pagine){
// do your thing
};
This worked for me
if (assoc_pagine[var] != undefined) {
instead this
if (assoc_pagine[var] != "undefined") {
TLDR; The best I can come up with is this: (Depending on your use case, there are a number of ways to optimize this function.)
function arrayIndexExists(array, index){
if ( typeof index !== 'number' && index === parseInt(index).toString()) {
index = parseInt(index);
} else {
return false;//to avoid checking typeof again
}
return typeof index === 'number' && index % 1===0 && index >= 0 && array.hasOwnKey(index);
}
The other answer's examples get close and will work for some (probably most) purposes, but are technically quite incorrect for reasons I explain below.
Javascript arrays only use 'numerical' keys. When you set an "associative key" on an array, you are actually setting a property on that array object, not an element of that array. For example, this means that the "associative key" will not be iterated over when using Array.forEach() and will not be included when calculating Array.length. (The exception for this is strings like '0' will resolve to an element of the array, but strings like ' 0' won't.)
Additionally, checking array element or object property that doesn't exist does evaluate as undefined, but that doesn't actually tell you that the array element or object property hasn't been set yet. For example, undefined is also the result you get by calling a function that doesn't terminate with a return statement. This could lead to some strange errors and difficulty debugging code.
This can be confusing, but can be explored very easily using your browser's javascript console. (I used chrome, each comment indicates the evaluated value of the line before it.);
var foo = new Array();
foo;
//[]
foo.length;
//0
foo['bar'] = 'bar';
//"bar"
foo;
//[]
foo.length;
//0
foo.bar;
//"bar"
This shows that associative keys are not used to access elements in the array, but for properties of the object.
foo[0] = 0;
//0
foo;
//[0]
foo.length;
//1
foo[2] = undefined
//undefined
typeof foo[2]
//"undefined"
foo.length
//3
This shows that checking typeof doesn't allow you to see if an element has been set.
var foo = new Array();
//undefined
foo;
//[]
foo[0] = 0;
//0
foo['0']
//0
foo[' 0']
//undefined
This shows the exception I mentioned above and why you can't just use parseInt();
If you want to use associative arrays, you are better off using simple objects as other answers have recommended.
if (assoc_pagine.indexOf('home') > -1) {
// we have home element in the assoc_pagine array
}
Mozilla indexOf
function isset(key){
ret = false;
array_example.forEach(function(entry) {
if( entry == key ){
ret = true;
}
});
return ret;
}
alert( isset("key_search") );
The most effective way:
if (array.indexOf(element) > -1) {
alert('Bingooo')
}
W3Schools

Categories

Resources