Javascript required
Skip to content Skip to sidebar Skip to footer

Cannot Read Property 'get' of Undefined Angular 2

Most of the mod languages similar Ruby, Python, or Java accept a single null value (nil or null), which seems a reasonable approach.

But JavaScript is different.

null, but also undefined, represent in JavaScript empty values. So what'southward the exact difference between them?

The brusk answer is that JavaScript interpreter returns undefined when accessing a variable or object holding that is not nevertheless initialized. For example:

          

javascript

let visitor ;

visitor ; // => undefined

let person = { name: 'John Smith' };

person . age ; // => undefined

On the other side, cypher represents a missing object reference. JavaScript doesn't initialize variables or object properties with null.

Some native methods like Cord.prototype.match() can render zippo to denote a missing object. Take a await at the sample:

          

javascript

allow array = null ;

array ; // => null

let picture = { name: 'Starship Troopers' , musicBy: null };

movie . musicBy ; // => null

'abc' . match ( / [ 0-9 ] / ); // => zero

Because JavaScript is permissive, developers have the temptation to access uninitialized values. I'1000 guilty of such bad practise likewise.

Frequently such risky actions generate undefined related errors:

  • TypeError: 'undefined' is not a role
  • TypeError: Cannot read belongings '<prop-name>' of undefined
  • and alike type errors.

JavaScript developer can understand the irony of this joke:

          

javascript

function undefined () {

// trouble solved

}

To reduce such errors, yous have to understand the cases when undefined is generated. Permit's explore undefined and its effect on code safety.

Table of Contents

  • 1. What is undefined
  • 2. Scenarios that create undefined
    • 2.one Uninitialized variable
    • two.two Accessing a not-existing property
    • 2.iii Function parameters
    • two.4 Function return value
    • 2.5 void operator
  • 3. undefined in arrays
  • 4. Departure between undefined and null
  • 5. Decision

1. What is undefined

JavaScript has 6 primitive types:

  • Boolean: truthful or false
  • Number: ane, 6.7, 0xFF
  • String: "Gorilla and banana"
  • Symbol: Symbol("name") (starting ES2015)
  • Null: null
  • Undefined: undefined.

And a separated object type: {proper noun: "Dmitri"}, ["apple", "orange"].

From 6 archaic types undefined is a special value with its own blazon Undefined. According to ECMAScript specification:

Undefined value primitive value is used when a variable has non been assigned a value.

The standard conspicuously defines that you lot will receive undefined when accessing uninitialized variables, non-existing object properties, non-existing array elements, and alike.

A few examples:

          

javascript

let number ;

number ; // => undefined

allow film = { proper name: 'Interstellar' };

movie . twelvemonth ; // => undefined

let movies = [ 'Interstellar' , 'Alexander' ];

movies [ three ]; // => undefined

The to a higher place instance demonstrates that accessing:

  • an uninitialized variable number
  • a non-existing object property moving picture.year
  • or a non-existing array element movies[iii]

are evaluated to undefined.

The ECMAScript specification defines the blazon of undefined value:

Undefined type is a blazon whose sole value is the undefined value.

In this sense, typeof operator returns 'undefined' string for an undefined value:

          

javascript

typeof undefined === 'undefined' ; // => true

Of course typeof works nicely to verify whether a variable contains an undefined value:

          

javascript

let zilch ;

typeof cypher === 'undefined' ; // => true

two. Scenarios that create undefined

2.i Uninitialized variable

A declared variable but not nonetheless assigned with a value (uninitialized) is by default undefined.

Plain and uncomplicated:

          

javascript

permit myVariable ;

myVariable ; // => undefined

myVariable is declared and not yet assigned with a value. Accessing the variable evaluates to undefined.

An efficient approach to solve the troubles of uninitialized variables is whenever possible assign an initial value. The less the variable exists in an uninitialized state, the ameliorate.

Ideally, you would assign a value right away after declaration const myVariable = 'Initial value'. Merely that's not ever possible.

Tip one: Favor const, otherwise use let, but say goodbye to var

In my opinion, one of the all-time features of ECMAScript 2015 is the new style to declare variables using const and let. It is a big step forward.

const and let are cake scoped (reverse to older function scoped var) and exist in a temporal dead zone until the declaration line.

