Speaker 1: Welcome to the deep dive. Think of this as your
Speaker 1: cheat sheet, maybe your shortcut to getting really well informed
Speaker 1: about important stuff.
Speaker 2: Yeah, we basically wade through all the information, find the
Speaker 2: core ideas, and bring back what you really need to know.
Speaker 3: Saves you time exactly.
Speaker 1: And today we are plunging into javascripts specifically for web developers.
Speaker 1: We've got a whole stack of resources here.
Speaker 2: We do, covering well everything from the real basic building
Speaker 2: blocks right up to the you know, the fancy new
Speaker 2: browser APIs and features just emerging.
Speaker 1: Right, So the mission for this deep dive pull out
Speaker 1: the essential concepts, maybe some surprising details about modern JS development.
Speaker 2: Give you a solid handle on it without you know,
Speaker 2: drowning you in every single tiny detail.
Speaker 1: Perfect. Okay, let's kick things off with something well fundamental.
Speaker 1: We always hear javascripts and ECMAScript toss around. What's the
Speaker 1: actual relationship there?
Speaker 2: Okay, good starting point. Think of ECMAScript as the official standard.
Speaker 2: It's the specificating like the rule book for how a
Speaker 2: scripting language should behave the rulebook okay in JavaScript? Well,
Speaker 2: JavaScript is the most well known language that actually follows
Speaker 2: those rules. It implements the ECMAScript standard.
Speaker 1: Ah, got it? So xmascript is the spec. JavaScript is
Speaker 1: the implementation.
Speaker 2: Exactly, and just like languages evolve, xmascript gets updated, new editions,
Speaker 2: come out S six, S twenty twenty, whatever, adding new features,
Speaker 2: refining things. JavaScript then usually catches up and implements those
Speaker 2: new features.
Speaker 1: Makes sense. So when we put JavaScript on a web page,
Speaker 1: we use the script tags. Our sources mentioned two main
Speaker 1: types these days, the old text JavaScript and the newer module.
Speaker 2: What's the key difference, right, So script type text JavaScript,
Speaker 2: that's the classic way. Code inside there runs in well
Speaker 2: basically the global scope for that script.
Speaker 1: Everything together pretty much.
Speaker 2: But script type module is different. I came with EES six.
Speaker 2: It tells the browser, hey, treat this code as a
Speaker 2: proper ECMAScript.
Speaker 1: Module and what does that let us do?
Speaker 2: That unlocks features like import and export, so you can
Speaker 2: break your code into smaller, reusable pieces, manage dependence the cleanly.
Speaker 2: It's a huge step up for organization and avoiding conflicts.
Speaker 1: Right, So it stops everything from just clashing in that
Speaker 1: one big global space, more organized, way, more organized.
Speaker 2: With separate offices communicating properly instead of one giant noisy room.
Speaker 1: Good analogy. Okay, moving into the code itself, comments, essential notes.
Speaker 2: Right.
Speaker 1: Our sources mentioned the C style comments.
Speaker 2: Yep, JavaScript uses the familiar SEA style you've got for
Speaker 2: single line comments. Anything after that on the line is ignored.
Speaker 1: And the multi line ones that's.
Speaker 2: To start and to end. You can put multiple lines
Speaker 2: of comments between those. It was a natural fit really,
Speaker 2: given JavaScript's influences and how common C style syntax was.
Speaker 1: Makes sense. Keep it familiar. Now, code structure curly braces.
Speaker 1: We use them everywhere, like with if statements. Are they
Speaker 1: just for looks or more fundamental?
Speaker 2: Oh, they're fundamental. They define code blocks. You can technically
Speaker 2: omit them for a single statement after an IF or
Speaker 2: a four like if condition do one thing.
Speaker 3: Yeah, I've seen that, but it's really.
Speaker 2: Really considered best practiced. Always use the curly braces. It
Speaker 2: makes the code much easier to read and prevents subtle
Speaker 2: bugs later if you add more statements to that block.
Speaker 1: Good advice, Always use the braces. Okay, Variables the heart
Speaker 1: of storing data. We've got the old var and the
Speaker 1: newer let and constant. Let's break down the key differences,
Speaker 1: scope hoisting all that stuff.
Speaker 2: Right, So var it's function scoped, meaning if you declare
Speaker 2: a var inside a function, it's known throughout that entire function,
Speaker 2: even inside nested blocks like ifts or loops.
Speaker 1: Okay, function scope and hoisting.
Speaker 2: Ye, var declarations are hoisted. That means the declaration part
Speaker 2: like varx is conceptually moved to the top of its
Speaker 2: function scope.
Speaker 1: Before the code runs just the declaration.
Speaker 2: Just the declaration the assignment x equals ten stays where
Speaker 2: you wrote it. This can lead to weird situations where
Speaker 2: you can use a variable before its declaration appears in
Speaker 2: the code, and it'll have the value undefined.
Speaker 1: And you can readeclare var variables too.
Speaker 2: Yep, you can write var myvar five and then later
Speaker 2: varivar ten in the same scope and JavaScript is fine
Speaker 2: with it, which can also cause confusion.
Speaker 1: Definitely sounds like it could. So how does let improve things?
Speaker 2: Let was introduced in e S six to fix these issues.
Speaker 2: The big change is block scope. A LET variable is
Speaker 2: only known within the specific block that curly braces words.
Speaker 1: Defined, So inside an if or a for loop, it
Speaker 1: only exists there exactly.
Speaker 2: Much more contained, much easier to reason about. It prevents
Speaker 2: accidental variable clashes between different parts of your code.
Speaker 1: That sounds way better. What about hoisting and redeclaration with let.
Speaker 2: Let declarations are also hoisted, but critically their initialization is not.
Speaker 2: This creates something called the temporal dead zone or TDZ.
Speaker 2: If you try to access a let variable before it's
Speaker 2: actual declaration line in the code, you get a reference there.
Speaker 1: Ah. Okay, so safer prevents using it before it's.
Speaker 2: Ready, right, and you cannot redeclare a let variable within
Speaker 2: the same scope. Yeah, if you try let x five
Speaker 2: let x bleeds ten in the same block, you'll get
Speaker 2: an error much stricter.
Speaker 1: Good and then const the name implies it can't be changed.
Speaker 2: Very similar to it's also block scoped has the TDZ
Speaker 2: and cannot be redeclared in the same scope.
Speaker 1: But the key difference.
Speaker 2: You must initialize a cost variable when you declare it
Speaker 2: like cost pi equals three point one four, and once assigned,
Speaker 2: you cannot reassign that variable to a different value. The
Speaker 2: binding is constant.
Speaker 1: So pi equals three later would cause an error exactly.
Speaker 2: But and this is important, if the const variable holds
Speaker 2: an object or an array, you could still change the
Speaker 2: contents of that object or array. You just can't make
Speaker 2: the variable point to a completely new object or array.
Speaker 1: Ah. Subtle but crucial distinctions. The variable binding is constant,
Speaker 1: not necessarily the value itself if it's an object precisely.
Speaker 2: And our sources mentioned a potential performance benefit to using
Speaker 2: let and const over var, because the engine has a
Speaker 2: better idea of how the variable will be used.
Speaker 1: Interesting worth keeping in mind. Now, naming these variables identifiers,
Speaker 1: are there strict rules?
Speaker 2: Yes, identifiers have to start with a letter, an underscore,
Speaker 2: or a dollar sign after the first character. You can
Speaker 2: also use numbers, okay.
Speaker 1: Any things you can't use definitely.
Speaker 2: You can't use JavaScript keywords like if, for function, let, const, var,
Speaker 2: et cetera. You also can't use reserved words words set
Speaker 2: aside for future use, and the literal values true, false,
Speaker 2: and null are also off limits as variable names.
Speaker 1: Makes sense, don't want to confuse the language itself. Okay,
Speaker 1: Let's talk data types the primitives first. These are the
Speaker 1: simple fundamental types, right, the.
Speaker 2: Basic building blocks. First up is number. This covers both
Speaker 2: integers and floating point numbers. JavaScript doesn't really distinguish between
Speaker 2: them internally in the way some other languages do.
Speaker 1: Some number okay, Any special ways to write.
Speaker 2: Numbers, Yeah, you can write integers in decimal obviously, but
Speaker 2: also binary using a zero B prefix, octal with a
Speaker 2: zero O prefix or just eleading zero in nonstrict mode,
Speaker 2: which can be confusing, and hexadecimal with zero.
Speaker 1: X hex is pretty common in web dev, very common.
Speaker 2: And within number you also have the special values nan
Speaker 2: not a.
Speaker 1: Number, which can confusingly is a number type right?
Speaker 2: Ah? Yes, type of nan returns number. It usually results
Speaker 2: from invalid math operations like zero zero, and you have
Speaker 2: infinity and into infinity.
Speaker 1: Okay, And what about really really huge numbers.
Speaker 2: That's where bigin comes in. It's a newer primitive type
Speaker 2: designed to handle integers larger than the maximum safe integer
Speaker 2: value for number, which is around two to the power
Speaker 2: of fifty three minus one.
Speaker 3: Wow.
Speaker 1: How do you create those?
Speaker 2: You append an end to the end of an integer
Speaker 2: literal like one, two, three, four five n or you
Speaker 2: use the big in function.
Speaker 1: Any gotcha's with big inn.
Speaker 2: Yeah. You can't mix biggest and number types in standard
Speaker 2: arithmetic operations directly. You have to convert them, and you
Speaker 2: can't use big in values with the built in math
Speaker 2: object methods.
Speaker 1: Good to know. Okay. Beyond numbers, we have.
Speaker 2: String represents text basically a sequence of sixteen bit Unicode characters.
Speaker 2: You can use single quotes, double quotes, or backticks to
Speaker 2: define them.
Speaker 1: Any difference between single and double quotes.
Speaker 2: Functionally no, it's mostly style preference, though enable template literals,
Speaker 2: which are super useful for embetting expressions directly into strings.
Speaker 1: Right with the syntax very handy.
Speaker 2: Next, boolean simple one can only be true or false,
Speaker 2: used all the time for conditional logic.
Speaker 1: Okay, and then null and undefined They seem similar but
Speaker 1: aren't quite.
Speaker 2: The same correct. Null is a primitive type that represents
Speaker 2: the intentional absence of any object value you explicitly set
Speaker 2: something to null. Undefined means a variable has been declared
Speaker 2: but hasn't been assigned of value yet. It's the default state.
Speaker 1: So null is I meant for this to be empty?
Speaker 1: And undefined is nobody put anything here yet?
Speaker 2: That's a good way to think about it. And finally,
Speaker 2: among the primatives, there's symbol symbols.
Speaker 1: These are unique identifiers right exactly.
Speaker 2: Symbol creates a unique, immutable primitive value. Even if you
Speaker 2: create two symbols with the same description, like symbol foo
Speaker 2: and simple foo, they are not equal. They're unique.
Speaker 1: What are they used for?
Speaker 2: Often? Uses keys for object properties when you want to
Speaker 2: avoid potential clashes with other properties or library code. There's
Speaker 2: also symbol dot four key, which creates or retrieve symbols
Speaker 2: from a global registry. So symbol dot for food.
Speaker 1: Interesting. Do they show up in normal object iteration? Not?
Speaker 2: Usually they aren't enumerated by four dot. In loops, you
Speaker 2: need specific methods like object dot get town property symbols,
Speaker 2: or reflect dot own keys to access them.
Speaker 1: Okay, and there are built in symbols.
Speaker 2: Too, Yes, well known symbols like symbol dot iterator, symbol
Speaker 2: dot replace, symbol dot search. These allow you to hook
Speaker 2: into fundamental language behaviors.
Speaker 1: That's a lot of primitives. Okay, let's talk operators doing
Speaker 1: things with these values basic math like and seem straightforward.
Speaker 1: But what about those bitwise operators? When do we use those?
Speaker 2: Right? So, multiplication and division have rules for nan and
Speaker 2: infinity like infinity zeros in NAN, but the bitwise operators
Speaker 2: and D or xo R not marriot left shift signed
Speaker 2: right shift, unsigned right shift. They operate directly on the
Speaker 2: binary representation of numbers.
Speaker 1: Lower level stuff, yeah.
Speaker 2: Very low level. You might use them for things like
Speaker 2: manipulating flags stored in a single number. Performance critical calculations,
Speaker 2: maybe graphics or network protocol work where you're packing data efficiently.
Speaker 1: So left shift multiplies by powers of two.
Speaker 2: Correct and preserves the sign signed right shift divides by
Speaker 2: powers of two, also preserving the sign. Unsigned right shifts
Speaker 2: also divides, but always fills with zeros on the left,
Speaker 2: so the result is always non negative. Not everyday tools
Speaker 2: for most web devs, but good to know they.
Speaker 1: Exist definitely now the sources mentioned the with statement sounds old, it.
Speaker 2: Is and definitely deprecated and forbidden in strict mode. Its
Speaker 2: idea was to shorten access to object properties like with
Speaker 2: document dot location instead of repeating document dot location.
Speaker 1: Why is it bad?
Speaker 2: It makes code really hard to understand because it's unclear
Speaker 2: where variables are coming from. Are they local, global, or
Speaker 2: from the with object And it kills performance because the
Speaker 2: engine can't easily optimize lookups.
Speaker 1: Avoid it good advice avoid with Okay, last fundamental strict
Speaker 1: mode you strict. Why should we use this?
Speaker 2: Strict mode is basically a way to opt into a cleaner, safer,
Speaker 2: less error prone version of JavaScript. You put the string
Speaker 2: you strict at the very top of a script or
Speaker 2: a function, and what does it do. It changes certain things.
Speaker 2: It turned some previously silent errors into throne errors. For example,
Speaker 2: assigning a value to an undeclared variable throws an error
Speaker 2: instead of implicitly creating a global variable.
Speaker 1: Ah. That's good. Helps catch typos exactly.
Speaker 2: It also prevents or throws errors for certain unsafe actions
Speaker 2: like deleting variables or functions. It bans the wis statement.
Speaker 2: It makes evil safer. It prevents using reserved words like
Speaker 2: evil or arguments as variable names.
Speaker 1: So it basically tightens up the rules and catches common
Speaker 1: mistakes pretty much.
Speaker 2: It helps you write more robust, maintainable code. It's highly
Speaker 2: recommended for all modern JavaScript development.
Speaker 1: Makes total sense like built in code review. Okay, let's
Speaker 1: switch gears to objects in a raise complex data first.
Speaker 1: That distinction primitive versus reference value. Why is this so critical?
Speaker 2: It fundamentally changes how you work with data. Primitive values, numbers, strings, booleans,
Speaker 2: et cetera. Are passed by value. When you assign a
Speaker 2: primitive variable to another, you're making a completely separate.
Speaker 1: Copy, independent copies, right.
Speaker 2: But reference values objects in a raise are passed by reference.
Speaker 2: When you assign an object variable to another, both variables
Speaker 2: end up pointing to the exact same object in memory.
Speaker 1: So changing the object through one variable affects the other absolutely.
Speaker 2: If you have OBJ one down a OBJ two dot
Speaker 2: day one and then you do OBJ two dot name
Speaker 2: aples a b UPJ one dot name will also be b.
Speaker 2: They're referencing the same underlying data structure. Understanding this is
Speaker 2: crucial for avoiding unexpected side effects.
Speaker 1: Definitely okay, So how do we figure out what type
Speaker 1: of data we have? Type of seems like the obvious choice,
Speaker 1: but it has quirks.
Speaker 2: It does type or for works great for primitives number, string,
Speaker 2: boolly and undefined symbol big int. It also correctly identifies
Speaker 2: functions returning function.
Speaker 1: But for objects, and as for.
Speaker 2: Most reference types, including regular objects in arrays, type offf
Speaker 2: just returns object, and confusingly, type of null also returns object.
Speaker 2: That's a long standing historical bug.
Speaker 1: So type of isn't always specific enough for objects. What
Speaker 1: else can we use?
Speaker 2: The instance of operator is often better for checking object types.
Speaker 2: You can do my array instance of array or my
Speaker 2: date instance of date to see if an object was
Speaker 2: created by a specific constructor or inherits from its prototype.
Speaker 1: Okay, instance of for more specific object checks now scope.
Speaker 1: How does JavaScript know which variable we mean when we
Speaker 1: use a name? The scope chain exactly.
Speaker 2: Scope determines where variables are accessible. JavaScript uses lexical scope,
Speaker 2: meaning scope is defined by where the code is physically written.
Speaker 2: When you use a variable, the engine first looks in
Speaker 2: the current innermost scope, and if it's not there, looks
Speaker 2: in the next scope outwards, then the next, and so
Speaker 2: on up the chain until it hits the global scope.
Speaker 2: This sequence of scopes is the.
Speaker 3: Scope chain, like nested boxes pretty much.
Speaker 2: If it which is the global scope and still doesn't
Speaker 2: find the variable, you get a reference error in strict mode. Anyway,
Speaker 2: looking up globals can be slightly slower than locals because
Speaker 2: the chain might be longer, but engines optimize this well.
Speaker 1: Okay. And memory management, JavaScript cleans up after itself with
Speaker 1: garbage collection. How does that work?
Speaker 2: Yes? JavaScript has automatic garbage collection PC. The engine tracks
Speaker 2: which objects are still reachable, meaning they can somehow be accessed,
Speaker 2: starting from the root objects like the global.
Speaker 1: Window object, so it traces all the references kind of.
Speaker 2: The most common algorithm is mark and sweep. The GC
Speaker 2: starts at the roots, marks all reachable objects, and then
Speaker 2: sweeps through memory reclaiming the memory used by any object
Speaker 2: that wasn't marked.
Speaker 1: So if nothing points to an object anymore, it gets
Speaker 1: swept up.
Speaker 2: Essentially, Yes, it's automatic, but not fool proof. You can
Speaker 2: still create memory leaks if you unintentionally keep references to
Speaker 2: objects you no longer need. And the timing of GC
Speaker 2: is nondeterministic. You don't control exactly when it runs.
Speaker 1: I know it's mostly handled, but leaks are still possible.
Speaker 1: All right, let's look at specific reference types. The basic object.
Speaker 1: It's more than just key value pairs, isn't it.
Speaker 2: Oh yeah. Object is the foundation for almost everything complex
Speaker 2: in JavaScript. It's a dynamic collection of properties where keys
Speaker 2: are usually strings or symbols, and values can be anything.
Speaker 2: We usually create them with object literals. It's the basis
Speaker 2: for prototype based inheritance, which is core to JS.
Speaker 1: The cornerstone, okay, an array. It's like a list, but
Speaker 1: more flexible than in some languages.
Speaker 2: Definitely. JavaScript arrays are ordered lists, but they're dynamic. They
Speaker 2: can grow and shrink, and importantly, they can hold elements
Speaker 2: of any data type mixed together. A single ray could
Speaker 2: have numbers, strings, objects, even other.
Speaker 3: Arrays very flexible.
Speaker 1: How do we make arrays. Literals are common.
Speaker 2: Literals are the most common and usually the best way.
Speaker 2: You can also use new array, but it has some
Speaker 2: weird behavior if you pass just one number argument. A
Speaker 2: ray out from is super useful for converting array like
Speaker 2: things like dom modalists or the argument's object or iter
Speaker 2: like sets or maps into real arrays.
Speaker 1: Array dot from some sandy and array dot from.
Speaker 2: Array does creates a new array with whatever arguments you
Speaker 2: pass it. A ray dot one two three gives one
Speaker 2: two three, and a ray of seven gives seven. It
Speaker 2: avoids the new array seven confusion, which creates an mpty
Speaker 2: array of length seven.
Speaker 1: Got it now changing array contents, dot fil sort, splice,
Speaker 1: What do these do?
Speaker 2: Phil Let's you set all or part of an array
Speaker 2: to a static value. Useful for initialization. Sort sorts the
Speaker 2: array in place than gotcha. By default, it sorts lexicographically
Speaker 2: like stringths.
Speaker 1: So one ten two would sort to one ten two exactly.
Speaker 2: For numeric sorting, you must provide a comparison function like
Speaker 2: ab equal ab for ascending order.
Speaker 1: Right always provide the compare function for numbers, and splice.
Speaker 2: Splice is the Swiss army knife. Let's remove elements in
Speaker 2: some elements or replace elements all of a specific index,
Speaker 2: modifying the original array directly. It's very powerful. Splice in
Speaker 2: x lead count outum one item.
Speaker 1: Two okay, modifies in place. What about finding things? Index
Speaker 1: of last and x xen inclusion.
Speaker 2: The first index of an item searching forwards last index
Speaker 2: yeah finds the last index searching backwards. Both return to
Speaker 2: nus one if not found, and both use strict equality
Speaker 2: and include just returns true or if false if the item
Speaker 2: exists in the array. Simpler if you don't need the index.
Speaker 2: It also uses strict equality index of and last index.
Speaker 2: Oves can take an optional second argument for the starting
Speaker 2: search position.
Speaker 1: Use includes for existence, check indexoflast, index of if you
Speaker 1: need the position. And reduce sounds like it boils an
Speaker 1: array down.
Speaker 2: It does. Reduce iterates through an array applying a function
Speaker 2: you provide to accumulate a single result. The function gets
Speaker 2: the accumulator, the current value, the index, and the array itself.
Speaker 2: You can some numbers, build an object, flatten an array
Speaker 2: really versatile. You usually provide an initial value for the accumulator.
Speaker 1: Powerful stuff, okay. Type dearrays in eight array float thirty
Speaker 1: two array. These sound specialized? Why use them over regular arrays.
Speaker 2: Performance, mainly when dealing with raw binary data. Regular rays
Speaker 2: are super flexible, but that flexibility has overhead. Type raise
Speaker 2: give you a direct fixed length view onto a chunk
Speaker 2: of binary memory an array buffer, where each element is
Speaker 2: known to be a specific numeric type like eight bit unsigned, editger,
Speaker 2: thirty two bit float, et cetera.
Speaker 1: So for things like graphics or processing audio data.
Speaker 2: Exactly WebGL web audio API manipulating file data read into
Speaker 2: an array buffer. They share many methods with regular arrays,
Speaker 2: map filter, etc. But they operate within the constraints of
Speaker 2: their type and fixed length. They also have methods like
Speaker 2: set for efficiently copying data in and subaray to create
Speaker 2: a new typed to array view over a portion of
Speaker 2: the same buffer.
Speaker 1: Efficient binary data handling and data view. How's that different?
Speaker 2: Data View also works on an array buffer, but it's
Speaker 2: even lower level. Instead of viewing the whole buffer as
Speaker 2: one type, data view lets you read and write different
Speaker 2: numeric types at any byte offset within the buffer.
Speaker 1: So you could read an eight bit in then a
Speaker 1: sixteen bit float from the same.
Speaker 2: Buffer precisely, and crucially, data view lets you control the
Speaker 2: endianness byte order big indian or little endian for multi
Speaker 2: byte types. This is essential when you're working with specific
Speaker 2: file formats or network protocols that dictate a particular byte order.
Speaker 1: So typed arrays for uniform numeric arrays. Data view for
Speaker 1: fine grained multi type endingess controlled access to binary data.
Speaker 2: That's a great summary.
Speaker 1: Okay, let's talk collections, map and set. How are they
Speaker 1: different from plain objects and arrays.
Speaker 2: Map is like an object for key value pairs, but
Speaker 2: with key differences. Keys in a map can be any
Speaker 2: data type, not just strings or symbols. You can use
Speaker 2: an object or even a function as a key. Also,
Speaker 2: map remembers the original insertion order.
Speaker 1: Of keys any data type as a key and ordered
Speaker 1: useful and set.
Speaker 2: Set is a collection of unique values you add items,
Speaker 2: and duplicates are automatically ignored. Like MAP, it also remembers
Speaker 2: insertion order. Great for quickly removing duplicates from an array
Speaker 2: or just storing a list where uniqueness matters.
Speaker 1: Set for uniqueness map for flexible keys. What about weak set?
Speaker 1: What's weak about it?
Speaker 2: Weekset is it's like set, but it only holds objects,
Speaker 2: and it holds them weekly. This means if an object
Speaker 2: is only referenced by the weakset and nowhere else in
Speaker 2: your code. The garbage collector is free to remove it.
Speaker 1: Ah, so it doesn't prevent garbage collection. Why is that useful?
Speaker 2: It's great for associating metadata with objects without preventing those
Speaker 2: objects from being cleaned up if they're removed from say
Speaker 2: the DOM. If you remove a DOM element and it
Speaker 2: was in the week set, the weekset reference won't keep
Speaker 2: it lingering in memory because items can disappear. You can't
Speaker 2: iterate over a week set.
Speaker 1: Smart for managing metadata on potentially transient objects. Okay, iterating
Speaker 1: over these collections in arrays and strings. The iteration protocols.
Speaker 1: What's the deal with symbol dot iterator?
Speaker 2: Right? For an object to be considered iterable, meaning you
Speaker 2: can use it with for out of loops or spread syntax,
Speaker 2: it needs to have a method whose key is the
Speaker 2: well known symbol symbol dot iterator.
Speaker 1: And what does that method do?
Speaker 2: That method, when called, must return an iterator object. The
Speaker 2: iterator object, in turn, must have an next method.
Speaker 1: And next gives you the value.
Speaker 2: Calling next returns an object with two properties value the
Speaker 2: next value in the sequence and done a boollion that's
Speaker 2: false until the iteration is complete, then it becomes true.
Speaker 1: So iterable means has symbol dot iterator, which gives an
Speaker 1: iterator which has naxt got it.
Speaker 2: That's the contract and for.
Speaker 1: Data Bouve just handles all that automatically.
Speaker 2: Yep fata b loops are designed specifically to work with
Speaker 2: this protocol. It calls symbol dot iterator, gets the iterator,
Speaker 2: and keeps calling next until done is true, give you
Speaker 2: the value at each step. Works on a raise strings, map, sets,
Speaker 2: no lists anything.
Speaker 1: Iterable much nicer than old four loops with index counters.
Speaker 1: Sometimes now generators dot function How do they fit into iteration?
Speaker 2: Generators are a special kind of function defined with function.
Speaker 2: When you call a generator function, it doesn't run the
Speaker 2: code immediately. Instead, it returns a generator object, which is
Speaker 2: an iterator.
Speaker 1: So calling it gives you the iterator directly.
Speaker 2: Yes. Inside the generator function, you use the yield keyword.
Speaker 2: Word yield pauses the function's execution and sends a value
Speaker 2: out that becomes the value in the value done object.
Speaker 3: From next pauses the function Yeah.
Speaker 2: The next time you call next on the generator object,
Speaker 2: the function resumes exactly where it left off right after
Speaker 2: the yield and continues until it hits the next yield
Speaker 2: or the end.
Speaker 1: Of the function whoa functions that pause and resume.
Speaker 2: It's powerful makes writing complex iterators much easier. You can
Speaker 2: also use yield to delegate iteration to another iterable or generator.
Speaker 1: Fascinating and async iterators a sync function and for a
Speaker 1: weight dot f. This is for asynchronous sequences exactly.
Speaker 2: ACNC iteration protocols handle sequences where the values arrive asynchronously,
Speaker 2: like data streaming over a network, and ACNC literable has
Speaker 2: symbol dot ACNC iterator, which returns an ACNC iterator.
Speaker 1: And its next method.
Speaker 2: Its next method returns a promise that resolves to the
Speaker 2: value downe object ah.
Speaker 1: So next is async itself.
Speaker 2: Right, and the four weight of loop is designed to
Speaker 2: work with these. It weighs asynchronously for the promise from
Speaker 2: next to resolve before each iteration. Perfect for handling streams
Speaker 2: of data like chunks from a fetch response or server
Speaker 2: send events.
Speaker 3: Very cool.
Speaker 1: Okay, let's dive deeper into objects. Property attributes, configurable, innumerable, writable.
Speaker 1: What are these internal things?
Speaker 2: Every object property has these internal attributes to control its behavior.
Speaker 2: Configurable means can the property be deleted or can its
Speaker 2: attributes be changed later? Innumerable means does it show up
Speaker 2: in four lot loombs, ritable means can its value be changed?
Speaker 2: And value holds the actual value.
Speaker 1: So they define the meta behavior of the property exactly.
Speaker 2: They're also get and set attributes for accessor properties getters
Speaker 2: and setters instead of value.
Speaker 1: And ritable, and we control these using object dot define property.
Speaker 2: Yes, object dot define property lets you define a new
Speaker 2: property or modify an existing one and explicitly set these
Speaker 2: attribute values like innumerable dot false or ritable dot false.
Speaker 2: You can also define getter and setter functions using this
Speaker 2: object out defined properties lets you do it for multiple
Speaker 2: properties at once.
Speaker 1: Gives you fine grain control. Now, object literals have some
Speaker 1: nice shorthands these days, right they do.
Speaker 2: If you have variable X and you want an object
Speaker 2: property x with that variable's value, you can just write
Speaker 2: x instead of xx.
Speaker 1: Nice. And for methods you can.
Speaker 2: Write my methods my method dot function cleaner syntax.
Speaker 1: And computed property keys.
Speaker 2: Yeah, you can use square brackets inside an object literal
Speaker 2: to use the result of an expression as a property
Speaker 2: key like prefix plus id. Very dynamic.
Speaker 1: These shorthands definitely make object creation less verbose. What about
Speaker 1: combining objects object dot A sign. How does it work?
Speaker 2: Object out a sign target dot sources copies all innumerable
Speaker 2: own properties from the source objects into the target object.
Speaker 2: It modifies the target directly and returns.
Speaker 1: It copies properties. Is it a deep copy?
Speaker 2: No. Crucially, it's a shallow copy. If a property value
Speaker 2: is an object or array, only the references copy, not
Speaker 2: the nested structure itself. Both the target and source will
Speaker 2: point to the same nested object.
Speaker 1: Okay, shall I copy important limitation? How does it handle
Speaker 1: getter setters?
Speaker 2: It invokes getters on the source and copies the resulting
Speaker 2: value to the target. It doesn't copy the getter function itself.
Speaker 2: Setters aren't copied.
Speaker 1: Got it useful for emerging simple objects or applying mix ins?
Speaker 1: What about getting values out of objects? Destructuring?
Speaker 2: Object destructuring is fantastic. It lets you unpack properties from
Speaker 2: an object directly into variables like const name age user.
Speaker 1: Much cleaner than constname user dot name constant age user
Speaker 1: dot age way cleaner.
Speaker 2: You can also rename variables comments, provide default values, constme measures,
Speaker 2: and use the rest syntax to collect remaining properties into
Speaker 2: a new object. Constant aid rest data.
Speaker 1: Super useful for working with API responses or config and
Speaker 1: the spread operator also works inside object literals.
Speaker 2: Yes, similar to object dot assign it lets you spread
Speaker 2: the properties of an existing object into a new object
Speaker 2: literal constant new user u uzer age thirty one is
Speaker 2: admin false. Also a shallow copy. Great for creating modified
Speaker 2: copies of objects nondestructively.
Speaker 1: Okay, spread for creating new objects based on old ones.
Speaker 1: Now the tricky this keyword. Its value depends on how
Speaker 1: a function.
Speaker 2: Is called right, hugely depends on the call site. In
Speaker 2: a regular function called directly, not as an object method,
Speaker 2: this is the global object window and browsers in non
Speaker 2: strict mode and undefined as strict mode.
Speaker 1: Okay, what about when it's a method like an object
Speaker 1: dot do something.
Speaker 2: Then this inside do something refers to object the object
Speaker 2: the method was called on.
Speaker 1: Makes sense, and we can explicitly set this yep.
Speaker 2: Using function dot call this rg R one, function dot
Speaker 2: apply this ars array, or function dot bind this arg
Speaker 2: which returns a new function permanently bound to that this value.
Speaker 1: And ero functions they're different.
Speaker 2: Completely different regarding this erofunctions don't have their own this.
Speaker 2: They lexically capture this value from their surrounding scope at
Speaker 2: the time they are defined. This solves many old problems,
Speaker 2: especially with callbacks inside methods that lexical.
Speaker 1: This in aerow functions is a key feature. Okay, let's
Speaker 1: talk inheritance prototypes. This is JavaScript's core inheritance model, right,
Speaker 1: not classes, initially.
Speaker 2: Correct, JavaScript uses prototype based inheritance. Every function is a
Speaker 2: prototype property, which is an object. When you use a
Speaker 2: function as a constructor with new the object created inherence
Speaker 2: from the constructor's prototype, object inherits.
Speaker 1: How does that work?
Speaker 2: Every object has an internal link, often accessible via proto,
Speaker 2: though object dot get prototype of is the standard way
Speaker 2: to read it to its prototype. When you try to
Speaker 2: access a property on an object, if the object doesn't
Speaker 2: have it directly, JavaScript looks at its prototype. If the
Speaker 2: prototype doesn't have it, it looks at its prototype, and so
Speaker 2: on up the chain.
Speaker 1: The prototype chain, so properties are looked up along this
Speaker 1: chain exactly.
Speaker 2: That's how inheritance works. Methods defined on a constructor's prototype
Speaker 2: are shared by all instances created from that constructor. You
Speaker 2: can use object dot is prototype of another object to
Speaker 2: check the chain relationship.
Speaker 1: Okay, Prototypes are the real mechanism. So what about ES
Speaker 1: six class syntax? Is that just sugar on top.
Speaker 2: Pretty much class provides a cleaner, more familiar syntax for
Speaker 2: setting up constructor functions and their prototypes. The constructor method
Speaker 2: inside a class defines the constructor function. Other methods defined
Speaker 2: in the class body automatically get added to the class's prototype.
Speaker 1: So it makes prototype inheritance look more like classical inheritance.
Speaker 2: Kind of yes, it simplifies the syntax. Class also introduces
Speaker 2: features like static members belonging to the class itself, not instances,
Speaker 2: and more recently, private members using the hashtag prefix for
Speaker 2: true encapsulation. But underneath it's still leveraging the prototype chain.
Speaker 1: Good to know classes mostly syntax over the existing prototype system. Okay,
Speaker 1: let's focus specifically on functions. Now different ways to define
Speaker 1: them declarations, expressions, arrows right.
Speaker 2: Function declarations look like function my function. These are fully hoisted.
Speaker 2: You can call them before they appear in the.
Speaker 1: Code hoisted okay, and expressions.
Speaker 2: Function expressions assign a function to a variable like co
Speaker 2: hocal function or constant my aerowfunk. With these, only the
Speaker 2: variable declaration constant my funk is hoisted, not the function
Speaker 2: assignment itself. You can't call them before the line where
Speaker 2: they're assigned.
Speaker 1: So declarations are fully hoisted expressions including arrows are not correct.
Speaker 2: And aero functions have that concise syntax in the lexical
Speaker 2: this binding we talked about. There's also the function constructor
Speaker 2: new function ab return of plus b, but it's generally discouraged.
Speaker 2: Like evil, it executes code from strings, which is slow
Speaker 2: and potentially insecure.
Speaker 1: Stick to declarations, expressions and arrows. Then, what about handling
Speaker 1: arguments rest parameters.
Speaker 2: Rest parameters dot orgs let you gather an indefinite number
Speaker 2: of trailing arguments passed to a function into a single
Speaker 2: real array named arcs, much better than the old arguments.
Speaker 1: Object and spread syntax in function calls.
Speaker 2: That does the opposite. It takes an iterable like an
Speaker 2: array and expands it into individual arguments. When calling a
Speaker 2: function my function dot my array.
Speaker 1: So rest collects arguments into an array. Spread expands an
Speaker 1: array into arguments. Got it and default parameter values.
Speaker 2: Yeah, you can set defaults directly in the signature function creed.
Speaker 2: If the argument isn't provided or is undefined, the default
Speaker 2: is used. Makes functions more robust.
Speaker 1: We covered hoisting already. How about functions as values first
Speaker 1: class functions?
Speaker 2: It just means functions in JavaScript are treated like any
Speaker 2: other value. You can assign them to variables, store them
Speaker 2: in arrays or objects, pass them as arguments to other
Speaker 2: functions callbacks, and return them from functions higher order functions.
Speaker 2: This is fundamental to functional programming patterns in JS.
Speaker 1: Very flexible. What about the caller property and the arguments
Speaker 1: object still relevant?
Speaker 2: The argument's object exists in non arrow functions. It's an
Speaker 2: array like object holding all past arguments. But rest parameters
Speaker 2: are generally preferred now because they give you a real array.
Speaker 2: Arguments dot collie refers to the current function and arguments
Speaker 2: dot caller or function dot caller refers to the calling
Speaker 2: function are deprecated, non standard and forbidden in strict mode.
Speaker 2: Avoid them good to know.
Speaker 1: Stick with rest parameters. Finally, execution context, scope chain, and closure.
Speaker 2: These sound deep, they are core concepts and execution context
Speaker 2: is like the environment where code runs includes the variables
Speaker 2: scope this value. When a function is called, a new
Speaker 2: context is created. The scope chain, as we said, is
Speaker 2: how JS looks up variables by checking the current scope,
Speaker 2: then outer scopes.
Speaker 1: Enclosure.
Speaker 2: Closure is when a function remembers its lexical scope the
Speaker 2: variables from the environment where it was created, even when
Speaker 2: the function is executed outside that original scope, so an.
Speaker 1: Inner function can still access the outer function's variables. After
Speaker 1: the outer function has finished running.
Speaker 2: Exactly, the inner function closes over the outer scope's variables.
Speaker 2: This enables powerful patterns like data privacy, creating private like
Speaker 2: variables and functions that maintain state between calls.
Speaker 1: Closures are powerful. Okay, asynchronous JavaScript promises a better way
Speaker 1: than callbacks.
Speaker 2: Oh, definitely. Promises represent the eventual result of an ACINC operation.
Speaker 2: A promise object is a placeholder for a future value.
Speaker 2: It starts an appending state, and then it eventually settles
Speaker 2: into either a fulfilled state if the operation succeeded with
Speaker 2: the result value, or a rejected state if it failed
Speaker 2: with an error or reason.
Speaker 1: How do we create them?
Speaker 2: Usually using new promise resolve reject inside that function the executor,
Speaker 2: you perform your ACNC operation. When it's done, you call
Speaker 2: resolve value on success or reject error on failure.
Speaker 1: And how do we use the result or handle the error?
Speaker 3: Then and dot catch Precisely.
Speaker 2: You chain that on fulfilled unrejected onto a promise. Unfulfilled
Speaker 2: runs if it resolves getting the value, on rejected runs
Speaker 2: if it rejects getting the error catch unrejected is just
Speaker 2: shorthand for that null unrejected, focusing.
Speaker 1: Only on errors, and then returns another promise. That's how
Speaker 1: chaining works.
Speaker 2: Yes, each then or dot catch returns a new promise,
Speaker 2: allowing you to chain asynchronous steps together in a much
Speaker 2: cleaner way than nested callbacks callback hell. The handlers in
Speaker 2: then are also non reentrant. They won't be called immediately
Speaker 2: if the promise is already settled, they get cued.
Speaker 1: Very elegant. What about managing multiple promises? Promise dot all
Speaker 1: promise dot race.
Speaker 2: Yeah, useful static methods. Promise dot all promises waits for
Speaker 2: all promises in the input iterable to fulfill. If any
Speaker 2: reject it rejects immediately, it resolves with an array of
Speaker 2: the results.
Speaker 1: Okay, waits for all successes.
Speaker 2: Promise dot all settled promises waits for all promises to settle,
Speaker 2: either fulfill or reject it always fulfills, returning an array
Speaker 2: of objects describing the outcome of each promise.
Speaker 1: Safer if you need to know about all outcomes, even failures.
Speaker 2: Right. Promise dot race promises settles as soon as the
Speaker 2: first promise in the terable settles either fulfills or rejects,
Speaker 2: It takes on the outcome of that first one, a
Speaker 2: race to the finish and promise. Any promises resolves as
Speaker 2: soon as the first promise fulfills. It only rejects if
Speaker 2: all promises reject and it rejects with a special aggregate error.
Speaker 1: Useful if you just need one success out of many possibilities.
Speaker 1: What about serial promise composition executing promises one after another.
Speaker 2: That's often just standard dend chaining. You ensure one acinc
Speaker 2: operation completes before starting the next, often passing the result
Speaker 2: along a synca weight makes this look even more sequential.
Speaker 1: Speaking of timing the micro test queue, how does that
Speaker 1: affect promises?
Speaker 2: Promise dot then and dot catch callbacks don't run immediately
Speaker 2: when a promise settles, its handlers are scheduled to run
Speaker 2: in the micro task queue. This queue has higher priority
Speaker 2: than the main macro task queue, which handles things like
Speaker 2: set time out or user events.
Speaker 1: So promise callbacks run very soon after the current synchronous
Speaker 1: code finishes, but before the next timer.
Speaker 2: Or event exactly. It ensures a predictable execution order for
Speaker 2: promise reactions happening after the current task but before the
Speaker 2: browser does other things like rendering got it?
Speaker 1: And why is it crucial to avoid unhandled rejection?
Speaker 2: If a promise rejects and nothing catches that rejection you
Speaker 2: dot catch or unrejected handler in a dot catch, then
Speaker 2: it's an unhandled rejection. Modern environments will log errors to
Speaker 2: the console, and in some cases, like no JS, it
Speaker 2: might even terminate the process. You always want to handle
Speaker 2: potential errors to keep your application stable.
Speaker 1: I always have a dot catch somewhere down the chain.
Speaker 1: What about promise extensions like cancelation or progress? Are those standard?
Speaker 2: No, they aren't part of the official trauma specification. Cancelation
Speaker 2: the ability to stop an ongoing async operation tied to
Speaker 2: a promise, and progress notifications getting updates before it finishes
Speaker 2: are things you usually implement with libraries or custom patterns,
Speaker 2: often using mechanisms like the abort controller, which we'll touch
Speaker 2: on with fetch.
Speaker 1: Okay, so not built in now? Asinc and a weight
Speaker 1: this is syntactic sugar on top of promises right makes
Speaker 1: ACYNC code look synchronous exactly.
Speaker 2: You mark a function with the acinc keyword inside that function,
Speaker 2: you can use the awake word before a promise.
Speaker 1: And what does a weight do?
Speaker 2: It? Pauses the execution of the acing function at that
Speaker 2: point until the promise you're awaiting settles.
Speaker 1: Pauses the function, not the whole browser, just.
Speaker 2: The acing function. It asynchronously waits if the promise fulfills
Speaker 2: a weight, returns is the result value. If the promise
Speaker 2: rejects a weight, throws that rejection reason as an error.
Speaker 1: So you can use try dot catch around awake.
Speaker 2: Yes, that's the beauty. You can use standard try dot
Speaker 2: catch dot finally blocks for error handling. Just like synchronous code,
Speaker 2: an ACYNC function itself implicitly returns a promise that resolves
Speaker 2: with the function's return value or rejects if an uncaught
Speaker 2: error occurs inside it.
Speaker 1: That sounds much easier to read and write than loss
Speaker 1: of dot chains. Where can we use.
Speaker 2: A weight only directly inside an acing function? You can't
Speaker 2: just sprinkle a weight anywhere In regular synchronous code. You
Speaker 2: might use an immediately invoked acing function expression iiaff e
Speaker 2: like acink a weight to use a weight at the
Speaker 2: top level of a module if needed.
Speaker 1: Gotcha. So for serial execution, instead of then, we just await, await, await.
Speaker 2: Pretty much concer result one will await step one const
Speaker 2: result two. Await step two Result one looks very linear
Speaker 2: and clear.
Speaker 1: Fantastic. What about running things in parallel with they sink away,
Speaker 1: but handling errors safely rejection safe parallelization.
Speaker 2: Right if you just await promise dot all P one,
Speaker 2: P two, p three, the whole thing rejects if any
Speaker 2: of them reject. If you want to get results even
Speaker 2: if some fail, you could await promise dot all settled,
Speaker 2: which always results and tells you the status of each.
Speaker 2: Or you could map your promises and handle errors individually,
Speaker 2: perhaps using a weight p dot catch EP do or
Speaker 2: within the mapping or wrapping awights in individual try dot
Speaker 2: catch blocks if doing them sequentially.
Speaker 1: So options exist to manage parallel tasks gracefully even with failures. Great.
Speaker 1: Let's shift to the browser environment itself, the browser object
Speaker 1: model BOM. What does this cover?
Speaker 2: The BOMB represents the browser window and its features, distinct
Speaker 2: from the HTML document content, which is the DOM. The
Speaker 2: core object is which is the global object.
Speaker 1: In browsers, and we can find out where the user.
Speaker 2: Has scrolled YEP, window dot scroll x or paychecks offset
Speaker 2: and window dust scrolly or pageops. I could give you
Speaker 2: the horizontal and vertical scroll positions in pixels.
Speaker 1: What about opening new windows? Window dot open pop up
Speaker 1: blockers are a thing.
Speaker 2: Though they are Window dot open ural name features tries
Speaker 2: to open a new window or tab, but browsers usually
Speaker 2: block this unless it happens right after a direct user
Speaker 2: action like a click. You must check the return value
Speaker 2: of window dot open. If it's null, the pop up
Speaker 2: was likely blocked.
Speaker 1: Good check. Timers set time out and set interval. How
Speaker 1: do they work with the single thread.
Speaker 2: Set time out callback delay runs the callback once after
Speaker 2: at least delay milliseconds. Set interval runs the callback repeatedly
Speaker 2: every interval milliseconds. Because JavaScript is single threaded and uses
Speaker 2: an event loop, the delay is a minimum. The callback
Speaker 2: actually runs only when the main thread is free after
Speaker 2: the delay is passed. Set time out returns an ID
Speaker 2: you can pass to clear timeout to cancel it. Set
Speaker 2: interval returns an id for clear.
Speaker 1: Interval minimum delay not exact. Dot IT navigation, location and
Speaker 1: history oobjects.
Speaker 2: Location gives info about the current url location dot href, location,
Speaker 2: dot path name, location, dot searchlocation, dot hash, et cetera,
Speaker 2: and lets you navigate by assigning to location dot h
Speaker 2: ref or using methods like location dot sign. You all
Speaker 2: navigates and ads to history location dot replace, heural navigates
Speaker 2: but replaces current history entry and location dot reload and
Speaker 2: history history lets you move through the user session history
Speaker 2: dot backstory, dot forward history dot go in where N
Speaker 2: can be positive or negative. History dot link tells you
Speaker 2: how many items are in.
Speaker 1: The history stack, useful for custom back forward buttons. What
Speaker 1: about the navigator object? What browserinfo does it?
Speaker 2: Whole navigator gives you browsersniffinginfo, though user agent is notoriously unreliable.
Speaker 2: Better info comes from properties like Navigator dot Language, Navigator
Speaker 2: dot platform. Crucially, it has Navigator dot online booley in
Speaker 2: for connection status and events online offline. The Navigator Dot
Speaker 2: Connection object Network Information API provides more tas like connection type,
Speaker 2: effective type, speed, downlink rtt OTT and a change event.
Speaker 1: Network INFOS sounds handy, and the screen object.
Speaker 2: Screen tells you about the users display screen dot width,
Speaker 2: screen dot height, screen dot availwith excluding os interfaces, screen
Speaker 2: dot color depth, screen dotpixel depth, screen dot orientation.
Speaker 1: Good for responsive design decisions. Can we control audio and
Speaker 1: video via.
Speaker 2: The bo yes HTML media elements Audio video have a
Speaker 2: rich JavaScript API. You can play, pause, control volume, get duration,
Speaker 2: get and set current time. They fire lots of events
Speaker 2: play pause and a time update, canplay error, etc. You
Speaker 2: can use canplay type mime type to check codec support.
Speaker 1: Full media control. The URL object better than string manipulation
Speaker 1: much better.
Speaker 2: New url string parses a URL string into an object
Speaker 2: with properties for easy access to protocol, host name, path, names, search, hash,
Speaker 2: et cetera. It also has search perms and objects specifically
Speaker 2: for manipulating query string parameters easily.
Speaker 1: Nice and performance monitoring dot performance dot.
Speaker 2: Now Yeah, the performance API is key for measuring speed.
Speaker 2: Performance dot now gives high resolution timestamps. You can create
Speaker 2: name markers with performance dot mark start task, measure durations
Speaker 2: between marks with performance dot measure task duration, start task
Speaker 2: and task and retrieve these entries with performance dot get entries.
Speaker 2: The Navigation Timing API Performance Navigation Timing gives detailed timings
Speaker 2: for pageload.
Speaker 1: Stages, essential for optimization. Okay, let's switch to the Document
Speaker 1: Object Model DOM. This is about the page content itself,
Speaker 1: the HTML structure exactly.
Speaker 2: The DOM represents the HTML document as a tree of nodes, elements, text, comments, attributes.
Speaker 2: The document object is.
Speaker 1: The root, and nodes have properties and relationships.
Speaker 2: Yep. Node type tells you what it is, element, texts
Speaker 2: et cetera. Note name gives the tag name for elements.
Speaker 2: Node value gives the content for text nodes. Relationships like
Speaker 2: parent node child nodes first child, last child, next sibling,
Speaker 2: previous sibling. Let you navigate this tree structure.
Speaker 1: How do we grab specific elements? To start with? Element
Speaker 1: by id.
Speaker 2: That's a classic for unique ideas. Get elements by tag
Speaker 2: name gets a live HTML collection of elements by tag.
Speaker 2: Get elements by name gets a live nodalist by the
Speaker 2: name attribute. There's also document dot, document element, the h
Speaker 2: nolande and document dot body.
Speaker 1: Right different ways to get elements. How do we change
Speaker 1: things add or remove nodes.
Speaker 2: You can document dot create element tag name and document
Speaker 2: dot create text node, then use parentode dot a pen
Speaker 2: child new node to add it at the end, or
Speaker 2: parentnode dot insert before new node, reference node to insert
Speaker 2: before another node. Use parentnode dot remove child node to
Speaker 2: remove and parentode dot replace child new node old node
Speaker 2: to replace document dot create. Document fragment is useful for
Speaker 2: building a chunk of dom off screen before appending it
Speaker 2: all at once for better performance.
Speaker 1: Document fragments for batch updates. Good tip what about using
Speaker 1: CSS selectors dot query selector yes.
Speaker 2: Query selector selector returns the first matching element, and query
Speaker 2: selectora selector returns a static nodalist of all matching elements.
Speaker 2: These are incredibly powerful on it available on document fragments
Speaker 2: and individual elements, much more flexible than the older get
Speaker 2: elements by methods and.
Speaker 1: Get elements by class name was added later.
Speaker 2: Right get elements by class named it gets a live
Speaker 2: HTML collection based on class names, also useful.
Speaker 1: Okay, we have the element, how do we change its content?
Speaker 1: Inner HTML, text content, etc.
Speaker 2: Inner HTML gets or sets the HTML content inside an element.
Speaker 2: Setting it parses the string as HTML. Outer HTML includes
Speaker 2: the element itself. Text content gets or sets only the
Speaker 2: text content, ignoring HTML tags and encoding entities when setting.
Speaker 2: Intertext is similar to text content, but is aware of
Speaker 2: CSS rendering. It omits hidden text and also codes entities differently.
Speaker 2: Be careful with inner HTML as it can be slow
Speaker 2: and requires reattaching event listeners to recreated elements.
Speaker 1: Good point about listeners. How do we change styles? Dot element, dot.
Speaker 2: Style, element dot style accesses the elements inline style attribute.
Speaker 2: You set properties like element dot style, dot background color
Speaker 2: red to get the actual computed style including styles from
Speaker 2: CSS rules. Use window dot get computed style element. You
Speaker 2: can also access style sheets via document dot style sheets
Speaker 2: and manipulate CSS rules, CSS rule CSS style directly, though
Speaker 2: that's less common.
Speaker 1: Inline versus computed style makes sense. What about element size
Speaker 1: and position offset client scroll.
Speaker 2: Dimensions to give different measurements offset offset offset with offset
Speaker 2: left offset top includes borders and padding and position relative
Speaker 2: to the offset parent client client height client with is
Speaker 2: the inner size, padding included, border, scroll bars excluded, scroll
Speaker 2: height scroll width is the total size of the scrollable content,
Speaker 2: while scroll left scroll top is the current scroll position
Speaker 2: within the element. Client dimensions are read.
Speaker 1: Only different numbers for different use cases. What if we
Speaker 1: need more advanced dom traversal no iterator and tree walker.
Speaker 2: These are for more complex iteration needs. They let you
Speaker 2: traverse a subtree of the dome, optionally filtering nodes based
Speaker 2: on criteria you define, especially tree walker, which has a
Speaker 2: filter function. They give you finer control than simple loops
Speaker 2: or recursive functions. Sometimes true walker keeps track of the
Speaker 2: current node.
Speaker 1: Specialized tools and DOM ranges selecting parts of the document.
Speaker 2: Yeah. Document dot creator range creates a range object representing
Speaker 2: a contiguous section of the document, you can set its
Speaker 2: start and end points. Set start, set end. Then you
Speaker 2: can manipulate that selected content. Delete contents, extract contents into
Speaker 2: a document fragment, clone contents, and certain nodes around contents.
Speaker 2: Useful for things like text editors or highlighting.
Speaker 1: Powerful selection manipulation. Lastly, for DOM intersection observer and resize
Speaker 1: observer modern ways to react to visibility and size changes.
Speaker 2: Exactly intersection observer new intersection Observer callback efficiently tells you
Speaker 2: when an element intersects with the viewport or another development.
Speaker 2: Great for lazy loading images, infinite scroll triggering animations on
Speaker 2: view resize observer new resize observer callback efficiently tells you
Speaker 2: when an element size changes, much better than pulling off
Speaker 2: stwidth constantly. Both are asynchronous in performance focus.
Speaker 1: Do you sound like essential modern tools? Okay? Events making
Speaker 1: pages interactive? DON level zero Level two.
Speaker 2: DOM level zero is the old way. Element dot on
Speaker 2: click will function simple, but only one handler per event
Speaker 2: type and only runs in the bubbling phase. This inside
Speaker 2: is the element removed by setting to NOL and.
Speaker 1: Level two the modern way.
Speaker 2: DOM level two introduced element dot ad event listener type listener,
Speaker 2: use capture This is the standard. You can add multiple listeners.
Speaker 2: The third argument use capture boolli in or options object
Speaker 2: lets you choose whether to listen during the capturing phase
Speaker 2: down the tree or the bubbling phase up the tree.
Speaker 2: The default you remove listeners with remove event listener, needing
Speaker 2: the exact same arguments.
Speaker 1: AD event listener is the way to go. When an
Speaker 1: event happens, we get an event object. What's in it?
Speaker 2: Lots of useful stuff? Event dot type like click, event
Speaker 2: dot target, the element the event originated on, event dot
Speaker 2: current target the element the listener is attached to. Event
Speaker 2: dot prevent default, stop to full browseractions, event dot stop
Speaker 2: propagation to stop bubbling cap Also details like coordinates, client x, clinyy, modifier, keys, feature,
Speaker 2: l key, old key, event phase, et cetera. Properties vary
Speaker 2: a bit by event type.
Speaker 1: Lots of context. What are some common event types we handle?
Speaker 2: Oh tons load for window, images of scripts, unload, window focused,
Speaker 2: blur or form fields, window, mouse, events, click, TVL click, mousedown,
Speaker 2: mouse oup, mouse over, mouse out, mouse enter, mouse leave wheel,
Speaker 2: keyboard events, key down, keep us key at form events, submit,
Speaker 2: change input, clipboard events, touch events, many more.
Speaker 1: A whole universe of events. Can we trigger events ourselves
Speaker 1: in code simulate them?
Speaker 2: Yes, it's a bit verbose. Use document dot create event
Speaker 2: like mouse events, then initialize it with details using a
Speaker 2: method like event dot inn at mouse event or newer
Speaker 2: constructors like new mouse event or new custom event. Finally,
Speaker 2: dispatch it on an element using element dot dispatch.
Speaker 1: Event create initialized dispatch guid. For smooth animations, request animation frame.
Speaker 3: How did that work?
Speaker 2: Instead of timers like set timeout, use request animation frame callback.
Speaker 2: The brow sol so calls your callback function just before
Speaker 2: it's about to repaint the screen. The sinks your animation
Speaker 2: logic perfectly with the browser's rendering cycle, making animations much
Speaker 2: smoother and more efficient. It passes a high resolution timestamp
Speaker 2: to the callback. You call it recursively within the callback
Speaker 2: to continue the animation loop. Use cancel animation frame to
Speaker 2: stop it.
Speaker 1: Perfect for performance animations.
Speaker 3: Okay.
Speaker 1: HTML five APIs canvas for drawing.
Speaker 2: Yes, the canvas element gives you a drawing surface. You
Speaker 2: get the two D context with canvas dot get context
Speaker 2: two D. This context object has tons of methods for
Speaker 2: drawing shapes, rectangles, lines, arcs, curves with begin path moved
Speaker 2: to a line to arc et cetera. Filling, fil style, fill, stroking,
Speaker 2: stroke style, stroke struck, drawing text on fill text, applying transformations, translate, rotate, scale,
Speaker 2: drawing images, dramage, adding shadows, gradients, patterns, clipping, compositing, global
Speaker 2: composite operation and even pixel manipulation. Get image data, put
Speaker 2: image data wow.
Speaker 1: Full two D graphics engine and WebGL for three D
Speaker 1: also on canvas.
Speaker 2: YEP, canvas, dot get context, WEBNIL or webjail two. It's
Speaker 2: based on OPENNGLS, providing low level access to the GPU
Speaker 2: for hardware accelerated two D and three D graphics. You
Speaker 2: define geometry in buffers, write vertex and fragment shaders in GLSL,
Speaker 2: link them into programs, past data via attributes and uniforms,
Speaker 2: and then issue draw calls, drawrays, draw elements. Much more
Speaker 2: complex than two D canvas, but incredibly powerful.
Speaker 1: High performance three D on the web. Forms got upgrades
Speaker 1: in HTML five to two, new types, validation, big.
Speaker 2: Time, new input types like email, earle date number with
Speaker 2: built in UI and validation attributes like required pattern min max,
Speaker 2: the constraint validation API element dot validity, element dot check, validity,
Speaker 2: element dot set custom validity, the invalid event programmatic submission
Speaker 2: with form dot submit. Fans like input change, clipboard events, copycut, paste,
Speaker 2: ridge text editing via the content editor attribute and document
Speaker 2: dot exec command, though the latter is getting replaced by
Speaker 2: newer APIs. So like boxes also have a good API
Speaker 2: from manipulating options.
Speaker 1: Forms are much smarter now, Okay, shifting to general JavaScript
Speaker 1: APIs atomics and shared airy buffer for worker community.
Speaker 2: Yes. This enables shared memory between multiple web workers and
Speaker 2: the main thread shared The rebuffer is a buffer whose
Speaker 2: underlying memory can be accessed by multiple threads simultaneously. Atomics
Speaker 2: provide special functions atomics, dot ad atomics, dot load atomics,
Speaker 2: dot store atomics, dot weight atomics, dot notify, et cetera
Speaker 2: that perform operations on that shared memory in an atomic way,
Speaker 2: preventing race conditions and ensuring operations aren't interrupted. Very advanced,
Speaker 2: high performance stuff for parallel computation.
Speaker 1: Shared memory powerful, but needs care. Clipboard API a better
Speaker 1: way to copy paste.
Speaker 2: Navigator dot Clipboard provides an async promise based API right
Speaker 2: text read text write for more complex data like images
Speaker 2: using clipboard item objects read. It's generally more secure as
Speaker 2: it often requires user permission, especially for reading. Also integrates
Speaker 2: with the copycut.
Speaker 1: Paste events, asynchronous and permission based sounds. Safer cross context
Speaker 1: messaging post message.
Speaker 2: Window dot post message message target origin allows safe communication
Speaker 2: between different windows I frame are workers, even if they're
Speaker 2: from different origins. The sender specifies the target origin for security,
Speaker 2: The receiver listens for the message, event checks event dot
Speaker 2: origin to verify the sender, and accesses the data via
Speaker 2: event dot data crucial for secure cross domain communication and
Speaker 2: things like embedded widgets.
Speaker 1: It's your window to Window Talk encoding API. Text encoder,
Speaker 1: text decoder.
Speaker 2: Simple but essential. Textingcoder converts a JavaScript string into a
Speaker 2: U and data array of UTFA bytes by default. Text
Speaker 2: cooder decoder, dot decode uit data array converts an array
Speaker 2: of bytes back into a JavaScript string. Handling different encodings
Speaker 2: useful when dealing with binary data from files or network
Speaker 2: requests that represents.
Speaker 1: Text, handling texting codings properly. Blob and file APIs for
Speaker 1: raw data and filed.
Speaker 2: Blob represents immutable raw data like a junk of binary data.
Speaker 2: File inherits from blob and adds file specific metadata like name, size, type,
Speaker 2: last modified usually comes from an input type file or
Speaker 2: drag and drop file reader reads the contents of blobs
Speaker 2: files asynchronously to text read as air buffer read as
Speaker 2: dator RRL. With events like onload on air. You can
Speaker 2: create object URLs url dot create creature l blob for
Speaker 2: referencing blobs files directly in things like MMG tags, but
Speaker 2: remember to URL revoke objet url when done.
Speaker 1: Comprehensive file handling. Full screen API making things take over
Speaker 1: the screen.
Speaker 2: Element dot request full screen ask the browser to make
Speaker 2: an element full screen requires user gesture usually document dot
Speaker 2: a inst full screen to leave document dot full screen.
Speaker 2: Element tells you what's full screen full screen change event
Speaker 2: fires when state changes. Good for videos, games, presentations.
Speaker 1: Immersive experiences. Geolocation API finding the user's.
Speaker 2: Location navigator dot geolocation methods get current positions success ab
Speaker 2: air CB options and watch position success CB air CB
Speaker 2: options needs user permission. Success callback gets a position object
Speaker 2: with chords latitude, longitude accuracy. Error callback gets position aer
Speaker 2: codes for permission denied, unavailable, timeout, use eaht TPS. Be
Speaker 2: mindful of privacy.
Speaker 1: Permission and privacy first. Other device APIs orientation network info.
Speaker 2: Yeah, we mentioned navigator dot connection for network details. Device
Speaker 2: orientation events. Device orientation, give alpha beta gamma values for
Speaker 2: physical orientation if hardware supported. Others like battery API are
Speaker 2: mostly deprecated. Provides context about the device environment.
Speaker 1: Good context fetch API the modern way for network.
Speaker 2: Requests absolutely fetch EARL options is the standard. Returns a
Speaker 2: promise that resolves to a response object. Options object controls
Speaker 2: method header's, body, credentials, cash, mode, et CETERA response object
Speaker 2: has methods to read the body response dot jason, response
Speaker 2: dot text, response dot, blob, response dot orra buffer. You
Speaker 2: check response dot OK or response dot status for success.
Speaker 2: Handle's cores via options and server headers. Integrates with request
Speaker 2: header's objects can be aborted using a board controller and
Speaker 2: a bort signal. Can work with dreams. Integrates with the cache.
Speaker 2: API caches for service workers. Far superior to XMLHTTP request.
Speaker 1: Fetch sounds like the complete package. Web sockets for real
Speaker 1: time communication.
Speaker 2: New web socket are established as a persistent two way connection.
Speaker 2: Ws dot, WS or WSS use eventhandlers dot on open
Speaker 2: on message gets data in event dot data on air
Speaker 2: on clothes send data with socket dot, send doses socket
Speaker 2: dot close. Great for chat, live updates, multiplayer games. Doesn't
Speaker 2: use ad event listener style. You assigned handlers.
Speaker 1: Directly persistent connections, web storage, local storage, session storage.
Speaker 2: Simple key value storage. In the browser. Local storage persists
Speaker 2: across browser sessions. Same origin. Session storage allows only for
Speaker 2: the current tab. Windows session both have set item key value,
Speaker 2: remove item key clear length limits around five to ten
Speaker 2: mil us storage event fires and other tabs. When storage
Speaker 2: changes stores values is strings.
Speaker 3: Simple key value stores.
Speaker 1: Then for more complex data, index dB.
Speaker 2: Yes INDEXTB is a full transactional NOSEQL database in the browser,
Speaker 2: stores complex JavaScript objects, files, blobs, asynchronous API. You work
Speaker 2: with databases object stores like tables, indexes for query transactions,
Speaker 2: cursors for iteration. Open with index dB open name version,
Speaker 2: schema changes happen in the unupgrade needed event powerful for
Speaker 2: offline apps and large data sets.
Speaker 1: A real database in the browser. Okay. Modules organizing code
Speaker 1: ES modules versus the old module pattern.
Speaker 2: Module pattern used iiv's enclosures to simulate modules. Es, modules,
Speaker 2: import exports, script type module are the native standard, much
Speaker 2: cleaner syntax, static analysis benefits, better dependency management. Named exports
Speaker 2: export x inport x, default exports, export default y, import y,
Speaker 2: dynamic import phrase incloading import maps for controlling resolution. The
Speaker 2: modern standard.
Speaker 1: Native modules are the way forward. Web workers background threads yes.
Speaker 2: Run jas off the main UI thread to avoid blocking
Speaker 2: dedicated workers. New worker for a single script, shared workers,
Speaker 2: new shared worker accessible by multiple scripts same origin. Service
Speaker 2: workers act as network proxies for offline support, push notifications,
Speaker 2: et cetera. Communicate via post message and on message. Data
Speaker 2: is copied, structured, cloning, or transfer transferable like a ray buffer.
Speaker 2: Each worker type has different scope in life cycle.
Speaker 1: Essential for performance parallelism in the browser. Important error handling
Speaker 1: and debugging stayingsane.
Speaker 2: Use try, dot, catch dot finally, throw errors with throw
Speaker 2: new error or specific types type er, et cetera. Handle
Speaker 2: global errors with window dot one, air, use browserdeb tools extensively,
Speaker 2: console debugger breakpoints, stepping, network panel, static analysis linters. Typescript
Speaker 2: helps catch errors early assertions can help during development. Robust
Speaker 2: error handling is key.
Speaker 1: Good practices are essential. Finally, json stringify.
Speaker 2: And parse Gson does stringify value. Replacer space converts a
Speaker 2: JS value to a JSON string. Json Dot parse text
Speaker 2: Reviver parses a Jason string back into a JS value.
Speaker 2: Replacer and reviver functions allow customization during serialization de serialization.
Speaker 2: Space argument pritifies the string output ubiquitous for data exchange,
Speaker 2: especially with apisvia.
Speaker 1: Fetch perfect, and we covered fetch for the actual sending earlier.
Speaker 2: Yep fetches how you typically get that Jason data from
Speaker 2: a server?
Speaker 1: Wo Okay. That was a seriously deep dive into JavaScript
Speaker 1: and the web platform. It's a massive ecosystem.
Speaker 2: It really is so many layers, from the core language
Speaker 2: features to these incredibly powerful browser APIs, and they all interconnect.
Speaker 1: Yeah, hopefully this gives you, our listener, a really solid
Speaker 1: map of the territory, a framework for understanding how all
Speaker 1: these pieces fit together in modern web development.
Speaker 2: It's definitely a foundation you can build on whether you're
Speaker 2: focusing on say React or view or maybe no JS
Speaker 2: on the back end, or getting deep into specific APIs
Speaker 2: like WebGL or web RTC.
Speaker 1: And it just keeps changing, doesn't it. JavaScript and the
Speaker 1: web platform are constantly evolving.
Speaker 2: They really are. Which leads to a final thought, maybe,
Speaker 2: given everything we've touched on today, this huge landscape, what's
Speaker 2: the one area of JavaScript or the web platform that
Speaker 2: really sparks your curiosity right now?
Speaker 1: That's a great question for everyone listening to think about,
Speaker 1: where do you want to explore next? Keep learning, keep building.
Speaker 1: Thanks for joining us on the deep Dive