Comments (26)
The reason why comparision to undefined
is not practiced, is that in most old browser engines you can overwrite it:
window.undefined = 'foo';
alert('foo' === undefined); // true
Therefore it's not safe. Imagine also small mistake in a code that inserts <div id="undefined"></div>
to the document, after that all your undefined
comparisons are doomed.
from javascript.
Thanks for bringing this up! I agree that this topic should be covered and that in many cases it's appropriate to do direct comparisons to undefined
vs. using typeof === "undefined"
.
One thing I think you should look at though is the statement "undefined is an object..." since technically that's not correct. undefined
is a primitive per the ECMAScript Spec.
I'll let @hshoff give his two cents...
from javascript.
Hm... true about "object", I'm still used to it meaning any-value as in many other languages. But undefined also isn't exactly a value, it's a unique singleton object like true or false. I'm not sure what it should be called?
from javascript.
There's lots of ways you can mess up your Javascript environment, I'm not sure why this is more unsafe?
from javascript.
Because this one may happen by accident. There are many ways to have window.undefined
compromised by simple error.
Thankfully it's fixed in ES5, so in modern engines it's completely safe to use undefined
from javascript.
@medikoo - Thanks for bringing this up. We should definitely mention that undefined
can be overwritten in certain engines and therefore can't always be trusted. Luckily there is a best-practice that gets around that. You can protect yourself from a modified undefined
by writing your code inside an anonymous function, which has undefined
as an argument that doesn't get passed anything. You'll know that inside that scope you can always trust undefined
.
undefined = 4;
(function($, undefined) {
var x;
x === undefined; // true
})(jQuery);
In most cases you should be writing code like this, especially if you're working in an environment that you don't have full control over, like a web page with scripts that you didn't author. The jQuery source code, for example, does this. We should include this quirk in the forthcoming undefined
section.
@ianb - I'd call undefined
a "primitive value" for now - like true
, false
, 3
, and null
. Technically undefined
is the only member of the undefined type, which is it's own type like boolean, number, etc... I feel like maybe there's better phrasing though.
from javascript.
"Primitive value" sounds good to me.
Would var undefined;
accomplish the same thing as the function argument, except without the possibility of getting it wrong (e.g., passing an argument in accidentally)?
It seems like a section on "defensive programming" might make sense β describing when you need to write defensively (you don't always), and things like this undefined issue, hasOwnProperty, and... I'm sure other people will find things to add too.
from javascript.
These are great ideas, I love discussions like this.
Perhaps we could create a section called "Quirks" and have sub-sections on things to watch out for? Then we could separate out the "defensive programming" things from the "things to keep in mind". It would be great to loop in the pull request from @getify about clarifying null
#35.
That would be a lovely resource to have and it'd be awesome to get new pull requests explaining problem areas and solutions (such as this undefined
issue).
@ianb I'm reading over your fork right now. Lots of great stuff in there. It's inspiring me to add more explanation behind the choices made, just so it's clear why we called it "mostly reasonable".
from javascript.
One word about overwriting undefined :)
Thanks to coercion both
undefined == null
and
null == undefined
produce true values.
The key here is that null cannot be redefined.
I would rather use 'something == null' for my conditions.
It's thoroughly explained in this wonderful post: http://webreflection.blogspot.ie/2010/10/javascript-coercion-demystified.html
from javascript.
@jterenzio 's comment is very important. I was often asking myself why jQuery and others used (function(window, undefined) { ... });
Just to add to the discussion:
- I was reviewing the code of one of my colleagues and he used:
if(mycart.products !== null && mycart.products !== undefined)
instead I replaced withif( mycart && mycart.products )
. I wanted to exclude all the falsy values:0
,false
,''
,undefined
,null
,NaN
. - jQuery seems to have strangely removed the
undefined
from the closure:
jquery/jquery@c93f91e#commitcomment-3620247
from javascript.
Here is another one to consider for such a section:
var foo = {}
foo.bar === void(0) // => true
from javascript.
π
@fschaefer I second mentioning void(0)
. I hope to never see it in unminified code. It's ugly & unreadable.
from javascript.
If you're going to mention void
operator, explain how it really works (using it like void(0)
kinda in function-call form is bizarre and mis-leading).
void
is an operator that always returns undefined
, no matter what operand you pass to it. Idiomatically, people use void 0
since that's from the C-language days for null pointers, but void true
would have the same behavior, though arguably a bit more confusing.
I tend not to make distinctions between null
and undefined
in my code, so I use coercion via the == null
check to check for either value and treat them as the same. However, there are some rare cases where you want to explicitly want to say "undefined", such as a placeholder value in an array, for instance.
The question becomes, is the identifier undefined
better than void 0
for those cases. I think it's a wash. I kinda like void 0
, but I don't really care strongly.
BTW, there are some limited cases where I've found it to be quite useful. I once used void
to empty out the return value of a function call that was itself being returned, sorta like this:
function doSomethingElse(o) {
return (o.foo = 3);
}
function doSomething(x) {
if (typeof x === "object") return void doSomethingElse(x);
return x;
}
var results = [
doSomething(3),
doSomething(4),
doSomething(results),
doSomething(5)
];
// [3,4,undefined,5]
results.foo; // 3
from javascript.
@getify Interesting use case, but I don't doubt it would cause confusion for many.
from javascript.
@Daniel-Hug library authors use parts of the language all the time that are likely to confuse the common developer. Of course, a lot of developers learn about the language by looking at library code to learn how they do it.
Would you rather have documentation that explained what something was doing in case someone runs across it, or would you rather omit it, or even worse, mention it and say "no , no, this is bad" and leave the common developer unable to fully learn what it is they're seeing?
from javascript.
doesn't no-undefined
address this issue?
from javascript.
That rule prevents use of the literal but doesn't add an explanatory section to the guide.
from javascript.
The fear of a redefined undefined
is one of the two main reasons behind allowing == null
comparisons: #1473 (comment) All ES3 browsers are dead, and the local-scope-level redefinition in ES5 is mitigated by no-undefined
. Why not revise the policy?
from javascript.
Why would we revise it? It still remains a best practice to treat null and undefined
the same; what would you suggest as an alternative?
from javascript.
I'm talking about the recommendation of using typeof x === 'undefined'
instead of x === undefined
. In addition to that, part of the argument for == null
rests on how verbose the alternative is, and without typeof
it becomes less of a concern.
from javascript.
even if x === undefined
was a good idea (itβs not, and no-undefined
forbids it anyways), it would still always be important to use == null to treat null and undefined
the same - so although the reasons might be updated, the conclusion would not be.
@ianb Iβm interested in closing this; would you be willing to make a PR as outlined in your OP?
from javascript.
Actually, I've misread the description of no-undefined
(skimmed too fast). I thought it was about disallowing the shadowing of undefined
, but it's about disallowing undefined
completely. Which throws the baby out with the bathwater, IMO.
The above aside, why is x === undefined
not a good idea in ES5? Isn't it the same as trusting that new Error
will produce a regular error, or that the JSON
global has a stringify
method, or that isNaN
isn't a no-op that returns false
for any input? As @ianb said:
There's lots of ways you can mess up your Javascript environment, I'm not sure why this is more unsafe?
And @medikoo's reply, about ES3, was valid-ish back in 2013, but it isn't anymore.
from javascript.
Any ways that anyone could mess up your javascript environment, you should be trying to protect yourself against. This one is trivial to address.
When are you checking for just undefined
such that == null isnβt ideal?
from javascript.
In undefined
's case, we're already fully protected by no-shadow-restricted-names
, no?
I have replied to your question in #1473 (comment) (it's off-topic in this thread).
from javascript.
Only in linted code, which doesn't include any third-party code. Linting rules are not bulletproof safeguards against runtime security holes.
from javascript.
This is the only way it can happen:
const ourInnocentCode = 'console.log(undefined)';
{ // Or a closure
const undefined = 'ha, not undefined'; // Or `let` / `var`
eval(ourInnocentCode);
// > "ha, not undefined"
}
No <div id="undefined">
, no window.undefined = 'foo'
. Can't be affected by other <script>
s. Can't be naive concatenation, because it would put our code on the global scope, where undefined
is safe. Is this really worth being protected against?
And even if it were (it isn't, unless I'm missing something), why not solve it by wrapping the whole bundle in a closure/block, with a safe undefined
, set to void 0
or something like that? Why does it have to be something a programmer needs to worry about?
from javascript.
Related Issues (20)
- [spam]
- [spam]
- Support Biome extends HOT 3
- [spam] HOT 1
- [spam]
- [spam] HOT 1
- Multiline comments HOT 3
- [spam]
- [spam]
- TypeError: Failed to load plugin 'jsx-a11y' declared HOT 4
- [spam]
- [spam] HOT 1
- Regarding Updation HOT 4
- [spam] HOT 1
- [spam]
- Link 404 not found HOT 2
- Can we add on quiz sections on this repo too HOT 11
- [spam]
- eslint v9 support
- [spam]
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from javascript.