I recommend const variable when its value is not going to change. Information technology creates an immutable binding.

One of the overnice features of const is that you must assign an initial value to the variable const myVariable = 'initial'. The variable is not exposed to the uninitialized country and accessing undefined is impossible.

Allow's check the function that verifies whether a word is a palindrome:

          

javascript

part isPalindrome ( discussion ) {

const length = discussion . length ;

const half = Math . flooring ( length / ii );

for ( let index = 0 ; index < one-half ; index ++) {

if ( word [ index ] !== word [ length - index - 1 ]) {

return false ;

}

}

return true ;

}

isPalindrome ( 'madam' ); // => true

isPalindrome ( 'hello' ); // => false

length and half variables are assigned with a value one time. It seems reasonable to declare them equally const since these variables aren't going to change.

Apply allow annunciation for variables whose value can change. Whenever possible assign an initial value right abroad, eastward.g. permit index = 0.

What about the erstwhile school var? My suggestion is to stop using it.

Do not write var, write const and let in JavaScript

var declaration problem is the variable hoisting within the part telescopic. You tin can declare a var variable somewhere at the stop of the part scope, but still, you can access it before annunciation: and y'all'll go an undefined.

          

javascript

function bigFunction () {

// code...

myVariable ; // => undefined

// code...

var myVariable = 'Initial value' ;

// code...

myVariable ; // => 'Initial value'

}

bigFunction ();

myVariable is accessible and contains undefined even before the proclamation line: var myVariable = 'Initial value'.

Contrary, a const or let variable cannot be accessed earlier the annunciation line — the variable is in a temporal dead zone before the annunciation. And that's nice because you take less run a risk to access an undefined.

The to a higher place instance updated with allow (instead of var) throws a ReferenceError because the variable in the temporal dead zone is not accessible.

          

javascript

function bigFunction () {

// code...

myVariable ; // => Throws 'ReferenceError: myVariable is not defined'

// code...

permit myVariable = 'Initial value' ;

// lawmaking...

myVariable ; // => 'Initial value'

}

bigFunction ();

Encouraging the usage of const for immutable bindings or allow otherwise ensures a exercise that reduces the advent of the uninitialized variable.

Tip 2: Increase cohesion

Cohesion characterizes the degree to which the elements of a module (namespace, class, method, block of code) vest together. The cohesion can exist high or low.

A high cohesion module is preferable because the elements of such a module focus solely on a single chore. It makes the module:

  • Focused and understandable: easier to empathize what the module does
  • Maintainable and easier to refactor: the change in the module affects fewer modules
  • Reusable: being focused on a single task, it makes the module easier to reuse
  • Testable: you would easier test a module that's focused on a unmarried task

Components coupling and cohesion

High cohesion accompanied past loose coupling is the characteristic of a well-designed system.

A code block can be considered a pocket-size module. To profit from the benefits of loftier cohesion, keep the variables as shut as possible to the code block that uses them.

For example, if a variable solely exists to form the logic of cake scope, so declare and brand the variable alive only within that cake (using const or let declarations). Practice not expose this variable to the outer block scope, since the outer block shouldn't care about this variable.

I classic instance of the unnecessarily extended life of variables is the usage of for bike within a role:

          

javascript

role someFunc ( array ) {

var index , particular , length = array . length ;

// some code...

// some lawmaking...

for ( index = 0 ; alphabetize < length ; index ++) {

item = assortment [ index ];

// some lawmaking...

}

render 'some outcome' ;

}

index, item and length variables are declared at the first of the function body. However, they are used but near the finish. What's the problem with this approach?

Between the announcement at the top and the usage in for argument the variables alphabetize, particular are uninitialized and exposed to undefined. They accept an unreasonably long lifecycle in the unabridged function scope.

A better approach is to move these variables as close as possible to their usage place:

          

javascript

function someFunc ( assortment ) {

// some code...

// some code...

const length = array . length ;

for ( let index = 0 ; index < length ; alphabetize ++) {

const item = array [ index ];

// some

}

return 'some result' ;

}

index and item variables exist only in the block scope of for statement. They don't have whatsoever meaning outside of for.
length variable is declared shut to the source of its usage too.

