I have the following javascript function that fails a jslint check
function hasActiveX() {
return ('ActiveXObject' in window);
}
jslint error
Unexpected 'in'. Compare with undefined, or use the hasOwnProperty method instead.
should I just live with the jslint error, or is there a better way to determine ActiveXObject?
I could not find a jslint flag to skip this check?
Ignore the error. The "in" operator is clearly defined in ECMA 262-5.1 / June 2011 sec-11.8.7
There appear to be only three outcomes for 'someProperty' in anObject which is one of: true, false, or a TypeError exception is thrown. When it evaluates to true, then there is definitely 'someProperty' in anObject. When it evaluates to false there is definitely not 'someProperty' in anObject. When a TypeError is thrown there is definitely not 'someProperty' in anObject because anObject is either null or it isn't an object at all. This all seems very clear to me. When I want to know if an object has a property and, I don't care if that property is the object's own property or being inherited and, I don't care what the value of the property is, then I simply look for 'someProperty' in anObject.
Warning
Caution: some would have you check for anObject.someProperty !== undefined but that isn't really checking whether or not the object has the property. What it's doing is checking whether the object has the property AND that the value of that property is NOT undefined. Some would have you check for anObject.hasOwnProperty('someProperty'); but that will only tell you if the object has that property AND has NOT inherited it somehow. Don't believe me? Try the following:
console.log(document.body.tagName);
// BODY
console.log(document.body.hasOwnProperty('tagName'));
// false, it's inherited
console.log('tagName' in document.body);
// true, it does have the property
document.body.wobbles = undefined;
// new property added to document.body
console.log('wobbles' in document.body);
// true, it does have the property
console.log(document.body.wobbles !== undefined);
// false, the value really IS undefined
I've written an article about the "in" operator that goes into more detail. If you want to read it it's at: http://matthewkastor.blogspot.com/2012/09/Unexpected--in---Compare-with-undefined--or-use-the-hasOwnProperty-method-instead.html The bottom line is that you should just ignore this error and wrap things up in a try catch block if the object might be null or not an object.
function hasProperty(prop, obj) {
try {
return prop in obj;
} catch(e) {
return e;
}
}
I think JSLint is asking you to try:
function hasActiveX() {
return window.hasOwnProperty('ActiveXObject');
}
Or the other suggestion of comparing against "undefined":
return (typeof(window.ActiveXObject) != "undefined");
Personally, I prefer the former.
After reading the comments, it seems like in is actually useful if JSLint would stop complaining about it, otherwise I would try option 2 above.
Related
I am going to test if 'session' property exists:
console.log(queryData)
console.log(typeof queryData)
if ('session' in queryData) {
console.log('in')
}
else {
console.log('not in')
}
if (queryData.hasOwnProperty('session')) {
console.log('has own propety')
}
Its result is:
[Object: null prototype] { session: '0geBdiCsfczLQiT47dd45kWVN2Yp' }
object
in
/home/ubuntu/22.enmsg/cli/main.js:72
if (queryData.hasOwnProperty('session')) {
^
TypeError: queryData.hasOwnProperty is not a function
Why does the hasOwnProperty NOT work?
Most objects in javascript inherit from Object; it's possible to intentionally create objects that inherit from nothing (i.e., null), and therefore they won't have any of the typical methods you'd expect to live on the object.
You would normally know if your code was doing this, so the object might be something passed to you from another library.
A way around the error is to call hasOwnProperty on Object explicitly, and bind it to the object, like so:
// Calls "hasOwnProperty" on queryData, even if queryData has
// no prototype:
console.log(Object.hasOwnProperty.bind(queryData)('session'));
EDIT: Just editing to add an opinion, which is that a much better line for your purposes is the simple truthy check if (queryData.session) {. The vagueness of this check is a strength when what you're asking is "did a session get passed?" - if session is null, undefined, false, empty string, or the key is missing altogether, the answer is clearly "no".
The easiest solution is to convert your null-prototype object to a standard javascript Object. You can do so by:
OBJjavascript = JSON.parse(JSON.stringify(objNullPrototype));
Parsing the object as in https://stackoverflow.com/a/56488323/3121906 would technically work but would be expensive for large objects.
https://stackoverflow.com/a/53978289/3121906 is good, but why not just use call?
Object.prototype.hasOwnProperty.call(queryData, 'session')
I'm trying to test some code that does different things depending on the environment. I thought I might be able to modify properties on process.env in my tests (although I thought it might be a bad idea), but I realized I get this really odd behavior:
let foo = function(inp) {
if (inp) {
console.log(inp + ' -> if')
} else {
console.log(inp + ' -> else')
}
}
// property starts undefined
foo(process.env.prop)
// undefined -> else
process.env.prop = true
foo(process.env.prop)
// true -> if
process.env.prop = false
foo(process.env.prop)
// false -> if !!!
process.env.prop = undefined
foo(process.env.prop)
// undefined -> if !!!
delete(process.env.prop)
foo(process.env.prop)
// undefined -> else
I expected that setting process.env.prop = false would have caused the else branch to execute, not the if branch. If I use properties on new objects, I do get the behavior I expect (Link to REPL demonstrating this: https://repl.it/#JustinKulikausk/TechnologicalThickMuse).
Has anyone else experienced this? I'm really hoping for some insight into why this is happening, not just a workaround for my tests.
Props are strings. From the docs (v10.4.1)
Assigning a property on process.env will implicitly convert the value to a string. This behavior is deprecated. Future versions of Node.js may throw an error when the value is not a string, number, or boolean.
Your false is converted to 'false' which is "truthy" as it is a valid string of length 5. Same with keyword undefined. Your delete is legit. I'm not sure which part is deprecated, but the behavior you describe looks like it is working as expected.
Suppose I have some variables:
var s = 's', i = 0, o = {}, a = [], n = null, nan = NaN, u;
How can I make any sense of when reading x.p will return undefined, and when it will throw a TypeError?
s.p; // undefined
i.p; // undefined
o.p; // undefined
a.p; // undefined
n.p; // TypeError!
nan.p; // undefined
u.p; // TypeError!
P.S. Are null and undefined the only weird values in this way? Are there others?
Edit
I'm aware that by declaring variables as I have, several of my values have been automatically wrapped by objects (e.g. Number), despite being primitives. Therefore I can treat them like "proper" objects (e.g. {}, []) and attempt to read their properties. But I can't find much explaining what is and isn't wrapped this way.
Yes, null and undefined are the only values that throw an exception when being used in a property access. The dot and bracket property accessors do invoke the internal CheckObjectCoercible function, which is defined as following:
The abstract operation CheckObjectCoercible throws an error if its
argument is a value that cannot be converted to an Object using
ToObject. It is defined by Table 15:
Table 15 — CheckObjectCoercible Results
Argument Type | Result
--------------+------------------
Undefined | Throw a TypeError exception.
Null | Throw a TypeError exception.
Boolean | Return
Number | Return
String | Return
Object | Return
null and undefined being the values that represent Nothing cannot be converted to objects ("wrapped" as you say). Notice that you could of course have an object with an existing property that throws on access, like
var o = {get p() { throw new TypeError("you may not access this"); }};
o.p // TypeError
When you're reading the property of something that's undefined. You're basing saying:
What is undefined of undefined? or in the case of null what is undefined of null ? Neither undefined nor null are objects, therefore you can't set or get properties on/from them. With that in mind, an error will be thrown.
When the object is null/undefined, it'll throw an error because it'll try to access a property of an object that does not exist in first place.
On the other cases, it'll try to access a property of an existing object and will return undefined because the property is not found.
Please note that almost everything in js is an object, as you can see here.
let's firstly start with
why undefined on:
var s='s';
You assigned s to string which is primitive type. Javascript is tricky here in one sense. Though primitive type, when you try to access the property by doing:
s.p
It firstly does this internally:
String(s)
and creates the object and then tries to see if it has that property which is, of course not defined and thus you get undefined. Almost similar things happen with numerical assignment and NAN.
For n=null:
If you do:
var n=null;
typeof n;//"object"
n.p// throws typeerror
In fact,null can be thought of special kind of object without any properties or method to represent absence of value and thus, you get typeerror when you try to access any properties of null.
a.p
o.p
Easily, you can see that you are trying to access the property of an object than is not defined or not built-in and thus it should say, undefined. You should be surprised to see other than that :D.
To add to the other answers here, there is an easy way to check if a property access will throw an exception. Simply loosely compare the value you're unsure of to null, like so:
if(x != null) { // note the LOOSE equality, rather than !==
// do something with x.prop
}
The reason this works is that only null and undefined * throw errors on property access, and they are only loosely equal to each other. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_when_to_use_them.
* There is also a case where some JS objects can apparently "emulate" being undefined, in which case they also are loosely equal to null and undefined.
This question already has answers here:
What is the difference between null and undefined in JavaScript?
(38 answers)
Closed 8 years ago.
I am really confused as to when JavaScript returns null or undefined. Also different browsers seem to be returning these differently.
Could you please give some examples of null/undefined with the browsers that return them.
While I am now clear on the undefined aspect, I am still not 100% clear on null. Is it similar to a blank value?
E.g. You have a text box which does not have any value set. Now when you try to access its value, will it be null or undefined and are they similar?
I find that some of these answers are vague and complicated, I find the best way to figure out these things for sure is to just open up the console and test it yourself.
var x;
x == null // true
x == undefined // true
x === null // false
x === undefined // true
var y = null;
y == null // true
y == undefined // true
y === null // true
y === undefined // false
typeof x // 'undefined'
typeof y // 'object'
var z = {abc: null};
z.abc == null // true
z.abc == undefined // true
z.abc === null // true
z.abc === undefined // false
z.xyz == null // true
z.xyz == undefined // true
z.xyz === null // false
z.xyz === undefined // true
null = 1; // throws error: invalid left hand assignment
undefined = 1; // works fine: this can cause some problems
So this is definitely one of the more subtle nuances of JavaScript. As you can see, you can override the value of undefined, making it somewhat unreliable compared to null. Using the == operator, you can reliably use null and undefined interchangeably as far as I can tell. However, because of the advantage that null cannot be redefined, I might would use it when using ==.
For example, variable != null will ALWAYS return false if variable is equal to either null or undefined, whereas variable != undefined will return false if variable is equal to either null or undefined UNLESS undefined is reassigned beforehand.
You can reliably use the === operator to differentiate between undefined and null, if you need to make sure that a value is actually undefined (rather than null).
According to the ECMAScript 5 spec:
Both Null and Undefined are two of the six built in types.
4.3.9 undefined value
primitive value used when a variable has not been assigned a value
4.3.11 null value
primitive value that represents the intentional absence of any object value
The DOM methods getElementById(), nextSibling(), childNodes[n], parentNode() and so on return null (defined but having no value) when the call does not return a node object.
The property is defined, but the object it refers to does not exist.
This is one of the few times you may not want to test for equality-
if(x!==undefined) will be true for a null value
but if(x!= undefined) will be true (only) for values that are not either undefined or null.
You get undefined for the various scenarios:
You declare a variable with var but never set it.
var foo;
alert(foo); //undefined.
You attempt to access a property on an object you've never set.
var foo = {};
alert(foo.bar); //undefined
You attempt to access an argument that was never provided.
function myFunction (foo) {
alert(foo); //undefined.
}
As cwolves pointed out in a comment on another answer, functions that don't return a value.
function myFunction () {
}
alert(myFunction());//undefined
A null usually has to be intentionally set on a variable or property (see comments for a case in which it can appear without having been set). In addition a null is of type object and undefined is of type undefined.
I should also note that null is valid in JSON but undefined is not:
JSON.parse(undefined); //syntax error
JSON.parse(null); //null
I might be missing something, but afaik, you get undefined only
Update: Ok, I missed a lot, trying to complete:
You get undefined...
... when you try to access properties of an object that don't exist:
var a = {}
a.foo // undefined
... when you have declared a variable but not initialized it:
var a;
// a is undefined
... when you access a parameter for which no value was passed:
function foo (a, b) {
// something
}
foo(42); // b inside foo is undefined
... when a function does not return a value:
function foo() {};
var a = foo(); // a is undefined
It might be that some built-in functions return null on some error, but if so, then it is documented. null is a concrete value in JavaScript, undefined is not.
Normally you don't need to distinguish between those. Depending on the possible values of a variable, it is sufficient to use if(variable) to test whether a value is set or not (both, null and undefined evaluate to false).
Also different browsers seem to be returning these differently.
Please give a concrete example.
Regarding this topic the specification (ecma-262) is quite clear
I found it really useful and straightforward, so that I share it:
- Here you will find Equality algorithm
- Here you will find Strict equality algorithm
I bumped into it reading "Abstract equality, strict equality, and same value" from mozilla developer site, section sameness.
I hope you find it useful.
A property, when it has no definition, is undefined.
null is an object. It's type is null. undefined is not an object, its type is undefined.
This is a good article explaining the difference and also giving some examples.
null vs undefined
I have been using JavaScript for couple of years and never cared about the difference between null & undefined earlier, I always use undefined to validate the object existence.
But recently I came through this article. Here they said
JavaScript distinguishes between null, which is an object of type 'object' that indicates a deliberate non-value, and undefined, which is an object of type 'undefined' that indicates an uninitialized value — that is, a value hasn't even been assigned yet. We'll talk about variables later, but in JavaScript it is possible to declare a variable without assigning a value to it. If you do this, the variable's type is undefined.
I am completely confused now, what exactly is non-value here. How this non-value differs from undefined. And what are the circumstances javascript returns null.
I have tried the below sample
var sam;
alert(sam); // returns undefined
And
try {
//var sam;
alert(sam);
} catch(ex) { } // exception says: sam is undefined
And I am not sure about when js returning nulls. Can someone clarify me.
alert(sam); // returns undefined
Nope, that's an exception.
You get undefined when you access an unset property; you get an error when you use an unset name directly.
Global variables are interesting because they can be accessed either using a simple variable name, or by using properties of the window global object:
alert(window.sam); // undefined
alert(window['sam']); // undefined
alert('sam' in window); // false
alert(sam); // ERROR
If sam is declared but not initialised, accessing window.sam still gets you undefined, but for a different reason: there is an entry in the window object for sam, but it points to the same undefined object as you get when you access a non-existant property.
var sam;
alert(window.sam); // undefined
alert(window['sam']); // undefined
alert('sam' in window); // ** true
alert(sam); // ** undefined
This is of course a confusing bloody mess; undefined is one of the worst mistakes in the design of the JavaScript language.
null on the other hand is fine and works pretty much the same as null/nil/void/None values in other languages. It doesn't come into any of the above.
<script type="text/javascript">
// variable with an unasigned value
var a;
if (a == undefined) {
alert('a is undefined');
}
if (a == null) {
alert('a is undefined');
}
// this will produce an error
if (b == undefined) {
alert('b is undefined');
}
// this is the right way to handle not defined variables
if (typeof(c) == 'undefined') {
alert('c is blabla');
}
</script>
For a variable to receive a null value it must be assigned. null is used to indicate an unknown or don't care value. undefined on the other hand is designed to indicate that the propery being accessed has never ben assigned a value. This differs from null.
With null one is deliberately saying "I don't know what value this should have yet" or "I don't care what value this is right now". OTH in undefined is really saying "Are you sure you should be using this value it hasn't been assigned".
The way I distinguish them is undefined being "I have not defined this value," and null being "I have defined this value, but I do not know or cannot figure out what the value should be."