Cannot Read Property 'msie' of Undefined With Aggregated Js
Nearly of the modern languages like Ruby, Python, or Coffee have a unmarried null value (nothing
or nothing
), which seems a reasonable approach.
Only JavaScript is different.
null
, merely besides undefined
, represent in JavaScript empty values. So what's the exact difference betwixt them?
The short answer is that JavaScript interpreter returns undefined
when accessing a variable or object belongings that is non yet initialized. For example:
javascript
let company ;
company ; // => undefined
let person = { name: 'John Smith' };
person . age ; // => undefined
On the other side, null
represents a missing object reference. JavaScript doesn't initialize variables or object properties with null
.
Some native methods similar String.prototype.lucifer()
tin can render null
to denote a missing object. Take a look at the sample:
javascript
let array = null ;
assortment ; // => null
let motion-picture show = { proper name: 'Starship Troopers' , musicBy: null };
movie . musicBy ; // => cipher
'abc' . match ( / [ 0-9 ] / ); // => goose egg
Because JavaScript is permissive, developers have the temptation to access uninitialized values. I'm guilty of such bad do too.
Often such risky actions generate undefined
related errors:
-
TypeError: 'undefined' is not a function
-
TypeError: Cannot read property '<prop-proper name>' of undefined
- and akin type errors.
JavaScript developer tin can understand the irony of this joke:
javascript
role undefined () {
// problem solved
}
To reduce such errors, you take to understand the cases when undefined
is generated. Allow'southward explore undefined
and its event on lawmaking rubber.
Table of Contents
- 1. What is undefined
- 2. Scenarios that create undefined
- 2.i Uninitialized variable
- 2.ii Accessing a non-existing property
- two.3 Function parameters
- 2.4 Office return value
- 2.5 void operator
- 3. undefined in arrays
- 4. Difference between undefined and goose egg
- five. Conclusion
1. What is undefined
JavaScript has 6 primitive types:
- Boolean:
true
orfalse
- Number:
1
,6.7
,0xFF
- String:
"Gorilla and assistant"
- Symbol:
Symbol("proper name")
(starting ES2015) - Null:
null
- Undefined:
undefined
.
And a separated object type: {name: "Dmitri"}
, ["apple", "orangish"]
.
From 6 primitive types undefined
is a special value with its own type Undefined. According to ECMAScript specification:
Undefined value primitive value is used when a variable has not been assigned a value.
The standard clearly defines that yous volition receive undefined
when accessing uninitialized variables, non-existing object properties, non-existing array elements, and alike.
A few examples:
javascript
let number ;
number ; // => undefined
let movie = { proper noun: 'Interstellar' };
motion-picture show . year ; // => undefined
allow movies = [ 'Interstellar' , 'Alexander' ];
movies [ iii ]; // => undefined
The above example demonstrates that accessing:
- an uninitialized variable
number
- a non-existing object property
movie.year
- or a non-existing assortment chemical element
movies[3]
are evaluated to undefined
.
The ECMAScript specification defines the blazon of undefined
value:
Undefined type is a type 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
allow nothing ;
typeof nil === 'undefined' ; // => true
2. Scenarios that create undefined
two.1 Uninitialized variable
A declared variable just not withal assigned with a value (uninitialized) is by default
undefined
.
Obviously and simple:
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 amend.
Ideally, y'all would assign a value right away later on declaration const myVariable = 'Initial value'
. Merely that's not always possible.
Tip 1: Favor const
, otherwise use permit
, only say goodbye to var
In my opinion, one of the best features of ECMAScript 2015 is the new fashion to declare variables using const
and let
. It is a big step forward.
const
and let
are block scoped (contrary to older function scoped var
) and be in a temporal dead zone until the announcement line.
I recommend const
variable when its value is not going to change. It creates an immutable binding.
One of the nice features of const
is that you lot must assign an initial value to the variable const myVariable = 'initial'
. The variable is non exposed to the uninitialized country and accessing undefined
is impossible.
Let'south cheque the function that verifies whether a discussion is a palindrome:
javascript
function isPalindrome ( word ) {
const length = word . length ;
const one-half = Math . floor ( length / 2 );
for ( let index = 0 ; index < half ; index ++) {
if ( word [ alphabetize ] !== give-and-take [ length - index - 1 ]) {
return false ;
}
}
return true ;
}
isPalindrome ( 'madam' ); // => true
isPalindrome ( 'hello' ); // => false
length
and half
variables are assigned with a value once. Information technology seems reasonable to declare them as const
since these variables aren't going to change.
Use let
annunciation for variables whose value can modify. Whenever possible assign an initial value right away, east.one thousand. allow index = 0
.
What about the onetime schoolhouse var
? My proposition is to end using it.
var
proclamation problem is the variable hoisting within the function scope. You can declare a var
variable somewhere at the end of the function telescopic, but still, y'all tin access it before announcement: and y'all'll become an undefined
.
javascript
role bigFunction () {
// code...
myVariable ; // => undefined
// lawmaking...
var myVariable = 'Initial value' ;
// code...
myVariable ; // => 'Initial value'
}
bigFunction ();
myVariable
is accessible and contains undefined
fifty-fifty before the declaration line: var myVariable = 'Initial value'
.
Contrary, a const
or permit
variable cannot be accessed before the proclamation line — the variable is in a temporal dead zone before the declaration. And that's overnice because you have less chance to admission an undefined
.
The to a higher place example updated with allow
(instead of var
) throws a ReferenceError
because the variable in the temporal dead zone is not attainable.
javascript
function bigFunction () {
// code...
myVariable ; // => Throws 'ReferenceError: myVariable is non divers'
// code...
let myVariable = 'Initial value' ;
// code...
myVariable ; // => 'Initial value'
}
bigFunction ();
Encouraging the usage of const
for immutable bindings or let
otherwise ensures a practise that reduces the appearance 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) belong together. The cohesion tin 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 understand what the module does
- Maintainable and easier to refactor: the modify in the module affects fewer modules
- Reusable: existence focused on a single task, it makes the module easier to reuse
- Testable: you lot would easier test a module that's focused on a single task
High cohesion accompanied by loose coupling is the characteristic of a well-designed system.
A lawmaking block can be considered a small module. To profit from the benefits of high cohesion, go on the variables every bit shut every bit possible to the code cake that uses them.
For instance, if a variable solely exists to form the logic of block scope, then declare and make the variable alive merely inside that cake (using const
or let
declarations). Do not betrayal this variable to the outer block scope, since the outer block shouldn't care most this variable.
One classic example of the unnecessarily extended life of variables is the usage of for
cycle inside a function:
javascript
role someFunc ( assortment ) {
var index , item , length = array . length ;
// some code...
// some code...
for ( index = 0 ; index < length ; alphabetize ++) {
particular = array [ index ];
// some code...
}
return 'some consequence' ;
}
index
, item
and length
variables are declared at the beginning of the function body. However, they are used but near the end. What'due south the problem with this approach?
Betwixt the declaration at the top and the usage in for
argument the variables alphabetize
, item
are uninitialized and exposed to undefined
. They have an unreasonably long lifecycle in the unabridged role scope.
A better arroyo is to motion these variables as shut as possible to their usage identify:
javascript
office someFunc ( assortment ) {
// some code...
// some code...
const length = array . length ;
for ( let alphabetize = 0 ; index < length ; index ++) {
const item = array [ alphabetize ];
// some
}
return 'some result' ;
}
index
and item
variables exist only in the block scope of for
argument. They don't accept whatsoever pregnant outside of for
.
length
variable is declared close to the source of its usage too.
Why is the modified version better than the initial one? Let's encounter:
- The variables are not exposed to uninitialized land, thus you have no risk of accessing
undefined
- Moving the variables as close as possible to their usage identify increases the code readability
- High cohesive chunks of code are easier to refactor and extract into separate functions, if necessary
2.2 Accessing a non-existing holding
When accessing a non-existing object holding, JavaScript returns
undefined
.
Let's demonstrate that in an example:
javascript
allow favoriteMovie = {
title: 'Blade Runner'
};
favoriteMovie . actors ; // => undefined
favoriteMovie
is an object with a unmarried belongings title
. Accessing a non-existing property actors
using a property accessor favoriteMovie.actors
evaluates to undefined
.
Accessing a non-existing holding does non throw an error. The problem appears when trying to get data from the not-existing property, which is the nigh common undefined
trap, reflected in the well-known error message TypeError: Cannot read property <prop> of undefined
.
Permit's slightly modify the previous code snippet to illustrate a TypeError
throw:
javascript
let favoriteMovie = {
championship: 'Blade Runner'
};
favoriteMovie . actors [ 0 ];
// TypeError: Cannot read property '0' of undefined
favoriteMovie
does not have the property actors
, then favoriteMovie.actors
evaluates to undefined
.
As a consequence, 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 backdrop is a source of nondeterminism: the property may be set or not. The practiced way to bypass this problem is to restrict the object to take always defined the properties that it holds.
Unfortunately, frequently you don't have control over the objects. Such objects may have a different set of properties in diverse scenarios. And then you have to handle all these scenarios manually.
Let'south implement a function append(array, toAppend)
that adds at the beginning and/or at the terminate of an array of new elements. toAppend
parameter accepts an object with properties:
-
first
: chemical element inserted at the offset ofarray
-
terminal
: element inserted at the end ofarray
.
The part returns a new array case, without altering the original array.
The starting time version of suspend()
, a chip naive, may look like this:
javascript
part suspend ( array , toAppend ) {
const arrayCopy = [... array ];
if ( toAppend . first ) {
arrayCopy . unshift ( toAppend . first );
}
if ( toAppend . concluding ) {
arrayCopy . push ( toAppend . last );
}
return arrayCopy ;
}
suspend ([ 2 , 3 , 4 ], { showtime: ane , last: 5 }); // => [one, 2, 3, 4, 5]
suspend ([ 'Howdy' ], { last: 'World' }); // => ['Howdy', 'World']
append ([ viii , 16 ], { first: 4 }); // => [iv, viii, 16]
Considering toAppend
object can omit first
or last
backdrop, information technology is obligatory to verify whether these properties exist in toAppend
.
A property accessor evaluates to undefined
if the property does non exist. The offset temptation to cheque whether beginning
or last
properties are nowadays is to verify them against undefined
. This is performed in conditionals if(toAppend.start){}
and if(toAppend.last){}
...
Non so fast. This arroyo has a drawback. undefined
, as well equally fake
, null
, 0
, NaN
and ''
are falsy values.
In the current implementation of append()
, the part doesn't allow to insert falsy elements:
javascript
append ([ 10 ], { first: 0 , last: false }); // => [10]
0
and false
are falsy. Because if(toAppend.beginning){}
and if(toAppend.last){}
actually compare against falsy, these elements are not inserted into the array. The role returns the initial array [10]
without modifications, instead of the expected [0, 10, faux]
.
The tips that follow explain how to correctly check the belongings'south existence.
Tip iii: Check the belongings being
Fortunately, JavaScript offers a agglomeration of ways to determine if the object has a specific holding:
-
obj.prop !== undefined
: compare againstundefined
directly -
typeof obj.prop !== 'undefined'
: verify the property value blazon -
obj.hasOwnProperty('prop')
: verify whether the object has an ain belongings -
'prop' in obj
: verify whether the object has an own or inherited property
My recommendation is to utilize in
operator. It has a short and sweet syntax. in
operator presence suggests a clear intent of checking whether an object has a specific property, without accessing the bodily holding value.
obj.hasOwnProperty('prop')
is a nice solution too. It'due south slightly longer than in
operator and verifies simply in the object'south own properties.
Allow'southward improve append(array, toAppend)
function using in
operator:
javascript
function append ( array , toAppend ) {
const arrayCopy = array . slice ();
if ( 'outset' in toAppend ) {
arrayCopy . unshift ( toAppend . first );
}
if ( 'concluding' in toAppend ) {
arrayCopy . button ( toAppend . last );
}
return arrayCopy ;
}
append ([ 2 , 3 , iv ], { first: 1 , last: 5 }); // => [1, two, 3, 4, 5]
append ([ 10 ], { first: 0 , last: faux }); // => [0, 10, faux]
'get-go' in toAppend
(and 'last' in toAppend
) is true
whether the corresponding property exists, false
otherwise.
in
operator fixes the trouble with inserting falsy elements 0
and simulated
. At present, adding these elements at the beginning and the end of [10]
produces the expected result [0, ten, faux]
.
Tip four: Destructuring to admission object properties
When accessing an object property, sometimes it's necessary to ready a default value if the property does not exist.
Y'all might employ 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 properties to cheque increases. For each belongings, you 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 elegant arroyo, let's get familiar with a great ES2015 feature called object destructuring.
Object destructuring allows inline extraction of object property values directly into variables and setting a default value if the holding does not exist. A user-friendly syntax to avoid dealing directly with undefined
.
Indeed, the belongings extraction is now precise:
javascript
const object = { };
const { prop = 'default' } = object ;
prop ; // => 'default'
To come across things in action, let's define a useful function that wraps a string in quotes.
quote(field of study, config)
accepts the first argument as the string to be wrapped. The second argument config
is an object with the properties:
-
char
: the quote char, due east.1000.'
(single quote) or"
(double quote). Defaults to"
. -
skipIfQuoted
: the boolean value to skip quoting if the string is already quoted. Defaults totrue
.
Applying the benefits of the object destructuring, permit's implement quote()
:
javascript
role quote ( str , config ) {
const { char = '"' , skipIfQuoted = true } = config ;
const length = str . length ;
if ( skipIfQuoted
&& str [ 0 ] === char
&& str [ length - one ] === char ) {
return str ;
}
render char + str + char ;
}
quote ( 'Hello World' , { char: '*' }); // => '*Hello World*'
quote ( '"Welcome"' , { skipIfQuoted: truthful }); // => '"Welcome"'
const { char = '"', skipIfQuoted = true } = config
destructuring assignment in ane line extracts the backdrop char
and skipIfQuoted
from config
object.
If some properties are missing in the config
object, the destructuring consignment sets the default values: '"'
for char
and fake
for skipIfQuoted
.
Fortunately, the function all the same has room for improvement.
Let'south move the destructuring assignment into the parameters department. And set a default value (an empty object { }
) for the config
parameter, to skip the 2d argument when default settings are enough.
javascript
function quote ( str , { char = '"' , skipIfQuoted = true } = {}) {
const length = str . length ;
if ( skipIfQuoted
&& str [ 0 ] === char
&& str [ length - one ] === char ) {
return str ;
}
return char + str + char ;
}
quote ( 'Howdy World' , { char: '*' }); // => '*Hello World*'
quote ( 'Sunny twenty-four hour period' ); // => '"Sunny day"'
The destructuring consignment replaces the config
parameter in the office's signature. I like that: quote()
becomes one line shorter.
= {}
on the right side of the destructuring assignment ensures that an empty object is used if the second argument is non specified at all quote('Sunny solar day')
.
Object destructuring is a powerful feature 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 exist. As a upshot, you avoid undefined
and the hassle around it.
Tip 5: Fill the object with default backdrop
If there is no need to create variables for every property, equally the destructuring assignment does, the object that misses some backdrop can be filled with default values.
The ES2015 Object.assign(target, source1, source2, ...)
copies the values of all enumerable ain properties from one or more source objects into the target object. The part returns the target object.
For instance, you need to admission the properties of unsafeOptions
object that doesn't always contain its full set of properties.
To avoid undefined
when accessing a non-existing holding from unsafeOptions
, let'south make some adjustments:
- Define an object
defaults
that holds the default property values - Phone call
Object.assign({ }, defaults, unsafeOptions)
to build a new objectoptions
. The new object receives all properties fromunsafeOptions
, but the missing ones are taken fromdefaults
.
javascript
const unsafeOptions = {
fontSize: 18
};
const defaults = {
fontSize: sixteen ,
color: 'black'
};
const options = Object . assign ({}, defaults , unsafeOptions );
options . fontSize ; // => 18
options . colour ; // => 'black'
unsafeOptions
contains just fontSize
property. defaults
object defines the default values for backdrop fontSize
and color
.
Object.assign()
takes the kickoff statement as a target object {}
. The target object receives the value of fontSize
property from unsafeOptions
source object. And the value of colour
property from defaults
source object, because unsafeOptions
doesn't contain color
.
The club in which the source objects are enumerated does matter: after source object properties overwrite earlier ones.
Y'all are now prophylactic to access any property of options
object, including options.color
that wasn't bachelor in unsafeOptions
initially.
Fortunately, an easier culling to fill the object with default properties exists. I recommend to employ the spread backdrop in object initializers.
Instead of Object.assign()
invocation, use the object spread syntax to copy into target object all own and enumerable backdrop from source objects:
javascript
const unsafeOptions = {
fontSize: 18
};
const defaults = {
fontSize: sixteen ,
colour: 'black'
};
const options = {
... defaults ,
... unsafeOptions
};
options . fontSize ; // => 18
options . color ; // => 'black'
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 make your code rubber and durable. No matter the state of affairs, 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 null
:
javascript
const value = nullOrUndefinedValue ?? defaultValue ;
Nullish coalescing operator is convenient to admission an object property while having a default value when this property is undefined
or null
:
javascript
const styles = {
fontSize: 18
};
styles . colour ?? 'blackness' ; // => 'black'
styles . fontSize ?? sixteen ; // => 18
styles
object doesn't have the property color
, thus styles.color
property accessor is undefined
. styles.color ?? 'black'
evaluates to the default value 'black'
.
styles.fontSize
is xviii
, and so the nullish coalescing operator evaluates to the property value 18
.
ii.3 Function parameters
The function parameters implicitly default to
undefined
.
Usually a role defined with a specific number of parameters should exist invoked with the aforementioned number of arguments. That's when the parameters get the values you await:
javascript
function multiply ( a , b ) {
a ; // => v
b ; // => 3
return a * b ;
}
multiply ( 5 , 3 ); // => 15
When multiply(5, 3)
, the parameters a
and b
receive five
and respectively 3
values. The multiplication is calculated as expected: 5 * 3 = 15
.
What does happen when you omit an statement on invocation? The corresponding parameter inside the function becomes undefined
.
Let's slightly modify the previous example by calling the function with just i statement:
javascript
role multiply ( a , b ) {
a ; // => 5
b ; // => undefined
return a * b ;
}
multiply ( 5 ); // => NaN
The invocation multiply(5)
is performed with a unmarried argument: as result a
parameter is 5
, but the b
parameter is undefined
.
Tip vi: Use default parameter value
Sometimes a part does non require the full ready of arguments on invocation. Y'all can ready defaults for parameters that don't take a value.
Recalling the previous example, permit'southward make an improvement. If b
parameter is undefined
, let default it to 2
:
javascript
office multiply ( a , b ) {
if ( b === undefined ) {
b = 2 ;
}
a ; // => 5
b ; // => ii
return a * b ;
}
multiply ( 5 ); // => 10
The function is invoked with a single statement multiply(5)
. Initially, a
parameter is ii
and b
is undefined
.
The conditional argument verifies whether b
is undefined
. If it happens, b = ii
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 like a hack.
A amend approach is to apply the ES2015 default parameters feature. Information technology'south brusque, expressive and no direct comparisons with undefined
.
Adding a default value to parameter b = 2
looks amend:
javascript
function multiply ( a , b = ii ) {
a ; // => 5
b ; // => 2
return a * b ;
}
multiply ( 5 ); // => 10
multiply ( 5 , undefined ); // => x
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 it to ready default values for optional parameters.
2.4 Function render value
Implicitly, without
render
argument, a JavaScript function returnsundefined
.
A function that doesn't take render
argument implicitly returns undefined
:
javascript
function square ( 10 ) {
const res = x * 10 ;
}
square ( 2 ); // => undefined
foursquare()
function does non return whatsoever computation results. The function invocation consequence is undefined
.
The same state of affairs happens when render
argument is present, but without an expression nearby:
javascript
function square ( 10 ) {
const res = x * x ;
return ;
}
square ( 2 ); // => undefined
render;
statement is executed, only it doesn't return any expression. The invocation outcome is as well undefined
.
Of course, indicating almost render
the expression to exist returned works as expected:
javascript
function square ( x ) {
const res = 10 * ten ;
return res ;
}
foursquare ( 2 ); // => 4
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
-
permit
,const
,var
,import
,export
declarations - expression statement
-
debugger
argument -
go along
statement,break
statement -
throw
statement -
return
statement
If you lot use one of the above statements, exist certain to point a semicolon at the end:
javascript
office getNum () {
// Discover the semicolons at the end
let num = 1 ;
return num ;
}
getNum (); // => 1
At the stop of both allow
proclamation and return
statement an obligatory semicolon is written.
What happens when you lot don't want to signal these semicolons? In such a state of affairs ECMAScript provides an Automated Semicolon Insertion (ASI) mechanism, which inserts for you the missing semicolons.
Helped by ASI, you can remove the semicolons from the previous example:
javascript
function getNum () {
// Notice that semicolons are missing
let num = 1
return num
}
getNum () // => 1
The in a higher place text is a valid JavaScript code. The missing semicolons are automatically inserted for you.
At offset sight, it looks pretty promising. ASI machinery lets you skip the unnecessary semicolons. You tin make the JavaScript code smaller and easier to read.
There is ane small, but annoying trap created by ASI. When a newline stands between return
and the returned expression return \n expression
, ASI automatically inserts a semicolon before the newline return; \n expression
.
What information technology does mean inside a function to have render;
argument? The role returns undefined
. If you don't know in detail the mechanism of ASI, the unexpectedly returned undefined
is misleading.
For instance, let's study the returned value of getPrimeNumbers()
invocation:
javascript
function getPrimeNumbers () {
return
[ 2 , 3 , v , 7 , 11 , 13 , 17 ]
}
getPrimeNumbers () // => undefined
Between return
statement and the assortment literal expression exists a new line. JavaScript automatically inserts a semicolon later return
, interpreting the code equally follows:
javascript
office getPrimeNumbers () {
return ;
[ 2 , 3 , 5 , 7 , 11 , thirteen , 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 betwixt return
and array literal:
javascript
office getPrimeNumbers () {
render [
ii , 3 , 5 , vii , xi , xiii , 17
];
}
getPrimeNumbers (); // => [2, 3, 5, 7, xi, thirteen, 17]
My recommendation is to study how exactly Automatic Semicolon Insertion works to avoid such situations.
Of class, never put a newline between return
and the returned expression.
two.five void operator
void <expression>
evaluates the expression and returns undefined
no matter the result of the evaluation.
javascript
void i ; // => undefined
void ( false ); // => undefined
void {name: 'John Smith' }; // => undefined
void Math . min ( 1 , 3 ); // => undefined
One employ instance of void
operator is to suppress expression evaluation to undefined
, relying on some side-effect of the evaluation.
3. undefined in arrays
You get undefined
when accessing an array element with an out of bounds index.
javascript
const colors = [ 'blue' , 'white' , 'cherry' ];
colors [ five ]; // => undefined
colors [- one ]; // => undefined
colors
array has 3 elements, thus valid indexes are 0
, 1
, and 2
.
Because there are no array elements at indexes five
and -1
, the accessors colors[5]
and colors[-1]
are undefined
.
In JavaScript, you might encounter and then-called sparse arrays. Theses are arrays that have gaps, i.e. at some indexes, no elements are defined.
When a gap (aka empty slot) is accessed inside a sparse assortment, you lot also become an undefined
.
The following example generates sparse arrays and tries to access their empty slots:
javascript
const sparse1 = new Array ( iii );
sparse1 ; // => [<empty slot>, <empty slot>, <empty slot>]
sparse1 [ 0 ]; // => undefined
sparse1 [ i ]; // => undefined
const sparse2 = [ 'white' , , 'blue' ]
sparse2 ; // => ['white', <empty slot>, 'blueish']
sparse2 [ 1 ]; // => undefined
sparse1
is created by invoking an Array
constructor with a numeric get-go argument. Information technology has iii empty slots.
sparse2
is created with an assortment literal with the missing 2d chemical element.
In any of these sparse arrays accessing an empty slot evaluates to undefined
.
When working with arrays, to avoid undefined
, be certain to use valid array indexes and prevent the creation of sparse arrays.
4. Difference between undefined and null
What is the main departure between undefined
and null
? Both special values imply an empty state.
undefined
represents the value of a variable that hasn't been withal initialized, whilenull
represents an intentional absence of an object.
Permit's explore the difference in some examples.
The variable number
is defined, however, is not assigned with an initial value:
javascript
let number ;
number ; // => undefined
number
variable is undefined
, which indicates an uninitialized variable.
The same uninitialized concept happens when a non-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, you tin can't instantiate the object. In such case null
is a meaningful indicator of a missing object.
For instance, clone()
is a function that clones a obviously JavaScript object. The office is expected to render an object:
javascript
function clone ( obj ) {
if ( typeof obj === 'object' && obj !== null ) {
render Object . assign ({}, obj );
}
return null ;
}
clone ({ name: 'John' }); // => {name: 'John'}
clone ( 15 ); // => null
clone ( null ); // => goose egg
However clone()
might exist invoked with a not-object argument: 15
or null
. In such a case, the office cannot create a clone, so it returns null
— the indicator of a missing object.
typeof
operator makes the distinction between undefined
and null
:
javascript
typeof undefined ; // => 'undefined'
typeof null ; // => 'object'
Also the strict quality operator ===
correctly differentiates undefined
from nil
:
javascript
let null = undefined ;
let missingObject = null ;
nothing === missingObject ; // => fake
v. Conclusion
undefined
existence is a result of JavaScript's permissive nature that allows the usage of:
- uninitialized variables
- not-existing object properties or methods
- out of bounds indexes to access array elements
- the invocation result of a office that returns nothing
Comparing directly against undefined
is unsafe because you rely on a permitted but discouraged practice mentioned above.
An efficient strategy is to reduce at minimum the appearance of undefined
keyword in your code by applying expert habits such every bit:
- reduce the usage of uninitialized variables
- make the variables lifecycle curt and close to the source of their usage
- whenever possible assign initial values to variables
- favor
const
, otherwise useallow
- use default values for insignificant office parameters
- verify the backdrop beingness or fill the unsafe objects with default backdrop
- avoid the usage of sparse arrays
Is it skillful that JavaScript has both undefined
and nada
to stand for empty values?
villarealmucatinter.blogspot.com
Source: https://dmitripavlutin.com/7-tips-to-handle-undefined-in-javascript/
0 Response to "Cannot Read Property 'msie' of Undefined With Aggregated Js"
Post a Comment