Why is the modified version better than the initial i? Permit'southward encounter:

  • The variables are not exposed to uninitialized state, thus you accept no risk of accessing undefined
  • Moving the variables as close as possible to their usage identify increases the code readability
  • Loftier cohesive chunks of code are easier to refactor and extract into separate functions, if necessary

2.two Accessing a non-existing property

When accessing a non-existing object property, JavaScript returns undefined.

Let'south demonstrate that in an example:

          

javascript

permit favoriteMovie = {

championship: 'Blade Runner'

};

favoriteMovie . actors ; // => undefined

favoriteMovie is an object with a unmarried belongings title. Accessing a non-existing holding actors using a property accessor favoriteMovie.actors evaluates to undefined.

Accessing a not-existing holding does not throw an error. The problem appears when trying to get data from the non-existing property, which is the most mutual undefined trap, reflected in the well-known mistake bulletin TypeError: Cannot read property <prop> of undefined.

Let's slightly alter the previous code snippet to illustrate a TypeError throw:

          

javascript

let favoriteMovie = {

title: 'Bract Runner'

};

favoriteMovie . actors [ 0 ];

// TypeError: Cannot read property '0' of undefined

favoriteMovie does not take the property actors, so favoriteMovie.actors evaluates to undefined.

Equally a result, accessing the first item of an undefined value using the expression favoriteMovie.actors[0] throws a TypeError.

The permissive nature of JavaScript that allows accessing non-existing properties is a source of nondeterminism: the property may be set or not. The good manner to bypass this problem is to restrict the object to have always defined the properties that it holds.

Unfortunately, often you lot don't have command over the objects. Such objects may accept a different fix of properties in diverse scenarios. So y'all take to handle all these scenarios manually.

Let'south implement a office suspend(array, toAppend) that adds at the beginning and/or at the cease of an array of new elements. toAppend parameter accepts an object with properties:

  • first: element inserted at the beginning of assortment
  • last: element inserted at the finish of array.

The office returns a new array instance, without altering the original array.

The first version of append(), a scrap naive, may look similar this:

          

javascript

function suspend ( assortment , toAppend ) {

const arrayCopy = [... array ];

if ( toAppend . offset ) {

arrayCopy . unshift ( toAppend . first );

}

if ( toAppend . concluding ) {

arrayCopy . push ( toAppend . concluding );

}

return arrayCopy ;

}

append ([ 2 , 3 , four ], { showtime: 1 , last: 5 }); // => [1, ii, three, 4, v]

suspend ([ 'Hullo' ], { last: 'World' }); // => ['Howdy', 'World']

suspend ([ 8 , 16 ], { first: 4 }); // => [four, 8, 16]

Considering toAppend object can omit starting time or final properties, information technology is obligatory to verify whether these properties exist in toAppend.

A holding accessor evaluates to undefined if the belongings does not be. The outset temptation to check whether get-go or last backdrop are present is to verify them against undefined. This is performed in conditionals if(toAppend.start){} and if(toAppend.concluding){}...

Not so fast. This arroyo has a drawback. undefined, as well as false, zip, 0, NaN and '' are falsy values.

In the current implementation of append(), the office doesn't allow to insert falsy elements:

          

javascript

suspend ([ x ], { starting time: 0 , last: fake }); // => [10]

0 and false are falsy. Considering if(toAppend.kickoff){} and if(toAppend.last){} actually compare confronting falsy, these elements are non inserted into the array. The role returns the initial array [10] without modifications, instead of the expected [0, 10, false].

The tips that follow explicate how to correctly check the property'south beingness.

Tip 3: Check the property existence

Fortunately, JavaScript offers a bunch of ways to determine if the object has a specific holding:

  • obj.prop !== undefined: compare against undefined directly
  • typeof obj.prop !== 'undefined': verify the property value type
  • obj.hasOwnProperty('prop'): verify whether the object has an own property
  • 'prop' in obj: verify whether the object has an ain or inherited property

My recommendation is to use in operator. It has a curt and sweet syntax. in operator presence suggests a articulate intent of checking whether an object has a specific property, without accessing the actual belongings value.

Do not write var, write const and let in JavaScript

obj.hasOwnProperty('prop') is a dainty solution also. It's slightly longer than in operator and verifies only in the object's own properties.

