Sean Robertson

Sean Robertson

1550372388

What was Javascript "undefined" intended for?

#javascript

What is GEEK

Buddha Community

Zachary Palmer

1550374883

When a variable is not declared, it is undefined. In JavaScript, when you use the typeof operator it provides the type of a variable. Instead of crying that is doesn’t exist, it returns “undefined”.

function undefinedTest() {
	var x = 10;
	if(typeof x == "undefined") return 1; // This will never happen since x has been defined.
	if(typeof y == "undefined") return 2; // Unless y was defined in the global scope, y will be undefined so the function will return 2.
 
	return false;
}

It was intended because JavaScript is supposed to be very flexible. Instead of crashing at the sight of an undeclared variable, you can handle it and hopefully continue execution without issue.

It can be useful in functions, since overloading isn’t a thing in JavaScript you can essentially simulate it:

function doSometing(v1, v2) {
	if(typeof v2 == "undefined") {
		return doSomethingV1(v1);
	// Do stuff
	return ...
}

In that example, if you call doSomething(“a value”) it will actually return the results of doSomethingV1.

Though I don’t think this was its original intention, it’s certainly a useful byproduct when creating reusable code.

for any variable, function, array[index], object.Property or Object.method used but was not defined

Sierra  Roob

Sierra Roob

1591072140

7 Tips to Handle Undefined in JavaScript

7 Tips to Handle Undefined in JavaScript
When I started to learn JavaScript about eight years ago, I found bizarre that both undefined and null represent empty values.
Most of the modern languages like Ruby, Python or Java have a single null value (nil or null), which seems a reasonable approach.
But JavaScript is different.
The JavaScript interpreter returns undefined when accessing a variable or object property that is not yet initialized.

#javascript #undefined #programming

Ysia Tamas

1573611289

JavaScript | How to handling null and undefined in JavaScript

One aspect of JavaScript development that many developers struggle with is dealing with optional values. What are the best strategies to minimize errors caused by values that could be null, undefined, or otherwise uninitialized at runtime?

Some languages have built-in affordances for those circumstances. In some statically typed languages, you can say that null and undefined are illegal values, and let your programming language throw a TypeError at compile time, but even in those languages, that can’t prevent null inputs from flowing into the program at runtime.

To get a better handle on this problem, we need to understand where these values can come from. Here are some of the most common sources:

  • User input
  • Database/network records
  • Uninitialized state
  • Functions which could return nothing

User Input

When you’re dealing with user input, validation is the first and best line of defense. I often rely on schema validators to help with that job. For example, check out react-jsonschema-form.

Hydrating Records from Input

I always pass inputs I receive from the network, database, or user input through a hydrating function. For example, I’ll use redux action creators that can handle undefined values to hydrate user records:

const setUser = ({ name = 'Anonymous', avatar = 'anon.png' } = {}) => ({
  type: setUser.type,
  payload: {
    name,
    avatar
  }
});
setUser.type = 'userReducer/setUser';

Sometimes, you’ll need to display different things depending on the current state of the data. If it’s possible to display a page before all of the data is initialized, you may find yourself in that situation. For example, when you’re displaying money balances to a user, you could accidentally display a $0 balance before the data loads. I’ve seen this upset users a number of times. You can create custom data types which generate different outputs based on the current state:


const createBalance = ({
  // default state
  state = 'uninitialized',
  value = createBalance.empty
} = {}) => createBalance.isValidState(state) && ({
  __proto__: {
    uninitialized: () => '--',
    initialized: () => value,
    format () {
      return this[this.getState()](value);
    },
    getState: () => state,
    set: value => {
      const test = Number(value);
      assert(!Number.isNaN(test), `setBalance Invalid value: ${ value }`);
      return createBalance({
        state: 'initialized',
        value
      });
    }
  }
});
createBalance.empty = '0';
createBalance.isValidState = state => {
  if (!['uninitialized', 'initialized'].includes(state)) {
    throw new Error(`createBalance Invalid state: ${ state }`);
  }
  return true;
};
const setBalance = value => createBalance().set(value);
const emptyBalanceForDisplay = createBalance()
  .format();
console.log(emptyBalanceForDisplay); // '--'
const balanceForDisplay = setBalance('25')
  .format(balance);
console.log(balanceForDisplay); // '25'
// Uncomment these calls to see the error cases:
// setBalance('foo'); // Error: setBalance Invalid value: foo
// Error: createBalance Invalid state: THIS IS NOT VALID
// createBalance({ state: 'THIS IS NOT VALID', value: '0' });

The code above is a state machine which makes it impossible to display invalid states. When you first create the balance, it will be set to an uninitialized state. If you try to display a balance while the state is uninitialized, you’ll always get a placeholder value (“--”) instead.

To change that, you have to explicitly set a value by calling the .set method, or the setBalance shortcut we defined below the createBalance factory.

The state itself is encapsulated to protect it from outside interference to make sure that other functions can’t grab it and set it to an invalid state.

Note:* If you’re wondering why we’re using strings instead of numbers for this, it’s because I represent money types with big number strings with lots of decimal precision to avoid rounding errors and accurately represent values for cryptocurrency transactions, which can have arbitrary significant decimal precision.*

If you’re using Redux or Redux architecture, you can declare state machines with Redux-DSM.

Avoid creating null and undefined values

In your own functions, you can avoid creating null or undefined values to begin with. There are a couple ways to do that built into JavaScript that spring to mind. See below.

Avoid null

I never explicitly create null values in JavaScript, because I never really saw the point of having two different primitive values that essentially mean “this value does not exist.”

Since 2015, JavaScript has supported default values that get filled in when you don’t supply a value for the argument or property in question. Those defaults don’t work for null values. That is usually a bug, in my experience. To avoid that trap, don’t use null in JavaScript.

If you want special cases for uninitialized or empty values, state machines are a better bet. See above.

New JavaScript Features

There are a couple of features that can help you deal with null or undefined values. Both are stage 3 proposals at the time of this writing, but if you’re reading from the future, you may be able to use them.

As of this writing, optional chaining is a stage 3 proposal. It works like this:

const foo = {};
// console.log(foo.bar.baz); // throws error
console.log(foo.bar?.baz) // undefined

Nullish Coalescing Operator

Also a stage 3 proposal to be added to the specification, “nullish coalescing operator” is basically a fancy way of saying “fallback value operator”. If the value on the left is undefined or null, it evaluates to the value on the right. It works like this:

let baz;
console.log(baz); // undefined
console.log(baz ?? 'default baz');
// default baz
// Combine with optional chaining:
console.log(foo.bar?.baz ?? 'default baz');
// default baz

If the future hasn’t arrived, yet, you’ll need to install @babel/plugin-proposal-optional-chaining and @babel/plugin-proposal-nullish-coalescing-operator.

Asynchronous Either with Promises

If a function may not return with a value, it might be a good idea to wrap it in an Either. In functional programming, the Either monad is a special abstract data type that allows you to attach two different code paths: a success path, or a fail path. JavaScript has a built-in asynchronous Either monad-ish data type called Promise. You can use it to do declarative error branching for undefined values:

const exists = x => x != null;
const ifExists = value => exists(value) ?
  Promise.resolve(value) :
  Promise.reject(`Invalid value: ${ value }`);
ifExists(null).then(log).catch(log); // Invalid value: null
ifExists('hello').then(log).catch(log); // hello

You could write a synchronous version of that if you want, but I haven’t needed it much. I’ll leave that as an exercise for you. If you have a good grounding in functors and monads, the process will be easier. If that sounds intimidating, don’t worry about it. Just use promises. They’re built-in and they work fine most of the time.

Arrays for Maybes

Arrays implement a map method which takes a function that is applied to each element of the array. If the array is empty, the function will never be called. In other words, Arrays in JavaScript can fill the role of Maybes from languages like Haskell.

What is a Maybe?

A Maybe is a special abstract data type that encapsulates an optional value. The data type takes two forms:

  • Just — A Maybe that contains a value

  • Nothing — a Maybe with no value

Here’s the gist of the idea:

const log = x => console.log(x);
const exists = x => x != null;
const Just = value => ({
  map: f => Just(f(value)),
});
const Nothing = () => ({
  map: () => Nothing(),
});
const Maybe = value => exists(value) ?
  Just(value) :
  Nothing();
const empty = undefined;
Maybe(empty).map(log); // does not log
Maybe('Maybe Foo').map(log); // logs "Maybe Foo"

This is just an example to demonstrate the concept. You could build a whole library of useful functions around maybes, implementing other operations like flatMap and flat (e.g., to avoid Just(Just(value)) when you compose multiple Maybe-returning functions). But JavaScript already has a data type that implements a lot of those features out-of-the-box, so I usually reach for that instead: The Array.

If you want to create a function which may or may not produce a result (particularly if there can be more than one result), you may have a great use-case to return an array.

const log = x => console.log(x);
const exists = x => x != null;
const arr = [1,2,3];
const find = (p, list) => [list.find(p)].filter(exists);
find(x => x > 3, arr).map(log); // does not log anything
find(x => x < 3, arr).map(log); // logs 1

I find the fact that map won’t be called on an empty list very useful for avoiding null and undefined values, but remember, if the array contains null and undefined values, it will call the function with those values, so if the function you’re running could produce null or undefined, you’ll need to filter those out of your returned array, as demonstrated above. That could have the effect of changing the length of the collection.

In Haskell, there’s a function maybe that (like map) applies a function to a value. But the value is optional and encapsulated in a Maybe. We can use JavaScript’s Array data type to do essentially the same thing:


// maybe = b => (a => b) => [a] => b
const maybe = (fallback, f = () => {}) => arr =>
  arr.map(f)[0] || fallback;

// turn a value (or null/undefined) into a maybeArray
const toMaybeArray = value => [value].filter(exists);

// maybe multiply the contents of an array by 2,
// default to 0 if the array is empty
const maybeDouble = maybe(0, x => x * 2);

const emptyArray = toMaybeArray(null);
const maybe2 = toMaybeArray(2);

// logs: "maybeDouble with fallback:  0"
console.log('maybeDouble with fallback: ', maybeDouble(emptyArray));
// logs: "maybeDouble(maybe2):  4"
console.log('maybeDouble(maybe2): ', maybeDouble(maybe2));

maybe takes a fallback value, then a function to map over the maybe array, then a maybe array (an array containing one value, or nothing), and returns either the result of applying the function to the array’s contents, or the fallback value if the array is empty.

For convenience, I’ve also defined a toMaybeArray function, and curried the maybe function to make it most obvious for this demonstration.

If you’d like to do something like this in production code, I’ve created a unit tested open source library to make it easier. It’s called Maybearray. The advantage of Maybearray over other JavaScript Maybe libraries is that it uses native JavaScript arrays to represent values, so you don’t have to give them any special treatment or do anything special to convert back and forth. When you encounter Maybe arrays in your debugging, you don’t have to ask, “what is this weird type?!” It’s just an array of a value or an empty array and you’ve seen them a million times before.

Happy Coding

#javascript

The Non-Value Trio of JavaScript

Undefined, Null, and NaN are 3 keywords, known as non-values or empty values, that are often a source of buggy code, stress, and confusion for many beginning JavaScript engineers. Part of the reason for that is that they are seldom given the proper attention they merit in most courses or books, in my humble opinion. Here, we will attempt to give this trio its proper due and uncover its mysteries.

Undefined

This keyword is both a data type and value in JavaScript. It is one of six primitive data types, the others being: stringnumberbooleannull, and symbol (ES5+). It is assigned, by default, to any variable whose value has not yet been defined. On a deeper level, this means that the variable exists but its value has been given an empty value, called _undefined_. JavaScript is a dynamically typed language, which means that the JS engine determines the type of a variable based on the data type of the value assigned to it. In that context,undefined really means that JavaScript doesn’t know about type of the variable declared because it has yet to be initialized with a value.

Any unassigned variable is automatically given the value and type of undefined

We can illustrate this with the code below.

let myVar;  //declared but left unassigned
console.log(myVar)

Output: undefined

Undefined is also a data type, hence the following:

console.log(typeof myVar)

Output: "undefined"

Notice that there’s a slight difference between the value and the type of undefined; the latter is in quotes. One of the questions that you may find on an interview question is:

What is the value of **typeof typeof undefined**?

The answer is: string

This means that we can type the following:

console.log(typeof myvar + “ variable”)

Output: undefined variable

We can therefore say that in JavaScript, _the data type of the data type of _undefined_ is __string_!

For functions, if the returned value is left unassigned, it returns undefined. More importantly, a function will also return undefined if a value was not returned.

function f(){
   return;
}

console.log(f())

Output: undefined

#keywords #javascript #undefined #nan #null

Javascript array pop: How to Remove Element from Array

Javascript array pop() is an inbuilt method that removes the last item from an array and returns that element. The pop() method changes the length of an array that is why it is not a pure function.

Javascript array pop() method changes the length of the array. If we want to remove the first element of an array, use the  shift() method.

Javascript Array Pop

The pop() method is intentionally generic and can be called or applied to objects resembling arrays.

The objects which do not contain the length property reflecting the last in the series of consecutive may not behave in any meaningful manner.

If the array is empty, then the removed item is undefined.

Let us take a simple example. Create an app.js file.

#javascript #app.js #undefined