What is JavaScript?
JavaScript is a very powerful client-side scripting language. JavaScript is used mainly for enhancing the interaction of a user with the webpage. In other words, you can make your webpage more lively and interactive, with the help of JavaScript. JavaScript is also being used widely in game development and Mobile application development.
let x;
x = 1; // x is a number
x = '1'; // x is a string
x = [1]; // x is an array
Seemingly different values equate to true
when compared with ==
(loose or abstract equality) because JavaScript (effectively) converts each to a string representation before comparison:
// all true
1 == '1';
1 == [1];
'1' == [1];
A more obvious false
result occurs when comparing with ===
(strict equality) because the type is considered:
// all false
1 === '1';
1 === [1];
'1' === [1];
Internally, JavaScript sets a value to one of six primitive data types:
- Undefined (a variable with no defined value)
- Null (a single null value)
- Boolean (true or false)
- Number (this includes
Infinity
andNaN
– not a number!) - String (textual data)
- Symbol (a unique and immutable primitive new to ES6/2015)
Everything else is an Object — including arrays.
Truthy and Falsy
As well as a type, each value also has an inherent boolean value, generally known as either truthy or falsy. Some of the rules are a little bizarre so understanding the concepts and effect on comparison helps when debugging JavaScript applications.
The following values are always falsy:
false
-
0
(zero) -
''
or""
(empty string) null
undefined
NaN
Everything else is truthy. That includes:
-
'0'
(a string containing a single zero) -
'false'
(a string containing the text “false”) -
[]
(an empty array) -
{}
(an empty object) -
function(){}
(an “empty” function)
A single value can therefore be used within conditions, e.g.
if (value) {
// value is truthy
}
else {
// value is falsy
// it could be false, 0, '', null, undefined or NaN
}
Loose Equality Comparisons With ==
The rules:
-
false
, zero and empty strings are all equivalent. -
null
andundefined
are equivalent to themselves and each other but nothing else. -
NaN
is not equivalent to anything – including anotherNaN
! -
Infinity
is truthy – but cannot be compared totrue
orfalse
! - An empty array is truthy – yet comparing with
true
isfalse
and comparing with false is true?!
Example:
// all true
false == 0;
0 == '';
null == undefined;
[] == false;
!![0] == true;
// all false
false == null;
NaN == NaN;
Infinity == true;
[] == true;
[0] == true;
Strict Equality Comparisons With ===
The situation is clearer when using a strict comparison because the value types must match:
The only exception is NaN
which remains stubbornly inequivalent to everything.
Recommendations
Truthy and falsy values can catch out the most experienced developers. Those new to programming or migrating from other languages have no chance! Fortunately, there are simple steps to catch the most difficult-to-spot errors when handling truthy and falsy variables:
1. Avoid direct comparisons
It’s rarely necessary to compare two truthy and falsy values when a single value will always equate to true or false:
// instead of
if (x == false) // ...
// runs if x is false, 0, '', or []
// use
if (!x) // ...
// runs if x is false, 0, '', NaN, null or undefined
2. Use ===
strict equality
Use a ===
strict equality (or !==
strict inequality) comparisons to compare values and avoid type conversion issues:
// instead of
if (x == y) // ...
// runs if x and y are both truthy or both falsy
// e.g. x = null and y = undefined
// use
if (x === y) // ...
// runs if x and y are identical...
// except when both are NaN
What is Scope?
Scope determines the visibility or accessibility of a variable or other resource in the area of your code.
Global Scope
There's only one Global scope in the JavaScript document. The area outside all the functions is consider the global scope and the variables defined inside the global scope can be accessed and altered in any other scopes.
//global scope
var fruit = 'apple'
console.log(fruit); //apple
function getFruit(){
console.log(fruit); //fruit is accessible here
}
getFruit(); //apple
Local Scope
Variables declared inside the functions become Local
to the function and are considered in the corresponding local scope. Every Functions has its own scope. Same variable can be used in different functions because they are bound to the respective functions and are not mutual visible.
//global scope
function foo1(){
//local scope 1
function foo2(){
//local scope 2
}
}
//global scope
function foo3(){
//local scope 3
}
//global scope
Local scope can be divided into function scope and block scope. The concept of block scope is introduced in ECMA script 6 (ES6) together with the new ways to declare variables -- const and let.
Function Scope
Whenever you declare a variable in a function, the variable is visible only within the function. You can't access it outside the function. var is the keyword to define variable for a function-scope accessibility.
function foo(){
var fruit ='apple';
console.log('inside function: ',fruit);
}
foo(); //inside function: apple
console.log(fruit); //error: fruit is not defined
Block Scope
A block scope is the area within if, switch conditions or for and while loops. Generally speaking, whenever you see {curly brackets}, it is a block. In ES6, const and let keywords allow developers to declare variables in the block scope, which means those variables exist only within the corresponding block.
function foo(){
if(true){
var fruit1 = 'apple'; //exist in function scope
const fruit2 = 'banana'; //exist in block scope
let fruit3 = 'strawberry'; //exist in block scope
}
console.log(fruit1);
console.log(fruit2);
console.log(fruit3);
}
foo();
//result:
//apple
//error: fruit2 is not defined
//error: fruit3 is not defined
Lexical Scope
Another point to mention is the lexical scope. Lexical scope means the children scope have the access to the variables defined in the parent scope. The children functions are lexically bound to the execution context of their parents.
function foo1(){
var fruit1 = 'apple';
const fruit2 = 'banana';
let fruit3 = 'strawberry';
function foo2(){
console.log(fruit1);
console.log(fruit2);
console.log(fruit3);
}
foo2();
}
foo1();
//result:
//apple
//banana
//strawberry
Top comments (0)