Let's improve append(array, toAppend) function using in operator:

          

javascript

office append ( array , toAppend ) {

const arrayCopy = array . slice ();

if ( 'kickoff' in toAppend ) {

arrayCopy . unshift ( toAppend . first );

}

if ( 'terminal' in toAppend ) {

arrayCopy . push button ( toAppend . final );

}

return arrayCopy ;

}

append ([ ii , 3 , iv ], { showtime: 1 , last: v }); // => [i, ii, 3, 4, 5]

append ([ 10 ], { first: 0 , last: false }); // => [0, x, simulated]

'first' in toAppend (and 'last' in toAppend) is true whether the corresponding belongings exists, faux otherwise.

in operator fixes the problem with inserting falsy elements 0 and false. Now, adding these elements at the offset and the end of [10] produces the expected result [0, 10, imitation].

Tip iv: Destructuring to access object properties

When accessing an object property, sometimes information technology's necessary to set a default value if the property does not exist.

You might use in accompanied with ternary operator to accomplish that:

          

javascript

const object = { };

const prop = 'prop' in object ? object . prop : 'default' ;

prop ; // => 'default'

Ternary operator syntax becomes daunting when the number of backdrop to check increases. For each holding, you lot have to create a new line of code to handle the defaults, increasing an ugly wall of similar-looking ternary operators.

To use a more than elegant approach, allow's get familiar with a great ES2015 feature called object destructuring.

Object destructuring allows inline extraction of object property values straight into variables and setting a default value if the property does not exist. A convenient syntax to avoid dealing directly with undefined.

Indeed, the property extraction is now precise:

          

javascript

const object = { };

const { prop = 'default' } = object ;

prop ; // => 'default'

To run into things in activity, let's define a useful function that wraps a string in quotes.

quote(subject field, config) accepts the kickoff argument equally the string to be wrapped. The second argument config is an object with the properties:

  • char: the quote char, e.one thousand. ' (unmarried quote) or " (double quote). Defaults to ".
  • skipIfQuoted: the boolean value to skip quoting if the cord is already quoted. Defaults to true.

Applying the benefits of the object destructuring, permit's implement quote():

          

javascript

function quote ( str , config ) {

const { char = '"' , skipIfQuoted = true } = config ;

const length = str . length ;

if ( skipIfQuoted

&& str [ 0 ] === char

&& str [ length - 1 ] === char ) {

render str ;

}

render char + str + char ;

}

quote ( 'Hello Globe' , { char: '*' }); // => '*Hello Earth*'

quote ( '"Welcome"' , { skipIfQuoted: truthful }); // => '"Welcome"'

const { char = '"', skipIfQuoted = true } = config destructuring consignment in one line extracts the properties char and skipIfQuoted from config object.
If some properties are missing in the config object, the destructuring assignment sets the default values: '"' for char and false for skipIfQuoted.

Fortunately, the function still has room for comeback.

Let'due south motion the destructuring assignment into the parameters section. And ready a default value (an empty object { }) for the config parameter, to skip the second statement when default settings are enough.

          

javascript

function quote ( str , { char = '"' , skipIfQuoted = true } = {}) {

const length = str . length ;

if ( skipIfQuoted

&& str [ 0 ] === char

&& str [ length - 1 ] === char ) {

return str ;

}

return char + str + char ;

}

quote ( 'Hello World' , { char: '*' }); // => '*Hello World*'

quote ( 'Sunny day' ); // => '"Sunny day"'

The destructuring assignment replaces the config parameter in the function'south signature. I like that: quote() becomes one line shorter.

= {} on the correct side of the destructuring assignment ensures that an empty object is used if the 2nd argument is not specified at all quote('Sunny twenty-four hour period').

Object destructuring is a powerful characteristic that handles efficiently the extraction of backdrop from objects. I similar the possibility to specify a default value to be returned when the accessed property doesn't be. As a effect, you avoid undefined and the hassle around it.

Tip 5: Fill the object with default properties

If there is no need to create variables for every property, as the destructuring assignment does, the object that misses some properties tin can exist filled with default values.

The ES2015 Object.assign(target, source1, source2, ...) copies the values of all enumerable own properties from one or more source objects into the target object. The function returns the target object.

