Discovering JavaScript: lets, vars and ifs
Tags: javascript, journey, path
Published: 2017-08-18 01:21:33

---
title: "Discovering JavaScript: lets, vars and ifs"
published: true
description: Little things in JavaScript you probably already know.
tags: javascript, journey, path
---
Learning is beautiful, the process is even more fascinating. How we transcend being ignorant about a subject to gaining varying levels of proficiency is simply mind-blowing. I've been programming professionally for a relatively short period but I thought it'd be nice to document some things I find interesting as I go through the learning process. I'm excited to share my first entry in what would hopefully be a series with you.

##let & var
>The major difference between `let` and `var` is the scope of both keywords -- `let` is block scoped while `var` is function scoped.
>[-source](https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var-to-declare-a-variable)

You see, I've been aware of this rule but it didn't really mean much till recently when I _personally_ experienced this behavior while working on a project feature.

This code snippet demonstrates the behavior and is somewhat similar to what I was working on when I hit my light-bulb moment regarding what distinguishes `let` from `var`.

```javascript
function checkProperty(userObject){
	if(userObject.hasOwnProperty('name') && userObject.hasOwnProperty('age')) {
		let name = userObject.name;
		let age = userObject.age;
    }
    //proceed to work with variables, in our case we log it to the console
	console.log('Name:', name);
    console.log('Age:', age);
}

let user = {name: 'Dev', age: 10};

checkProperty(user); //execute function: should throw Reference Error

```
Running this snippet should throw a `ReferenceError` that says `name is not defined`. This is because the `let` keyword is bound to the code block in which it is declared. In this case, variables declared with `let` are bound to our `if` block and are therefore inaccessible outside it. This quote from [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var) best explains the behavior of the `var` keyword;

>"The scope of a variable declared with var is its current execution context, which is either the enclosing function or, for variables declared outside any function, global."

The next thing I did, albeit intuitively after verifying that this wasn't a typo was to change `let` to `var` and voila, it worked as it should. This was when the "scoping" of both keywords made sense to me.

After identifying and understanding this behavior, I adapted my code and declared my variables in the `checkProperty` function scope and that fixed the error. The updated code looks like the following;

```javascript
function checkProperty(userObject){
	let name, age;
	if(userObject.hasOwnProperty('name') && userObject.hasOwnProperty('age')) {
		name = userObject.name;
		age = userObject.age;
    }
    //proceed to work with variables, in our case we log it to the console
	console.log('Name:', name);
    console.log('Age:', age);
}

let user = {name: 'Dev', age: 10};

checkProperty(user); //execute function: Logs "Name: Dev \n Age: 10" to console

```


##if
I needed to make sure certain properties of an object were set before using them and I didn't want to write `if` conditions that would stretch so far that one would have to scroll horizontally, that is just not pretty. So I set out to experiment with `if` till I found something that works and is pretty.ðŸ˜Š

I had something like this in my first iteration*ðŸ’€ :face palm:

```javascript
function checkProperty(user){
	
	if(user.name !== 'undefined' && user.age !== 'undefined' && user.email !== 'undefined' && user.level !== 'undefined') {
		
    }
}
```

That was painful to see, I know :(. There had to be another way and I indeed found something!

```javascript
function checkProperty(user){
	if((user.name && user.age && user.email && user.level) !== (undefined || null)) {
		console.log('It passed.')	
    }
}
```
The caveat of using this approach is that it passes for properties that don't exist on the object. This means one would have to ensure the properties exist using the `hasOwnProperty' function before proceeding to use this. Oh, welp! :(

For robust object schema validation though, you should probably look into [joi](https://github.com/hapijs/joi).

Comments and corrections are welcomed. Thanks for reading!