Language 02
JS Comparisons 1
When comparing different types, JS converts values to numbers:
1 2 3 |
|
Problems:
1 2 3 |
|
JS Comparison 2
null
and undefined
1 2 |
|
In equality:
1 2 3 |
|
JS Comparisons 3
1 2 3 |
|
undefined
gets converted to NaN
, NaN
returns false
for all comparisons. In equality check – undefined
only equals null
, undefined
and no other value.
JS Comparisons 4
- Comparison operators return a boolean value.
- Strings are compared letter-by-letter in the "dictionary" order.
- When values of different types are compared, they get converted to numbers (with the exclusion of a strict equality check).
- The values null and undefined equal == each other and do not equal any other value.
- Be careful when using comparisons like > or < with variables that can occasionally be null/undefined. Checking for null/undefined separately is a good idea.
isNaN(value)
– forNaN
checking
Dialogs
alert(message)
– Modal dialog, OK button.result = prompt(title, [default])
– modal, with input field with default value and OK/Cancel.Result === null
if canceled.Result = confirm(question)
– modal, OK/Cancel. Result istrue
for OK,false
otherwise.
Switch
- Mostly normal
- When first match is found, execution continues to next break.
- Any expression can be switch/case argument.
- Switch uses strict equality checks (===).
Functions
1 2 3 |
|
- Does not need return statement (returns
undefined
). - Variables declared inside function are local
- Can access variables from outside
- Outer variable is only used, if there is not a local one (shadowed)
- Pass arbitrary data to functions using parameters
- If value for parameter is not provided – it becomes
undefined
- Can use default values function
showMessage(text = "greetings"){}
- Default is evaluated when no parameter was presented
function showMessage(text = getText() ){}
Function expressions
1 2 3 |
|
- In JavaScript, a function is not a "magical language structure", but a special kind of value.
- Can be passed around as any other value
typeof( Math.abs ) === "function" // true
- A Function Expression is created when the execution reaches it and is usable only from that moment.
- A Function Declaration can be called earlier than it is defined.
- In strict mode, when a Function Declaration is within a code block, it’s visible everywhere inside that block. But not outside of it.
Arrow functions
Multiline arrow functions – you need return statement
1 2 3 4 5 6 |
|
For future discussion:
- Arrow functions have no
this
. Ifthis
is accessed, it’s taken from outside. - Arrow functions have no
arguments
variable - No
super
also
Objects - Basics 1
- Objects are used to store keyed collections of various data and more complex entities
- Can be created with { } or with new Object()
-
Properties can be acced and added two ways: dot notation and brackets.
1 2 3 4 5
let user = { name: "FooBar" }; user.name = "akaver"; user["name"] = "akaver"; //can use multiword properties
-
Properties can be removed with
delete
operator.delete user.name;
-
Properties names can be computed in case of
[]
.1 2 3 4
let fruit = 'apple'; let bag = { [fruit + 'Computers']: 5 };
Objects - Basics 2
-
If property name in object will be the same as variable – shorthand syntax
1 2 3 4
let name = "fooBar"; let person = { name, // same as name:name }
-
Property name limitations
- Strings or symbols (will be covered later)
-
Other types are converted to strings.
1 2 3 4
let x = { 1: "foo" }; x["1"] === "foo";
-
Can use keywords as names.
1
let x = {return: "foobar"};
-
Special property proto (later)
Objects - Basics 3
-
Property existance test
1
user.noSuchProperty === undefined // true when not found
-
Special operator
in
– key in object1 2 3
"age" in user let key = "age" key in user
-
Edge case
1 2 3 4 5 6 |
|
Objects - Basics 4
- To walk over all keys of an object, there exists a special form of the loop:
for..in
- Or use
Object.keys(someObject)
– returns array of property names. - Or use
Object.values(someObject)
– returns array of property values.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Objects - Basics 5
- Object properties – order
- Integer properties are sorted, others appear in creation order.
- The
integer property
- a string that can be converted to-and-from an integer without a change.
Objects - Basics 6
Comparison by reference
1 2 3 |
|
Objects - Basics 7
- Object copying – BY REFERENCE
- Shallow copy
1 2 |
|
- What to do when properties are other objects – deep copy
- There’s a standard algorithm for deep cloning that more complex cases, called the Structured cloning algorithm. Do not to reinvent the wheel, use a working implementation of it from the JavaScript library lodash,
_.cloneDeep(obj)
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Symbols 1
Somewhat advanced
Symbol is a primitive type for unique identifiers.
Symbols are created with Symbol()
call with an optional description (name).
Symbols are always different values, even if they have the same name.
For same-named symbols to be equal, use the global registry: Symbol.for(key)
returns (creates if needed) a global symbol with key as the name. Multiple calls of Symbol.for with the same key return exactly the same symbol.
Symbols 2
Symbols don’t auto-convert to strings.
1 2 3 |
|
Symbols allow to create "hidden" properties of an object, that no other part of code can accidentally access or overwrite.
1 2 3 |
|
Symbols 3
- Symbols are skipped by
for…in
Object.keys(user)
also ignores them- Built-in method
Object.getOwnPropertySymbols(obj)
- get all symbols. - Also there is a method named
Reflect.ownKeys(obj)
- returns all keys of an object including symbolic ones. Object.assign
copies symbols over to new object.
Object methods, this
- Objects properties can contain anything – including functions.
-
Can be defined in several ways.
-
To access current instance of the object – use
this
this
is not bound in js (its defined in run-time)!- In non strict mode – this will finally be window object
- In strict mode – if not inside object –
this == undefined
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Arrow functions and this
Arrow functions have no this
Arrow functions are special: they don’t have their "own" this
. When referenced this
from such a function, it’s taken from the outer "normal" function.
1 2 3 4 5 6 7 8 9 |
|
Object - converting to primitives
Advanced topic, later
obj + obj
orobj - obj
alert(obj)
The conversion algorithm is:
- Call
obj[Symbol.toPrimitive](hint)
if the method exists, - Otherwise if hint is "string"
- try
obj.toString()
andobj.valueOf()
, whatever exists.
- try
- Otherwise if hint is "number" or "default"
- try
obj.valueOf()
andobj.toString()
, whatever exists.
- try
1 2 3 4 5 6 7 8 9 |
|
Constructor functions, operator new
Constructor functions – just regular functions, few conventions
- Named with capital letters
- Should only be executed with “new" operator
- A new empty object is created and assigned to
this
. - The function body executes. Usually it modifies
this
, adds new properties to it. - The value of
this
is returned.
1 2 3 4 5 6 7 8 9 10 11 |
|
Constructor functions 2
Inside a function, we can check whether it was called with new or without it, using a special new.target
property.
1 2 3 4 5 6 7 8 9 |
|
Constructor functions, return
Usually, constructors do not have a return statement. Their task is to write all necessary stuff into this, and it automatically becomes the result.
But if there is a return statement:
- If return is called with an object, then the object is returned instead of
this
. - If return is called with a primitive, it’s ignored.
Destructing assignment
- Two most used data structures in JS – Array and Object
- Objects allow us to create a single entity that stores data items by key, and arrays allow us to gather data items into an ordered collection.
- You can ignore elements with extra commas
- Works with any iterable on right hand side
- Assign to anything in left hand side
- Gather remaining values into new array with “…putRestHere"
- Absent values – undefined, can use defaults
1 2 3 4 5 6 |
|
Destructuring objects
-
Also works with objects:
1
let {var1, var2} = {var1:…, var2:…}
-
Ordering of variables does not matter, names have to match.
- Names on the left can be changed
{ sourceProperty: targetVariable }
-
In case of pre-existing variables use parenthesis
1 2
let title, width, height; ({title, width, height} = {title: "Menu", width: 200, height: 100});
1 2 3 4 5
function showMenu({ title = "Menu", width = 100, height = 200 } = {}) { alert(`${title} ${width} ${height}`); } showMenu(); // Menu 100 200
Rest parameters
- Any function can be called with any number of parameters
-
Use rest parameter to collect arguments into array
1 2
function showName(firstName, lastName, ...titles) { }
-
Rest parameter must be the last one
- There is older built-in array like
arguments
variable (but its not array) - Arrow functions do not have
arguments
variable
Spread syntax
-
Reverse of rest parameters
1 2
let arr = [3, 5, 1]; alert( Math.max(...arr) ); // 5 (spread turns array into a list of arguments)
-
Can be used several times and mixed with normal parameters
-
Can be used to concatenate arrays
1 2 3
let arr = [3, 5, 1]; let arr2 = [8, 9, 15]; let merged = [0, ...arr, 2, ...arr2];
-
Can be used on objects the same way
1 2
const o1={a:'va',b:'vb'}; const o2={c:'vc', ...o1};
Object getters and setters
From outside, an accessor property looks like a regular one.
1 2 3 4 5 6 7 8 9 |
|