For instance, you demand to access the properties of unsafeOptions object that doesn't ever incorporate its full gear up of properties.

To avert undefined when accessing a not-existing belongings from unsafeOptions, let'due south make some adjustments:

  • Define an object defaults that holds the default property values
  • Call Object.assign({ }, defaults, unsafeOptions) to build a new object options. The new object receives all properties from unsafeOptions, but the missing ones are taken from defaults.
          

javascript

const unsafeOptions = {

fontSize: 18

};

const defaults = {

fontSize: xvi ,

color: 'blackness'

};

const options = Object . assign ({}, defaults , unsafeOptions );

options . fontSize ; // => xviii

options . color ; // => 'black'

unsafeOptions contains only fontSize property. defaults object defines the default values for backdrop fontSize and color.

Object.assign() takes the first statement every bit a target object {}. The target object receives the value of fontSize property from unsafeOptions source object. And the value of color property from defaults source object, considering unsafeOptions doesn't contain color.

The order in which the source objects are enumerated does matter: afterwards source object properties overwrite before ones.

Yous are now prophylactic to access any property of options object, including options.colour that wasn't available in unsafeOptions initially.

Fortunately, an easier alternative to fill the object with default backdrop exists. I recommend to utilize the spread backdrop in object initializers.

Instead of Object.assign() invocation, use the object spread syntax to copy into target object all ain and enumerable properties from source objects:

          

javascript

const unsafeOptions = {

fontSize: 18

};

const defaults = {

fontSize: 16 ,

color: 'blackness'

};

const options = {

... defaults ,

... unsafeOptions

};

options . fontSize ; // => xviii

options . colour ; // => 'blackness'

The object initializer spreads properties from defaults and unsafeOptions source objects. The order in which the source objects are specified is important: later source object backdrop overwrite earlier ones.

Filling an incomplete object with default property values is an efficient strategy to brand your code safety and durable. No affair the situation, the object always contains the full set of properties: and undefined cannot exist generated.

Bonus tip: nullish coalescing

The operator nullish coalescing evaluates to a default value when its operand is undefined or nada:

          

javascript

const value = nullOrUndefinedValue ?? defaultValue ;

Nullish coalescing operator is convenient to admission an object holding while having a default value when this belongings is undefined or zero:

          

javascript

const styles = {

fontSize: xviii

};

styles . color ?? 'black' ; // => 'black'

styles . fontSize ?? 16 ; // => eighteen

styles object doesn't take the belongings color, thus styles.color property accessor is undefined. styles.color ?? 'black' evaluates to the default value 'black'.

styles.fontSize is 18, so the nullish coalescing operator evaluates to the belongings value xviii.

2.iii Function parameters

The function parameters implicitly default to undefined.

Ordinarily a function defined with a specific number of parameters should be invoked with the aforementioned number of arguments. That'due south when the parameters get the values you await:

          

javascript

function multiply ( a , b ) {

a ; // => 5

b ; // => iii

return a * b ;

}

multiply ( 5 , 3 ); // => 15

When multiply(5, 3), the parameters a and b receive 5 and respectively iii values. The multiplication is calculated as expected: 5 * 3 = fifteen.

What does happen when you omit an argument on invocation? The corresponding parameter inside the function becomes undefined.

Permit'southward slightly modify the previous example past calling the function with just one argument:

          

javascript

function multiply ( a , b ) {

a ; // => 5

b ; // => undefined

return a * b ;

}

multiply ( five ); // => NaN

The invocation multiply(5) is performed with a single argument: every bit event a parameter is 5, only the b parameter is undefined.

Tip vi: Use default parameter value

Sometimes a office does not require the full set of arguments on invocation. You can set defaults for parameters that don't have a value.

Recalling the previous example, let'southward brand an comeback. If b parameter is undefined, let default it to ii:

          

javascript

function multiply ( a , b ) {

if ( b === undefined ) {

b = two ;

}

a ; // => 5

b ; // => 2

render a * b ;

}

multiply ( 5 ); // => 10

The function is invoked with a single argument multiply(5). Initially, a parameter is two and b is undefined.
The conditional argument verifies whether b is undefined. If it happens, b = 2 assignment sets a default value.

