4 ms·
This is problematic in that you don't control external APIs. For example look at the DOM which preferences null but returns undefined when there is a language
by austincheney 6y ago
This is problematic in that you don't control external APIs. For example look at the DOM which preferences null but returns undefined when there is a language construct in the way:
document.getElementById("asdf") // returns null;
document.getElementsByTagName("asdf") // returns [];
document.getEleemntsByTagName("asdf")[0] // returns undefined
document.getElementsByTagName("body")[0].getAttribute("asdf") // returns null
//
document.getElementsByTagName("input") // assuming not empty for the next several lines
document.getElementsByTagName("input")[0] // Element object
document.getEleemntsByTagName("input")[0].value // returns "" as valus is implicitly an empty string if not supplied
document.getElementsByTagName("div")[0].value // returns undefined even though the element is present but expresses an inference to an unsupported property
I completely agree supporting both null and undefined complicates some forms of validation, but I have accounted for this in my test automation. I don't encounter this problem with input validation or managing event handlers.
Here are the rules I use:
* undefined is a value where a value is never before assigned. Yes, you can do stupid things in opposition to the default such as arbitrarily assigning undefined or even redefining undefined to an assignment, but those footguns are not be accident.
* null is a value that is explicitly assigned.
If you program with those assumptions in mind you are safe 99% of the time given default language constructs, which doesn't account for the intentionally bad decisions other people make. This also helps with troubleshooting because when an error is encountered due to a null or undefined value the assignment distinction helps to diagnose the problem.
- roguesherlock 6y agoI actually find all of the return values reasonable. As you said, undefined == I just don’t know what the value is null == I know that there isn’t supposed to be a value here.
- amw-zero 6y agoWhy is this distinction important practically?
- jolux 6y agoIt shouldn’t be but due to the way JavaScript is structured it is.
- lmm 6y agoBecause they mean very different things. E.g. "no-one owns this land" is very different from "I don't know who owns this land". "You don't need to do anything" is very different from "I don't know what you need to do". "No-one's in that room" is very different from "I don't know who's in that room". Of course the practical difference depends on context, but so does the practical difference between 2 and 3.
- amw-zero 6y agoThat’s not what I asked. I know what the distinction is. I asked why would I ever need that distinction in a program. In 10 years I’ve never come across a situation where I found that distinction useful.
- thenanyu 6y agoAgree. I would never attempt to write flow control that had different cases for handling undefined and null. It feels so extremely brittle
- reificator 6y agoUndefined should mean in most cases that you've made a programming mistake, be that a typo or an invalid assumption about the type of thing you're getting back. Null should mean in most cases that the data you wanted to access was invalid, but you can expect it to exist there in other circumstances. Neither are a guarantee in JS, and you can find counterexamples for the counterexamples of the counterexamples, but that's the intention behind each.
- megous 6y agoIn the past it was one of the ways to distinguish between arguments to function that were not passed in by the caller.
- anuila 6y agoIf the value is expected to be a Boolean, use undefined to set it as undefined. For everything else, use false to “explicitly assign it”, you don’t need a third type.
- JimDabell 6y ago> use false to “explicitly assign it” Then you still have null, you’re just spelling it funny while confusing all the other developers who have to deal with your code and making it incompatible with language constructs like the nullish coalescing operator. If the concept you are trying to express is “null”, then please use null to represent that instead of bringing in a poor substitute like an overloaded false.
- anuila 6y agoNo, most likely I'll just use undefined because my abstractions are not a complicated mess that need 2 null types. Found? string Not found? undefined
- JimDabell 6y ago> most likely I'll just use undefined You were telling people to use false and that’s what I was responding to. That’s why I quoted that part in my comment.
- seanwilson 6y ago> document.getElementById("asdf") > document.getElementsByTagName For what it's worth I usually wrap these functions to e.g. throw an error if they don't find any items as that's what you usually want to happen but forget to write checks for. It's rare I'll use getElementById and expect it not to find something. Lots of undefined + null values crop up from situations like this where you want to fail when something you expect to be there isn't found e.g. file handling, dictionaries, web requests. It's a no-brainer to use TypeScript as well if you want robustness from these kinds of bugs, where returning undefined or a value is more practical because TypeScript will force you to check for undefined. I don't understand why anyone would willingly give up to type checks like these as it's obvious to me you can't compete with automated checking.
- anonytrary 6y agoconst w = (fn, _) => function(...args){ return (_ = fn(...args)) === null ? undefined : _; }; document.getElementById = w(document.getElementById.bind(document));
- cmroanirgo 6y agoI seriously hope this is joke code. Returning undefined for null, as well as changing dom functions is a great way to ensure unintended side effects will creep into your code.
- philihp 6y agoFor sure you wouldn’t actually commit this, but it’s for sure interesting to do the mental gymnastics to understand it.
- anonytrary 6y agoIt is an illustration of a concept. I wouldn't call it a joke, but I also wouldn't use it.
- sergeykish 6y agoundefined would be rare foo //Uncaught ReferenceError: foo is not defined if not property access, and it lies o = { foo: undefined } o.foo //undefined o.hasOwnProperty('foo') //true Array is an object, access by index is property access a = [] a[0] //undefined That's unfortunate. In Ruby: foo #NameError (undefined local variable or method `foo' for main:Object) defined?(foo) #=> nil o = Object.new o.foo #NoMethodError (undefined method `foo' for #<Object:0x000055f2f4e56e78>) a = [] a[0] #=> nil And Ruby enforces method arity and keyword parameters: def foo(value) end foo #ArgumentError (wrong number of arguments (given 0, expected 1)) def bar(value:) end bar #ArgumentError (missing keyword: :value) Basically it throws on undefined. I think reimplementation is a great way to uncover how things work, Ruby "fix" for property access http://sergeykish.com/ruby-like-javascript-undefined.rb http://sergeykish.com/ruby-like-javascript-undefined.rb Anyone knows how to relax arity?