Typeerror Cannot Read Property 'hasownproperty' of Undefined
Nigh of the mod languages like Ruby, Python, or Java have a single zilch value (naught or null), which seems a reasonable approach.
But JavaScript is dissimilar.
null, simply too undefined, represent in JavaScript empty values. And then what'due south the verbal difference betwixt them?
The curt answer is that JavaScript interpreter returns undefined when accessing a variable or object property that is not yet initialized. For instance:
javascript
permit visitor ;
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 like String.epitome.match() can return null to denote a missing object. Take a look at the sample:
javascript
let array = nada ;
assortment ; // => null
let movie = { proper name: 'Starship Troopers' , musicBy: null };
movie . musicBy ; // => aught
'abc' . lucifer ( / [ 0-nine ] / ); // => null
Because JavaScript is permissive, developers have the temptation to access uninitialized values. I'm guilty of such bad exercise also.
Frequently such risky actions generate undefined related errors:
-
TypeError: 'undefined' is non a function -
TypeError: Cannot read property '<prop-name>' of undefined - and alike type errors.
JavaScript developer can sympathize the irony of this joke:
javascript
function undefined () {
// problem solved
}
To reduce such errors, you have to understand the cases when undefined is generated. Let's explore undefined and its effect on code safety.
Table of Contents
- 1. What is undefined
- 2. Scenarios that create undefined
- 2.1 Uninitialized variable
- 2.two Accessing a non-existing holding
- two.3 Part parameters
- 2.4 Role return value
- 2.5 void operator
- 3. undefined in arrays
- 4. Difference between undefined and nix
- five. Conclusion
1. What is undefined
JavaScript has six primitive types:
- Boolean:
trueorfalse - Number:
1,half-dozen.seven,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 half dozen 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 conspicuously defines that you will receive undefined when accessing uninitialized variables, non-existing object properties, not-existing array elements, and alike.
A few examples:
javascript
permit number ;
number ; // => undefined
let film = { name: 'Interstellar' };
movie . twelvemonth ; // => undefined
let movies = [ 'Interstellar' , 'Alexander' ];
movies [ 3 ]; // => undefined
The to a higher place instance demonstrates that accessing:
- an uninitialized variable
number - a not-existing object property
picture show.twelvemonth - or a not-existing array 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
undefinedvalue.
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 nil ;
typeof goose egg === 'undefined' ; // => true
two. Scenarios that create undefined
2.i Uninitialized variable
A declared variable but non yet assigned with a value (uninitialized) is by default
undefined.
Plain and simple:
javascript
let myVariable ;
myVariable ; // => undefined
myVariable is declared and not notwithstanding 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 country, the better.
Ideally, you would assign a value right abroad later annunciation const myVariable = 'Initial value'. But that's not always possible.
Tip 1: Favor const, otherwise utilize permit, but say adieu to var
In my opinion, one of the best features of ECMAScript 2015 is the new way to declare variables using const and allow. It is a large step frontward.
const and allow are block 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 modify. It creates an immutable binding.
One of the nice 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 bank check the part that verifies whether a give-and-take is a palindrome:
javascript
function isPalindrome ( discussion ) {
const length = word . length ;
const half = Math . flooring ( length / 2 );
for ( permit alphabetize = 0 ; index < one-half ; index ++) {
if ( give-and-take [ index ] !== word [ length - alphabetize - 1 ]) {
render false ;
}
}
return true ;
}
isPalindrome ( 'madam' ); // => true
isPalindrome ( 'hello' ); // => false
length and one-half variables are assigned with a value once. It seems reasonable to declare them every bit const since these variables aren't going to change.
Use let declaration for variables whose value can modify. Whenever possible assign an initial value correct abroad, due east.g. allow alphabetize = 0.
What well-nigh the onetime schoolhouse var? My suggestion is to stop using information technology.
var declaration trouble is the variable hoisting within the part scope. You tin can declare a var variable somewhere at the end of the function telescopic, merely still, you can access information technology earlier annunciation: and y'all'll go an undefined.
javascript
function bigFunction () {
// code...
myVariable ; // => undefined
// code...
var myVariable = 'Initial value' ;
// lawmaking...
myVariable ; // => 'Initial value'
}
bigFunction ();
myVariable is accessible and contains undefined even before the announcement line: var myVariable = 'Initial value'.
Reverse, a const or let variable cannot exist accessed before the proclamation line — the variable is in a temporal dead zone before the proclamation. And that's nice because yous have less chance to access an undefined.
The above example updated with permit (instead of var) throws a ReferenceError because the variable in the temporal expressionless zone is non accessible.
javascript
function bigFunction () {
// code...
myVariable ; // => Throws 'ReferenceError: myVariable is not defined'
// lawmaking...
allow myVariable = 'Initial value' ;
// lawmaking...
myVariable ; // => 'Initial value'
}
bigFunction ();
Encouraging the usage of const for immutable bindings or let otherwise ensures a exercise that reduces the appearance of the uninitialized variable.
Tip two: Increase cohesion
Cohesion characterizes the degree to which the elements of a module (namespace, grade, method, block of code) vest together. The cohesion can exist loftier or depression.
A high cohesion module is preferable because the elements of such a module focus solely on a single task. It makes the module:
- Focused and understandable: easier to understand what the module does
- Maintainable and easier to refactor: the alter in the module affects fewer modules
- Reusable: being focused on a single task, it makes the module easier to reuse
- Testable: yous would easier test a module that'due south focused on a single task
High cohesion accompanied past loose coupling is the characteristic of a well-designed system.
A lawmaking cake tin can be considered a minor module. To profit from the benefits of high cohesion, keep the variables every bit close every bit possible to the lawmaking cake that uses them.
For instance, if a variable solely exists to grade the logic of block scope, then declare and make the variable live only within that block (using const or allow declarations). Practise non expose this variable to the outer block scope, since the outer cake shouldn't intendance about this variable.
One archetype example of the unnecessarily extended life of variables is the usage of for cycle within a part:
javascript
function someFunc ( array ) {
var index , detail , length = assortment . length ;
// some code...
// some code...
for ( alphabetize = 0 ; index < length ; index ++) {
particular = array [ index ];
// some lawmaking...
}
return 'some effect' ;
}
index, detail and length variables are declared at the start of the function body. All the same, they are used only near the end. What'due south the problem with this approach?
Between the declaration at the top and the usage in for argument the variables index, item are uninitialized and exposed to undefined. They have an unreasonably long lifecycle in the entire function scope.
A better approach is to motion these variables as close as possible to their usage place:
javascript
office someFunc ( assortment ) {
// some code...
// some code...
const length = array . length ;
for ( let index = 0 ; index < length ; index ++) {
const item = array [ index ];
// some
}
render 'some upshot' ;
}
index and item variables exist only in the cake 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 one? Let'due south see:
- The variables are not exposed to uninitialized state, thus you have no risk of accessing
undefined - Moving the variables every bit shut as possible to their usage place increases the code readability
- Loftier cohesive chunks of code are easier to refactor and extract into split up functions, if necessary
2.ii Accessing a non-existing property
When accessing a not-existing object holding, JavaScript returns
undefined.
Permit'southward demonstrate that in an example:
javascript
allow favoriteMovie = {
title: 'Blade Runner'
};
favoriteMovie . actors ; // => undefined
favoriteMovie is an object with a unmarried property title. Accessing a not-existing property actors using a property accessor favoriteMovie.actors evaluates to undefined.
Accessing a non-existing belongings does non throw an mistake. The problem appears when trying to get data from the non-existing belongings, which is the most common undefined trap, reflected in the well-known error message TypeError: Cannot read belongings <prop> of undefined.
Let'southward slightly modify the previous lawmaking snippet to illustrate a TypeError throw:
javascript
let favoriteMovie = {
title: 'Blade Runner'
};
favoriteMovie . actors [ 0 ];
// TypeError: Cannot read belongings '0' of undefined
favoriteMovie does not have the property actors, and so favoriteMovie.actors evaluates to undefined.
Every bit a upshot, accessing the first particular 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 skilful way to bypass this trouble is to restrict the object to accept e'er defined the properties that it holds.
Unfortunately, often you don't have control over the objects. Such objects may have a different set up of backdrop in diverse scenarios. So you take to handle all these scenarios manually.
Let'southward implement a function suspend(assortment, toAppend) that adds at the beginning and/or at the end of an array of new elements. toAppend parameter accepts an object with properties:
-
first: element inserted at the commencement ofarray -
last: chemical element inserted at the cease ofarray.
The office returns a new array instance, without altering the original array.
The starting time version of append(), a fleck naive, may look like this:
javascript
function append ( array , toAppend ) {
const arrayCopy = [... array ];
if ( toAppend . starting time ) {
arrayCopy . unshift ( toAppend . first );
}
if ( toAppend . last ) {
arrayCopy . push button ( toAppend . final );
}
return arrayCopy ;
}
append ([ 2 , 3 , iv ], { commencement: ane , last: v }); // => [1, 2, 3, 4, 5]
append ([ 'Hello' ], { last: 'World' }); // => ['How-do-you-do', 'World']
append ([ 8 , 16 ], { starting time: 4 }); // => [4, 8, 16]
Because toAppend object tin omit first or concluding properties, it is obligatory to verify whether these properties be in toAppend.
A belongings accessor evaluates to undefined if the holding does not be. The first temptation to check whether get-go or last properties are present is to verify them against undefined. This is performed in conditionals if(toAppend.outset){} and if(toAppend.last){}...
Not so fast. This approach has a drawback. undefined, likewise every bit fake, nada, 0, NaN and '' are falsy values.
In the current implementation of append(), the part doesn't allow to insert falsy elements:
javascript
append ([ ten ], { first: 0 , last: false }); // => [x]
0 and simulated are falsy. Because if(toAppend.first){} and if(toAppend.last){} actually compare confronting falsy, these elements are not inserted into the array. The function returns the initial array [ten] without modifications, instead of the expected [0, 10, false].
The tips that follow explain how to correctly bank check the property's existence.
Tip 3: Check the belongings being
Fortunately, JavaScript offers a bunch of ways to determine if the object has a specific property:
-
obj.prop !== undefined: compare againstundefineddirect -
typeof obj.prop !== 'undefined': verify the holding value blazon -
obj.hasOwnProperty('prop'): verify whether the object has an own holding -
'prop' in obj: verify whether the object has an own or inherited property
My recommendation is to use in operator. Information technology 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 actual holding value.
obj.hasOwnProperty('prop') is a overnice solution also. It'southward slightly longer than in operator and verifies only in the object's own backdrop.
Let's improve append(array, toAppend) function using in operator:
javascript
function append ( array , toAppend ) {
const arrayCopy = array . slice ();
if ( 'outset' in toAppend ) {
arrayCopy . unshift ( toAppend . starting time );
}
if ( 'last' in toAppend ) {
arrayCopy . push button ( toAppend . last );
}
return arrayCopy ;
}
append ([ 2 , 3 , iv ], { first: i , terminal: v }); // => [1, two, 3, four, v]
append ([ 10 ], { first: 0 , final: false }); // => [0, 10, faux]
'get-go' in toAppend (and 'concluding' in toAppend) is true whether the corresponding belongings exists, false otherwise.
in operator fixes the problem with inserting falsy elements 0 and false. At present, adding these elements at the showtime and the terminate of [10] produces the expected result [0, 10, false].
Tip 4: Destructuring to access object properties
When accessing an object property, sometimes information technology's necessary to gear up a default value if the belongings does non be.
Yous 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 belongings, you accept to create a new line of code to handle the defaults, increasing an ugly wall of similar-looking ternary operators.
To employ a more elegant approach, permit'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 property does non 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 see things in action, permit'due south ascertain a useful function that wraps a string in quotes.
quote(subject field, config) accepts the first statement equally the string to be wrapped. The second statement config is an object with the backdrop:
-
char: the quote char, e.g.'(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'southward implement quote():
javascript
role quote ( str , config ) {
const { char = '"' , skipIfQuoted = true } = config ;
const length = str . length ;
if ( skipIfQuoted
&& str [ 0 ] === char
&& str [ length - ane ] === char ) {
return str ;
}
return char + str + char ;
}
quote ( 'Hello World' , { char: '*' }); // => '*Hello World*'
quote ( '"Welcome"' , { skipIfQuoted: truthful }); // => '"Welcome"'
const { char = '"', skipIfQuoted = truthful } = config destructuring assignment in 1 line extracts the properties char and skipIfQuoted from config object.
If some backdrop are missing in the config object, the destructuring assignment sets the default values: '"' for char and imitation for skipIfQuoted.
Fortunately, the part still has room for improvement.
Allow's motion the destructuring consignment into the parameters section. And set a default value (an empty object { }) for the config parameter, to skip the second statement when default settings are plenty.
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: '*' }); // => '*Hullo World*'
quote ( 'Sunny day' ); // => '"Sunny day"'
The destructuring consignment replaces the config parameter in the role's 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 second statement is not specified at all quote('Sunny day').
Object destructuring is a powerful characteristic that handles efficiently the extraction of properties from objects. I like the possibility to specify a default value to be returned when the accessed property doesn't exist. As a outcome, you avert undefined and the hassle around it.
Tip five: Fill the object with default properties
If there is no need to create variables for every holding, every bit the destructuring consignment does, the object that misses some properties tin can be filled with default values.
The ES2015 Object.assign(target, source1, source2, ...) copies the values of all enumerable own properties from one or more than source objects into the target object. The function returns the target object.
For instance, y'all need to admission the properties of unsafeOptions object that doesn't always comprise its full set of backdrop.
To avert undefined when accessing a not-existing property from unsafeOptions, allow's make some adjustments:
- Define an object
defaultsthat holds the default property values - 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: eighteen
};
const defaults = {
fontSize: 16 ,
color: 'black'
};
const options = Object . assign ({}, defaults , unsafeOptions );
options . fontSize ; // => 18
options . color ; // => 'black'
unsafeOptions contains only fontSize belongings. defaults object defines the default values for properties fontSize and color.
Object.assign() takes the first argument as a target object {}. The target object receives the value of fontSize property from unsafeOptions source object. And the value of color holding from defaults source object, because unsafeOptions doesn't contain color.
The social club in which the source objects are enumerated does matter: subsequently source object properties overwrite earlier ones.
You lot are at present prophylactic to access whatsoever property of options object, including options.colour that wasn't bachelor in unsafeOptions initially.
Fortunately, an easier culling to fill the object with default properties exists. I recommend to use 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 properties from source objects:
javascript
const unsafeOptions = {
fontSize: 18
};
const defaults = {
fontSize: 16 ,
colour: 'black'
};
const options = {
... defaults ,
... unsafeOptions
};
options . fontSize ; // => 18
options . colour ; // => 'black'
The object initializer spreads backdrop from defaults and unsafeOptions source objects. The order in which the source objects are specified is important: later source object properties overwrite before 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 ever contains the full set of properties: and undefined cannot be generated.
Bonus tip: nullish coalescing
The operator nullish coalescing evaluates to a default value when its operand is undefined or aught:
javascript
const value = nullOrUndefinedValue ?? defaultValue ;
Nullish coalescing operator is user-friendly to access an object property while having a default value when this property is undefined or cypher:
javascript
const styles = {
fontSize: 18
};
styles . color ?? 'black' ; // => 'blackness'
styles . fontSize ?? xvi ; // => xviii
styles object doesn't have the property color, thus styles.color holding accessor is undefined. styles.color ?? 'blackness' evaluates to the default value 'blackness'.
styles.fontSize is 18, and so the nullish coalescing operator evaluates to the property value 18.
2.3 Part parameters
The part parameters implicitly default to
undefined.
Usually a function defined with a specific number of parameters should be invoked with the same number of arguments. That's when the parameters get the values yous expect:
javascript
role multiply ( a , b ) {
a ; // => v
b ; // => three
return a * b ;
}
multiply ( five , 3 ); // => xv
When multiply(5, 3), the parameters a and b receive 5 and respectively 3 values. The multiplication is calculated as expected: five * three = fifteen.
What does happen when y'all omit an argument on invocation? The corresponding parameter inside the function becomes undefined.
Let's slightly change the previous example by calling the function with but 1 argument:
javascript
office multiply ( a , b ) {
a ; // => 5
b ; // => undefined
return a * b ;
}
multiply ( 5 ); // => NaN
The invocation multiply(v) is performed with a single argument: as effect a parameter is 5, but the b parameter is undefined.
Tip 6: Use default parameter value
Sometimes a function does non 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's make an improvement. If b parameter is undefined, let default it to 2:
javascript
function multiply ( a , b ) {
if ( b === undefined ) {
b = two ;
}
a ; // => 5
b ; // => 2
render a * b ;
}
multiply ( 5 ); // => x
The office is invoked with a single statement multiply(five). Initially, a parameter is ii and b is undefined.
The conditional statement verifies whether b is undefined. If it happens, b = ii consignment sets a default value.
While the provided style to assign default values works, I don't recommend comparing directly against undefined. Information technology's verbose and looks like a hack.
A ameliorate approach is to utilize the ES2015 default parameters feature. It's short, expressive and no direct comparisons with undefined.
Adding a default value to parameter b = ii looks ameliorate:
javascript
role multiply ( a , b = two ) {
a ; // => 5
b ; // => 2
render a * b ;
}
multiply ( 5 ); // => 10
multiply ( 5 , undefined ); // => 10
b = 2 in the part signature makes sure that if b is undefined, the parameter defaults to 2.
ES2015 default parameters feature is intuitive and expressive. Always utilize information technology to set default values for optional parameters.
ii.4 Function return value
Implicitly, without
returnstatement, a JavaScript function returnsundefined.
A function that doesn't accept return statement implicitly returns undefined:
javascript
function square ( x ) {
const res = x * 10 ;
}
square ( two ); // => undefined
foursquare() function does not return whatever computation results. The office invocation issue is undefined.
The same situation happens when return statement is present, just without an expression nearby:
javascript
function square ( x ) {
const res = x * x ;
return ;
}
square ( two ); // => undefined
return; argument is executed, merely information technology doesn't return any expression. The invocation result is also undefined.
Of course, indicating near render the expression to be returned works every bit expected:
javascript
function square ( x ) {
const res = x * x ;
return res ;
}
square ( two ); // => four
Now the function invocation is evaluated to four, which is 2 squared.
Tip seven: Don't trust the automatic semicolon insertion
The following list of statements in JavaScript must end with semicolons (;):
- empty statement
-
permit,const,var,import,consigndeclarations - expression statement
-
debuggerargument -
go alongstatement,breakstatement -
throwstatement -
renderstatement
If you use one of the above statements, exist certain to signal a semicolon at the end:
javascript
function getNum () {
// Notice the semicolons at the end
permit num = 1 ;
render num ;
}
getNum (); // => 1
At the end of both permit declaration and return argument an obligatory semicolon is written.
What happens when you don't desire to bespeak these semicolons? In such a situation ECMAScript provides an Automatic Semicolon Insertion (ASI) mechanism, which inserts for you the missing semicolons.
Helped by ASI, y'all can remove the semicolons from the previous example:
javascript
function getNum () {
// Discover that semicolons are missing
permit num = 1
return num
}
getNum () // => 1
The above text is a valid JavaScript code. The missing semicolons are automatically inserted for you lot.
At outset sight, it looks pretty promising. ASI mechanism lets y'all skip the unnecessary semicolons. You tin make the JavaScript lawmaking smaller and easier to read.
There is 1 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 it does mean inside a part to have return; argument? The function 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
office getPrimeNumbers () {
return
[ 2 , 3 , 5 , 7 , xi , 13 , 17 ]
}
getPrimeNumbers () // => undefined
Between return statement and the array literal expression exists a new line. JavaScript automatically inserts a semicolon later return, interpreting the code as follows:
javascript
part getPrimeNumbers () {
return ;
[ 2 , 3 , 5 , 7 , 11 , 13 , 17 ];
}
getPrimeNumbers (); // => undefined
The statement return; makes the function getPrimeNumbers() to return undefined instead of the expected array.
The trouble is solved by removing the newline between return and array literal:
javascript
office getPrimeNumbers () {
render [
2 , 3 , v , 7 , eleven , 13 , 17
];
}
getPrimeNumbers (); // => [2, iii, v, 7, 11, 13, 17]
My recommendation is to written report how exactly Automatic Semicolon Insertion works to avoid such situations.
Of course, never put a newline betwixt render and the returned expression.
2.5 void operator
void <expression> evaluates the expression and returns undefined no thing the consequence of the evaluation.
javascript
void ane ; // => undefined
void ( false ); // => undefined
void {name: 'John Smith' }; // => undefined
void Math . min ( i , 3 ); // => undefined
One employ case of void operator is to suppress expression evaluation to undefined, relying on some side-effect of the evaluation.
iii. undefined in arrays
You get undefined when accessing an assortment chemical element with an out of premises index.
javascript
const colors = [ 'bluish' , 'white' , 'cerise' ];
colors [ v ]; // => undefined
colors [- 1 ]; // => undefined
colors array has three elements, thus valid indexes are 0, 1, and 2.
Because there are no array elements at indexes 5 and -1, the accessors colors[5] and colors[-1] are undefined.
In JavaScript, you might run across so-called thin arrays. Theses are arrays that have gaps, i.e. at some indexes, no elements are divers.
When a gap (aka empty slot) is accessed within a sparse assortment, you also get an undefined.
The following example generates thin arrays and tries to access their empty slots:
javascript
const sparse1 = new Array ( three );
sparse1 ; // => [<empty slot>, <empty slot>, <empty slot>]
sparse1 [ 0 ]; // => undefined
sparse1 [ 1 ]; // => undefined
const sparse2 = [ 'white' , , 'blue' ]
sparse2 ; // => ['white', <empty slot>, 'blue']
sparse2 [ one ]; // => undefined
sparse1 is created by invoking an Array constructor with a numeric first argument. It has 3 empty slots.
sparse2 is created with an assortment literal with the missing second chemical element.
In any of these sparse arrays accessing an empty slot evaluates to undefined.
When working with arrays, to avoid undefined, be sure to use valid array indexes and prevent the cosmos of sparse arrays.
four. Difference betwixt undefined and nada
What is the master difference between undefined and null? Both special values imply an empty state.
undefinedrepresents the value of a variable that hasn't been notwithstanding initialized, whilenullrepresents an intentional absenteeism of an object.
Let'south explore the deviation in some examples.
The variable number is defined, all the same, 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 belongings is accessed:
javascript
const obj = { firstName: 'Dmitri' };
obj . lastName ; // => undefined
Because lastName property does not exist 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't instantiate the object. In such case zippo is a meaningful indicator of a missing object.
For example, clone() is a role that clones a plain JavaScript object. The function is expected to return an object:
javascript
function clone ( obj ) {
if ( typeof obj === 'object' && obj !== null ) {
return Object . assign ({}, obj );
}
return zero ;
}
clone ({ name: 'John' }); // => {name: 'John'}
clone ( xv ); // => zilch
clone ( null ); // => zip
However clone() might be invoked with a non-object argument: 15 or null. In such a case, the office cannot create a clone, so it returns nada — the indicator of a missing object.
typeof operator makes the distinction betwixt undefined and null:
javascript
typeof undefined ; // => 'undefined'
typeof nil ; // => 'object'
As well the strict quality operator === correctly differentiates undefined from nix:
javascript
let nothing = undefined ;
let missingObject = null ;
cipher === missingObject ; // => false
5. Conclusion
undefined existence is a event of JavaScript'southward permissive nature that allows the usage of:
- uninitialized variables
- non-existing object backdrop or methods
- out of bounds indexes to access array elements
- the invocation result of a part that returns nothing
Comparing directly against undefined is dangerous because you rely on a permitted only discouraged exercise mentioned above.
An efficient strategy is to reduce at minimum the appearance of undefined keyword in your code by applying practiced habits such as:
- reduce the usage of uninitialized variables
- brand the variables lifecycle brusque and close to the source of their usage
- whenever possible assign initial values to variables
- favor
const, otherwise uselet - use default values for insignificant function parameters
- verify the properties existence or fill the dangerous objects with default properties
- avoid the usage of sparse arrays
Is information technology good that JavaScript has both undefined and nix to represent empty values?
Source: https://dmitripavlutin.com/7-tips-to-handle-undefined-in-javascript/
Belum ada Komentar untuk "Typeerror Cannot Read Property 'hasownproperty' of Undefined"
Posting Komentar