While the provided way to assign default values works, I don't recommend comparing directly against undefined. It's verbose and looks similar a hack.

A better approach is to use the ES2015 default parameters feature. It's short, expressive and no direct comparisons with undefined.

Adding a default value to parameter b = 2 looks amend:

          

javascript

function multiply ( a , b = 2 ) {

a ; // => five

b ; // => 2

render a * b ;

}

multiply ( five ); // => 10

multiply ( 5 , undefined ); // => 10

b = 2 in the function signature makes sure that if b is undefined, the parameter defaults to 2.

ES2015 default parameters feature is intuitive and expressive. E'er use information technology to set up default values for optional parameters.

two.four Office return value

Implicitly, without render statement, a JavaScript function returns undefined.

A function that doesn't take return statement implicitly returns undefined:

          

javascript

function square ( 10 ) {

const res = x * x ;

}

foursquare ( two ); // => undefined

square() office does not render whatsoever ciphering results. The function invocation result is undefined.

The aforementioned situation happens when render statement is present, just without an expression nearby:

          

javascript

function foursquare ( x ) {

const res = 10 * x ;

render ;

}

foursquare ( 2 ); // => undefined

return; argument is executed, but it doesn't return whatsoever expression. The invocation result is too undefined.

Of course, indicating nearly render the expression to be returned works as expected:

          

javascript

function square ( ten ) {

const res = x * x ;

render res ;

}

square ( 2 ); // => iv

Now the function invocation is evaluated to 4, which is 2 squared.

Tip 7: Don't trust the automated semicolon insertion

The following list of statements in JavaScript must end with semicolons (;):

  • empty statement
  • let, const, var, import, export declarations
  • expression argument
  • debugger statement
  • keep statement, break statement
  • throw statement
  • return statement

If y'all employ 1 of the to a higher place statements, exist sure to betoken a semicolon at the cease:

          

javascript

office getNum () {

// Discover the semicolons at the end

let num = 1 ;

return num ;

}

getNum (); // => ane

At the stop of both let declaration and render statement an obligatory semicolon is written.

What happens when you don't desire to indicate these semicolons? In such a state of affairs ECMAScript provides an Automatic Semicolon Insertion (ASI) mechanism, which inserts for you the missing semicolons.

Helped past ASI, y'all can remove the semicolons from the previous example:

          

javascript

office getNum () {

// Notice that semicolons are missing

let num = 1

return num

}

getNum () // => i

The above text is a valid JavaScript code. The missing semicolons are automatically inserted for y'all.

At first sight, it looks pretty promising. ASI mechanism lets you skip the unnecessary semicolons. Y'all can make the JavaScript lawmaking smaller and easier to read.

In that location is one small, simply annoying trap created by ASI. When a newline stands betwixt return and the returned expression return \n expression, ASI automatically inserts a semicolon before the newline return; \northward expression.

What information technology does hateful inside a office to have return; statement? The function returns undefined. If you don't know in detail the mechanism of ASI, the unexpectedly returned undefined is misleading.

For instance, let'south written report the returned value of getPrimeNumbers() invocation:

          

javascript

office getPrimeNumbers () {

return

[ ii , iii , 5 , 7 , eleven , 13 , 17 ]

}

getPrimeNumbers () // => undefined

Between return statement and the array literal expression exists a new line. JavaScript automatically inserts a semicolon after return, interpreting the code as follows:

          

javascript

function getPrimeNumbers () {

return ;

[ 2 , three , v , 7 , 11 , 13 , 17 ];

}

getPrimeNumbers (); // => undefined

The statement return; makes the function getPrimeNumbers() to return undefined instead of the expected array.

The problem is solved by removing the newline between render and array literal:

          

javascript

function getPrimeNumbers () {

return [

2 , three , 5 , 7 , 11 , 13 , 17

];

}

getPrimeNumbers (); // => [2, three, five, vii, eleven, 13, 17]

My recommendation is to report how exactly Automatic Semicolon Insertion works to avoid such situations.

Of course, never put a newline between return and the returned expression.

2.5 void operator

void <expression> evaluates the expression and returns undefined no thing the outcome of the evaluation.

          

javascript

void 1 ; // => undefined

void ( false ); // => undefined

void {name: 'John Smith' }; // => undefined

void Math . min ( 1 , 3 ); // => undefined

Ane use case of void operator is to suppress expression evaluation to undefined, relying on some side-effect of the evaluation.

three. undefined in arrays

You become undefined when accessing an array element with an out of bounds alphabetize.

          

javascript

const colors = [ 'blue' , 'white' , 'red' ];

colors [ v ]; // => undefined

colors [- one ]; // => undefined

colors array has 3 elements, thus valid indexes are 0, ane, and ii.

Because there are no assortment elements at indexes 5 and -1, the accessors colors[5] and colors[-1] are undefined.

In JavaScript, you might encounter and so-called sparse arrays. Theses are arrays that accept gaps, i.e. at some indexes, no elements are defined.

When a gap (aka empty slot) is accessed inside a sparse array, you also get an undefined.

The following example generates sparse arrays and tries to access their empty slots:

          

javascript

const sparse1 = new Array ( 3 );

sparse1 ; // => [<empty slot>, <empty slot>, <empty slot>]

sparse1 [ 0 ]; // => undefined

sparse1 [ 1 ]; // => undefined

const sparse2 = [ 'white' , , 'blue' ]

sparse2 ; // => ['white', <empty slot>, 'bluish']

sparse2 [ i ]; // => undefined

sparse1 is created by invoking an Array constructor with a numeric start statement. Information technology has 3 empty slots.

sparse2 is created with an array literal with the missing second element.

In whatever of these sparse arrays accessing an empty slot evaluates to undefined.

When working with arrays, to avert undefined, be certain to apply valid array indexes and forbid the creation of sparse arrays.

4. Divergence between undefined and zip

What is the master difference between undefined and aught? Both special values imply an empty state.

undefined represents the value of a variable that hasn't been nonetheless initialized, while aught represents an intentional absence of an object.

Let's explore the divergence in some examples.

The variable number is defined, however, is not assigned with an initial value:

          

javascript

allow number ;

number ; // => undefined

number variable is undefined, which indicates an uninitialized variable.

The same uninitialized concept happens when a not-existing object property is accessed:

          

javascript

const obj = { firstName: 'Dmitri' };

obj . lastName ; // => undefined

Because lastName property does not be in obj, JavaScript evaluates obj.lastName to undefined.

On the other side, you know that a variable expects an object. But for some reason, y'all tin't instantiate the object. In such case null is a meaningful indicator of a missing object.

For example, clone() is a office that clones a plain JavaScript object. The office is expected to return an object:

          

javascript

function clone ( obj ) {

if ( typeof obj === 'object' && obj !== null ) {

return Object . assign ({}, obj );

}

render null ;

}

clone ({ name: 'John' }); // => {name: 'John'}

clone ( 15 ); // => null

clone ( cipher ); // => null

However clone() might be invoked with a non-object argument: 15 or null. In such a example, the function cannot create a clone, so information technology returns null — the indicator of a missing object.

typeof operator makes the distinction between undefined and null:

          

javascript

typeof undefined ; // => 'undefined'

typeof cipher ; // => 'object'

As well the strict quality operator === correctly differentiates undefined from naught:

          

javascript

let nothing = undefined ;

permit missingObject = zippo ;

nothing === missingObject ; // => false

five. Conclusion

undefined being is a consequence of JavaScript's permissive nature that allows the usage of:

  • uninitialized variables
  • non-existing object properties or methods
  • out of bounds indexes to admission array elements
  • the invocation effect of a function that returns nil

Comparing directly against undefined is unsafe because you rely on a permitted but discouraged do mentioned higher up.

An efficient strategy is to reduce at minimum the appearance of undefined keyword in your lawmaking past applying practiced habits such as:

  • reduce the usage of uninitialized variables
  • make the variables lifecycle short and close to the source of their usage
  • whenever possible assign initial values to variables
  • favor const, otherwise apply permit
  • employ default values for insignificant office parameters
  • verify the properties existence or fill up the unsafe objects with default properties
  • avoid the usage of sparse arrays

Is it good that JavaScript has both undefined and nada to stand for empty values?

knibbsdoevall.blogspot.com

Source: https://dmitripavlutin.com/7-tips-to-handle-undefined-in-javascript/