JSJ 474: Things JavaScript Developers Should Know, Part 1
Having done a three-part series on the things JavaScript developers MUST know, Dan now leads a panel discussion on the things that JavaScript developers SHOULD know. These are things that devs can get by without knowing, but that will improve their abilities if they do know and understand. Subjects covered include: passing functions args by value vs by reference, sparse arrays, property descriptors, event capture, and more.
Show Notes
Having done a three-part series on the things JavaScript developers MUST know, Dan now leads a panel discussion on the things that JavaScript developers SHOULD know. These are things that devs can get by without knowing, but that will improve their abilities if they do know and understand. Subjects covered include: passing functions args by value vs by reference, sparse arrays, property descriptors, event capture, and more.
Panel
- Aimee Knight
- AJ O'Neal
- Dan Shappir
- Steve Edwards
Sponsors
Links
Picks
- Aimee- Load balancing and its different types
- AJ- Ethan Garofolo - YouTube
- AJ- XMission
- AJ- LuaJIT
- AJ- rclone | webinstall.dev
- AJ- USB-C Cozy for USB C Adapters
- AJ- xkcd: Security
- Dan- Tel Aviv weather
- Dan- Axel Rauschmayer
- Dan- 2ality – JavaScript and more
- Dan- JavaScript for impatient programmers (ES2021 edition)
Sponsored By:
- Dexecure: Exclusive Offer For Javascript Jabber Listeners Promo Code: DEXJSJAB
Transcript
AJ_O’NEAL: Hello, hello, and welcome back to the infamous JavaScript Jabber, where we take low jabs and high jabs and jab. All right, I lost it. Anyway, we've got Dan Shappir being our guest today to talk to us about the things that weren't important enough to cover the other three or four times, the things that JavaScript developers should know, but maybe or maybe not must know. I'm your host AJ O'Neill, yo, yo, yo, coming at you live from the gray skies of Pleasant Grove. We also have with us Amy Knight.
AIMEE_KNIGHT: I'm from Nashville.
AJ_O’NEAL: And Dan, who needs no introduction, why don't you kick us off?
DAN_SHAPPIR: Yeah. So you put it quite eloquently, you know, after we finished those three episodes on the things that JavaScript developers must know, because as it turns out, there are a lot of things that JavaScript developers actually apparently need to know, it occurred to me that there are a whole bunch of additional things that are really useful to know, but are not necessarily in the must know category. That means that you know, you can get by without actually knowing them. But certainly beneficial if you do. And I tried to put a list of these and and yeah, that's the list that you guys have in front of you. So this time instead of reading it through, I think we'll just do it, you know, as a surprise, just an item by item. What do you think of that?
AJ_O’NEAL: Let's do it.
This episode is brought to you by Dexecure, a company that helps developers make websites load faster automatically. With Dexecure, you no longer need to constantly chase new compression techniques. Let them do the work for you and focus on what you love doing, building products and features. Not only is Dexecure easy to integrate, it makes your website 40% faster, increases website traffic, and better yet, your website running faster than your competitors. Visit dexecure.com slash JSJabber to learn more about how their products work.
DAN_SHAPPIR: Okay, so the first one I had on my list was actually prompted by a Twitter meme that kind of resurfaces every couple of weeks. It's this animated GIF that shows passing parameters into a function and comparing passing by value to passing by reference. And on the left hand side, I think you have, in both cases, you have a cup of coffee, empty cup of coffee being passed into a function. And then inside the function, the cup of coffee is actually filled. And then in, on the one side, in the pass-by-value side, the cup of coffee that's outside the function stays empty while on the pass by reference, the cup of coffee gets filled as well. And this, and this is always tagged in the context of JavaScript and, uh, coding newbie and 100 days of code. And I find it somewhat unfortunate because it really shows a lack of understanding, I would say, about how parameters actually get passed into functions in JavaScript.
AIMEE_KNIGHT: I also feel like this should have probably been admittedly moved to one of our earlier episodes because this is actually really important and the source of a lot of bugs.
AJ_O’NEAL: I know people that have been programming in JavaScript for like 10 years and don't understand the difference between the reference and value stuff. And it pops up as bugs in their code. And they're like, I don't remember why this happens. I just have to do it the other way. And I don't know why.
AIMEE_KNIGHT: It's also been a pretty popular, like whenever you have like trick interview questions, this is a pretty popular one.
AJ_O’NEAL: There's nothing that's a trick about this.
AIMEE_KNIGHT: No, it's not tricky about it. However, yeah, it helps people like understand like, do you know the JavaScript language or anyways, carry on Dan.
DAN_SHAPPIR: Well, so in this context, JavaScript is kind of like its original namesake, which is Java, in that in JavaScript, you really only pass parameters by value. There is no pass by reference in JavaScript. Now this is really confusing to a lot of people because they say, hey, wait a minute, when I pass an object into a function, I pass the reference to that object. And that's correct. But what actually happens is that you pass the reference. By value, that means the parameter that you pass in is not the object itself, it's the reference to that object. And that reference gets passed in by value. What does that mean? It means that if inside, let's say the external variable is called A and the parameter's name or the argument name and the function is called B, so you pass A into B. If you then modify B to reference another object, that does not impact the A reference. A continues to reference the original object. If you actually were using a programming language which does support pass by reference, programming language like C++ or C sharp or VB.
AJ_O’NEAL: Rust or Go.
DAN_SHAPPIR: Yeah, or Fortran, if we go really old school, then you could actually specify that you're passing the reference itself by reference in fact, kind of making B and A aliases to the same variable. And then if you cause B to reference some other object, then A would also reference that same object. So again, in JavaScript, whenever you're passing a variable, it's always by value. It's as if, again, going back to my example, with A on the outside and B on the inside, it's as if you did B equals A. And from that point on, these are two separate and distinct variables that, again, might reference the same object. And if they do reference the same object, then when one of them is used to modify the object because it's the same object, the other one references that same object and gets that same modification.
AIMEE_KNIGHT: I'll say too, like one thing that I've seen happen as like a common side effect of this, bug wise, especially with like more newer JavaScript developers who don't know how it works is changing the order of execution of different things within, let's say your file can suddenly have like different effects because of passing by reference. So if you have something like online five that's doing something and you decide to move that down later on in the file, suddenly what you're expecting to be there isn't necessarily there.
DAN_SHAPPIR: Yeah, it's indeed the source of a lot of bugs. And again, the sense that when you're passing in an object, because you're not passing in the actual object, you're passing in a reference to that object, it doesn't get copied over. And when you're making changes to that object, you're influencing code that's outside your function. So there is effectively a side effect here. It's not immutable. And I've seen a lot of cases in which functions modify objects that they don't really own. So they get some sort of, let's say, an options object as a parameter, and then for convenience sake they calculate something and put it in a property on that object. And they disregard the fact that maybe that external code that invoked them, you know, assumes that the object has a particular structure or values in its fields and all of a sudden the function itself has modified it unexpectedly. And in that type of a scenario, you probably will want to clone that object inside that function. And one nice thing about ES6, quote unquote, or ES 2020 or 2021 or whatever, is that now with the spread operator on objects, it's actually fairly easy to do a shallow clone of an object. So if you've got an object, let's say X, you can do just open curly brackets, dot, dot, dot X, close curly brackets, and you've got a shallow copy of that X object. And this way you can clone that object inside of your function, and then do with it whatever you want.
AJ_O’NEAL: That's not any different than object on a sign, right? Is this syntax sugar?
DAN_SHAPPIR: Yeah, well, there's also a semantic difference because you're creating an object rather than modifying one, but for practical purposes, it's essentially identical. Any comments on this before we move on?
AIMEE_KNIGHT: I don't think we're very good there.
DAN_SHAPPIR: I actually have a comment myself, and something that's kind of related to that is that people are often confused by a const reference to an object then modifying the object that it's referenced.
AIMEE_KNIGHT: Oh, yeah, this is, this is.
DAN_SHAPPIR: Yeah, this is this is again, it's the same sort of thing, because again, again, the const here is the reference, the reference cannot be changed, not the object which is being referenced. That object is wholly mutable. If you want the object itself to be immutable, you need to do something like an object freeze on it. So yeah, so it's kind of related and certainly confusing to a lot of people when, when they see constitutes in this way. Some people even consider it a sort of a bug in the language. I think.
AJ_O’NEAL: One other thing in regards to weirdness is that happen with functions is we didn't talk about the arguments, special. I don't know what we call it. Keyword, I guess variable property. I don't, I don't know what it's, it's a thing. Yeah, it's not really an object. I mean, not a JavaScript object.
DAN_SHAPPIR: I would say it's dead to me.
AJ_O’NEAL: Well, I think it's just important to know. So there's an arguments thing in the same way that this exists inside of a function. Arguments also exist inside of a function. But arguments is neither an object nor an array in terms of a JavaScript object or a JavaScript array. It is a special reference type that doesn't exist anywhere else in the language, and if you modify the array-like thing that is called arguments, it can modify references. So it almost acts like a double pointer. So if you had some elements that you were passing in, say A and B, and you were to modify arguments sun zero equals five, then whatever a is that's being received by the function would become five. And this is just a weird thing that I don't think that it's super important to understand under the hood, like how that's working or why just that it's kind of a bug in the language that can't get fixed for whatever reason.
DAN_SHAPPIR: So it's actually actually let me let me interrupt you. It actually sort of got fixed then arguments doesn't behave this way anymore.
AJ_O’NEAL: Oh, I'm gonna test that real quick.
DAN_SHAPPIR: Please do, correct me if I'm wrong. Wouldn't be the first time. But that's what I recall, that if you use strict mode, then arguments ceases to be an alias for the original arguments, and in fact becomes more of like a copy of them. But like I said, in any event, arguments is kind of dead to me. I now use the spread operator when I want to handle a variable our length argument list and much safer and cleaner, I would say. And while we're waiting for AJ to finish verifying me, let's look at the next topic in the list. And the next topic that I have in this list is sparse arrays. It's funny that one, because I think that a lot of JavaScript developers aren't even aware that this thing even exists. And you know what, like I said, it's something that you should know, because if you don't know that it exists, it's usually not the end of the world, except that sometimes it might result in behavior that you might find to be inexplicable or maybe even a bug.
AJ_O’NEAL: To be clear, it should not exist. It should throw syntax errors when you put commas back to back to back by accident.
DAN_SHAPPIR: Yeah, but there's actually an easier way to think about it. So what you were referring to the fact that I can actually initialize an array or create an array literal, and instead of putting values in between the commas, I can just string along several commas together, effectively creating a non-value in between existing values. But I'll give a simpler example of a sparse array. And that's supposed that I assign an empty array literal into the variable A. So I do a equals open square brackets, close square brackets. And then I do a open square brackets, one million close square brackets equals seven. That is, I put the value seven into the position one million inside of the array, position that previously did not exist because I initialized the variable with an empty array. Now, in some programming languages that might cause something like a segmentation fault. You know, you're accessing memory that you don't own. In other languages, you're more protected, like Java that will just throw an exception, an out of range array access exception that you can catch. In JavaScript, that works just fine. You've in fact increased the array to be of a length of one million, or actually more correctly, one million and one, because arrays are zero based of course, is not intended, and you put the value seven there. So that kind of begs the question. Did I, by making this single assignment, did I just allocate one million array entries or one million and one array entries? So initially it might actually seem so because if I do a.lengths it will in fact return one million and one. But if I do and for each on the array to iterate over all the elements, I will find that it actually only iterated over that one element. And
AJ_O’NEAL: Well, it depends on how you iterate, because it behaves differently with different iterator constructs in the language, which is
DAN_SHAPPIR: Well, like I said, the length did increase to 1 million and one. So if I do for i zero i less than a dot length, then obviously I would iterate through a million values of i and you know visit all these entries in between. But if I do iteration over the actual proper over the actual entries that exist in the array using either for each or a for in loop then I would see that I only actually iterated over that one single entry. And the reason is that JavaScript is kind of quote-unquote smart about it and creates what's known as a sparse array where it just like kind of uses areas like objects. It just created an entry for that for that value of one million left all the other entries non existent. And that's what's known as a sparse array. A sparse array is an array where only the entries that actually contain values exist and all the other ones that don't contain values just don't exist. Now in most other programming languages, if they even have this type of a construct, it's distinct and separate from an array. But in JavaScript, everything is an array. Array is an array, stack is an array, a queue is an array, and also a sparse array is an array. So it's kind of, it automatically works. Array can become, a sparse array can become an array if you fill in all the missing bits. And an array can in fact even become a sparse array. And we can talk about that later.
AJ_O’NEAL: So I think that this is one of those things you should know so that you don't use it because I just, I don't believe that there is a legitimate use case for this. I think if you're going to do essentially what's a hash map, then you should be using an object and object dot keys or object dot values and that remembering the differences between for each and for in and for of and for, and how they all behave differently, I don't personally feel like that is a lot of value.
DAN_SHAPPIR: Well, I would have to agree with you because I think that in like how many, I won't even say how many years of coding in JavaScript. I can't think of ever intentionally using sparse arrays in my code. On the other hand, the funny thing is that my son who's studying computer sciences, you know, he did just ComSci 101. They, one of the exercises they got was to actually implement a sparse array in, uh, in Python. So, you know, there's that.
AJ_O’NEAL: Well, but there's a lot of stuff that you do theoretically and pedagogically. That's like, Oh, it's cool to know this, but if it doesn't have a practical application, I like, what do you call that? Cytogenesis. Like something exists because you reference it as existing, but not, I mean, it's like, knowledge that didn't get garbage collected because somebody said it was knowledge that shouldn't get garbage collected. It's one of those circular dependent circular reasoning like because somebody comes up with a theoretical case for it does not make it a practical case.
DAN_SHAPPIR: Well like I said I put it in the should know bucket rather than the must know bucket and it's a very it's even arguable whether it's something that you you know
AJ_O’NEAL: I agree that you should know because you're going to come across code or if nothing else, perhaps a mistake that you make where you accidentally hit the comma twice and your linter doesn't actually delete it because technically it's not a mistake in the language. It should be a syntax error, but technically it isn't. So at some point you're going to come across where you put like a comma behind something and a comma before it, or you put two commas in a row or whatever, and you're going to end up with a sparse array and you need to know this behavior exists and you need to know why your array is off by one or whatever. So I agree that it's something that you should know. I'm just saying you should know it so that you don't use it and that when you come across it, you know how to fix it.
AIMEE_KNIGHT: It's pretty uncommon.
DAN_SHAPPIR: My next entry is also something that you should know in order not to use. But before we get there, did you actually get around to test the arguments object that we spoke about before?
AJ_O’NEAL: I did, and you are in fact correct. And I am surprised because I have been, you know, a long time use stricter ever since before it was implemented in Firefox even when it was, you know, first being introduced in linters, I was a use stricter. And so I was familiar with a number of the use stricts fixes but I was not familiar with that one. And I'm happy to announce, if I'm not mistaken, if you use ESM, one of the benefits of ESM is that you don't have to put use strict at the top of your code.
AIMEE_KNIGHT: That's true.
AJ_O’NEAL: It runs in strict mode. So I am happy to see that they reintroduced strict mode after taking it out when they reintroduced ESM.
DAN_SHAPPIR: I totally agree. Strict mode for the win. So we spoke about sparse arrays as something that you should know in order to probably not use. The next one is something that you should know in order to kind of almost definitely not use, which is the delete operator, something that really confused me when I started working JavaScript, having come to it from C++ primarily, that also has a delete operator, which does something completely different. So it was and unfortunately, the syntax is kind of similar. So it was especially confusing for me. I guess it's confusing the sort of way that a lot of people coming into JavaScript from these sort of C-based languages like C++ or Java get confused by a lot of things in JavaScript. But anyway, so the delete operator, what the delete operator in these other languages, just because I mentioned it in C++, delete operator is the opposite of new. That is you C++ does not have a garbage collector. So when you allocate an object using new, you have to explicitly release it so that its memory can be reused. And the way that you do that is with the delete operator. That's totally not what it does in JavaScript. In JavaScript, what the delete operator does is remove properties from objects. That is, if you've got an object, let's say you've got X which references an object and that object has a Y property, then delete X.Y will delete the Y property from that object. That property after the delete no longer exists. If you use the in or has instance of or whatever, it's not there or object keys to get the list of all the properties, it's not there anymore, it's just gone. Now, why did I say and by the way, that's different than assigning undefined to that property because when you do that, the property is still there. It just has like a value that indicates it's not been initialized yet, but it's still there.
AJ_O’NEAL: There's the difference between not defined and undefined and null.
DAN_SHAPPIR: Yeah. I'm not even going to talk about null talking about things that maybe ideally would not have existed in the language. But anyway, so why am I saying that you should not use delete in most cases? Because using delete modifies the structure of the object, which gets in the way of the JavaScript engine being able to optimize the code. It turns out that, you know, when you look at JavaScript objects, they kind of operate like property bags or even dictionaries. And you might think that the JavaScript engine does kind of look up whenever it needs to access a property. And way, way, way back when that's actually what it did. So way back when, objects were kind of implemented similar to a hash in other programming languages, and you would literally do a lookup. But that's really expensive. And back then we would do silly tricks like in order to make loops faster, instead of doing i less than a.length, we would copy the length into a variable and compare the length to that variable just to avoid accessing the length property on the array all the time. Because it was expensive, it turned into a lookup. While JavaScript engines don't work like this anymore, I won't go into the details, but they have this whole concept of hidden classes the names into offsets within the structure of the object. So they kind of work in this way without actually having explicit classes. They work as efficiently as programming languages that use classes and are compiled like Java or like C++ or C sharp. And then when you use delete, the delete operator in JavaScript, it kind of throws this whole thing out the window because you've removed a property and potentially change the offsets of all the other properties in that object, because all the properties that came after this property are now moved back. And that really gets in the way, let's say, of the JavaScript engine ability to optimize the code. So really, the only use that you might have for the delete operator in JavaScript is when you're using the object really explicitly as a map. But then I might argue that these days you should probably be using the new back type rather than using an object for it.
AJ_O’NEAL: I would love to hear why that is.
DAN_SHAPPIR: Because I believe that you should use things for what they're intended because at the very least you convey intent. When I see somebody use a map, I know that, Hey, they're going to be using this thing as a map. If I see somebody using an object, well, they might be using it as a map, but they might just be using it as an object. I need to read the code in order to understand.
AJ_O’NEAL: Um, so my question is, cause I've never used a map and part of the reason I've never used any of these new map and set and all that is because just sounds complicated, like what I've got works. Why do I need a different tool? Like what does it benefit me? My fear is this, it's just going to make debugging harder and portability harder and understanding between communicating with people. More difficult. I get what you're saying. If it says, you know, map, then you know, well, you hope that it's being used as a map intentionally. But as far as I understand, there's no optimization that you get from it. There's it just makes it more complicated, makes the enumeration of properties weirder. It just like, well, screws up the way things used to be. But I don't, I don't really know. I don't, that's my, that's, that's my, from briefly looking at it once years ago and not having looked at it since.
DAN_SHAPPIR: Well, I would say, I would say like this, first of all, the old way continues to work and will always work because there's just so much code out there that just depends on it. And you know, you're perfectly, it's perfectly legitimate to just, you know,
AJ_O’NEAL: it would have to be a type language to not work like you'd have to change the language even more.
DAN_SHAPPIR: Yeah, by the way, one of the advantages of using map is if you're switching over to TypeScript and using map for maps is a whole lot easier because the type system just gets in the way of using the objects as map. But anyway, putting that aside, with a map, map actually has a few advantages. First of all, I have to say that it's supported universally essentially now. So unless you really, I don't know, need to work on IE 11 and even then you can use polyfields. But really, Map is supported everywhere. And I know that you're primarily coding for Node. Node has had Map for a long time. So you can just use it if you want. You don't need any transpilation or anything like that in order to use that. So Map has a few advantages. First of all, the keys can be object references. They don't need to be strings. If you use a JavaScript object as a map, then the key has to be either, we spoke about it several times in previous episodes, it needs to be either a string or a symbol, and that really introduces a limitation, and sometimes it's really useful to be able to map one object into another object without having to modify the original object by introducing some sort of an artificial key value on it, that you, you know, hash value on it or whatever in order to use that as the map. So being able to map objects to objects is a useful capability that map gives you and it's difficult to implement without maps.
AJ_O’NEAL: I would say the core use case of this would have been something like add event listener, remove event listener, where you need to find the function, which in the olden days, you just had to store them in an array and then loop through the array until you find found the function that triple equal the function you were handling to see if that had already been added or if you could remove it. But that's mostly, you know, internal stuff that lowly web developers didn't do.
DAN_SHAPPIR: Yeah. But I can give you another example. Let's say that you want to add some arbitrary data, not string data, just arbitrary data on top of HTML elements. So if, you know, the way that you might do it now is either just, you know, modify those elements themselves, which kind of breaks encapsulation and does all sorts of bad things can result in memory leaks or whatnot. Or you give them all IDs and use these IDs as keys into a map that maps to them. So what you want to do is keep the data, your own data on a separate object from the HTML element, but be able to easily get from that HTML element to that other object that html element to that other object which contains your own private data. And like I said, with maps, it's really easy to do. And without maps, you either have to really break encapsulation or jump to a lot of hoops to achieve something similar. And it's not such a weird...
AJ_O’NEAL: Well, not really a lot of hoops so much as an order and loop.
DAN_SHAPPIR: Anyway, so, and a map just makes it much easier and more convenient. So that's another benefit of map. And the other thing is, like we said, with objects, you have this whole concept of hidden classes and whatnot, which potentially gets in the way of using objects as maps. And you kind of confuse the JavaScript optimizer. And again, that doesn't happen when you're just using a map for the map.
AJ_O’NEAL: PS Steve, did I get a chuckle from you silently there? Cause I thought that was a really good bad joke. I mean, dad joke.
STEVE_EDWARDS: No, you did not. Yeah. You did not get one for me.
AJ_O’NEAL: Sorry. It was that bad. Yikes. Okay.
DAN_SHAPPIR: Hi Steve. Cool to have you along.
STEVE_EDWARDS: Oh, thanks. I'm just listening since I came in late.
AJ_O’NEAL: So also on our show today, we have Steve Edwards.
STEVE_EDWARDS: Hello from where am I from? Oh yeah. Portland where it's very cold.
DAN_SHAPPIR: One of my picks at the end will be the Tel Aviv weather. So just you wait, you'll be really jealous.
STEVE_EDWARDS: Oh, I'm always jealous of people where it's warm. So anyway, moving along, the next one that I have on.
AJ_O’NEAL: I had one more thing on that. One more thing. Which is that, you know, we're talking about compiler or VM optimizations and all that. There is in fact a way to free up memory on an object, depending on how it's done and where it's done, et cetera. If you assign null to something, especially if you assign null to it, within the function in which it was created. It will get reaped by the virtual machine at that time rather than waiting for the garbage collection pass. It depends, you can do things that will break that, if you have other references to it or it's been put into a closure or whatever. But if you, and some weird reason, you want to make garbage collection happen sooner. I don't know if the delete operator will do that, but I imagine that in some cases it may, probably in the same cases where assigning null will work, but I have personally observed that assigning null can cause a free quote unquote.
Did you work your tail off to get that senior developer gig just to realize that senior dev doesn't actually mean dream job? I've been there too. My first senior developer job was at a place where all of our triumphs were the bosses and all the failures were ours. The second one was a great place to continue to learn and grow, only for it to go under due to poor management. And now I get job offers from great places to work all the time. Not only that, but the last job interview I actually sat in was a discussion about how much my podcast had helped the people interviewing me. If you're looking for a way to get into your dream job, then join our Dev Heroes Accelerator. Not only will we help you get the kind of exposure that makes you attractive to your dream employer, but you'll be able to ask them for top dollar as well. Check it out at devherosexcelerator.com.
DAN_SHAPPIR: Well, it's a strong hint to the engine that that's what you want to happen. But I don't know if this is a part of the specification or just an implementation detail on the part of V8 or something.
AJ_O’NEAL: Yeah, well, likewise with what you're saying, I don't think that those are part of the specification or maybe it is in like ES 20, whatever, whatever. But it was something that like it came out of a talk from Douglas Crawford that this was popularized the whole, you know, problem with the delete operator. And then the Chrome team, a lot of the stuff that he said within months was no longer valid. And then the Chrome team came out with a tech talk and they talked about how they do all these optimizations that shouldn't be possible because they detect in your code when you're using something in a particular way and it should matter or it shouldn't matter. So like a lot of this stuff isn't specced in the spec. It's just anecdotal. We assume everybody's using V8. So somebody somewhere said, you know, the V8 team said this. And so we repeat it and we say, oh, this is how it works. Or we've observed it in Chrome or whatever. But yeah, I mean, like it may be different in nitro. It might be different in, I know what's the newest whatever monkey from Mozilla.
DAN_SHAPPIR: I like to say that it's when you got the best engineers from Google and Apple and the open source community competing head on on who can build the best engine for your favorite programming language, good things happen.
AJ_O’NEAL: Yes. Yes.
DAN_SHAPPIR: Whenever I compare the quality of JavaScript engines to the engines of other languages that require an engine, it's night and day. JavaScript is just amazing, the quality that they've been able to achieve. Anyway, as I said, moving along, the next one that I have on the list, is object dot define property and object dot define properties, which kind of lead into a discussion of something that I think a lot of JavaScript developers don't even know exists, which is property descriptors. You guys familiar with the term?
AIMEE_KNIGHT: No, you haven't really used it.
AJ_O’NEAL: I don't know it by the term property descriptors. I mean, I know what it is. I mean, the best example would be anytime you have an array and you access dot length.dot length calls a function that returns the number, or if you assign to dot length, it calls a function which truncates the array. But it looks like a property, but it's actually a function.
DAN_SHAPPIR: Yeah, that's a good example of it. So the idea with property descriptors is actually with all properties in JavaScript, we usually just look at the value of that property. And again, like you said, sometimes the value is actually, accessing that value is actually done via getters and setters, but we still just look at that value. Well, it turns out that objects, in addition to the value, actually contain additional information about each property and the way that it behaves. And the collection of all this information per each property is referred to as a property descriptor. So that property descriptor has a couple of attributes. The obvious attribute is value, which for simple properties would be the value of that property. So if I do a, let's say again, I have an AX, sorry, references an object, and I have a property Y on it. So X.Y equals seven just means that the value attribute of that property is now set to seven. But there are additional attributes on each property. One attribute, for example, is an attribute called configurable, which is a Boolean. It can be either true or false. And what it specifies is whether or not you can change that descriptor or delete that property. If it's true, then you can. And if it's false, then you can't. Going back to the delete operator, if you try to delete a property that has its configurable attribute and the descriptor is set to false, you can't delete it. I think that delete operator will return false and the property will just stay there. So, you know, it's an interesting name, like configurable for saying you can't delete it, but yeah, there you are. So that's one attribute. A more useful attribute is an attribute called innumerable, which is also Boolean and basically says whether or not that attributes participates in enumerations. Going back again, AJ, to your example of the length on an array. So an array, let's say I have an array of, of let's say three elements. So I effectively have a property zero, a property one, and a property two, but also property length. But when I enumerate the array, I only see zero, one, and two. I don't see the length. And that's because length is specified as not being a numerable it's the it's a numerable attribute is false.
AJ_O’NEAL: And in general, I hate it when people do this because usually whatever the thing is, isn't documented and you can't console.log to figure out what the heck it does or what its functions are. Like for example, Google's OAuth library is probably one of those poorly documented libraries in all of history. There's like lots of features that it has that you literally, they're not in the official documentation but they're somewhere. And if you console.log any of the objects, like the user object, for example, you get a bunch of garbage that's like minified. So the object will have like a.underscoreY property or something like that. And that'll end up being the user. But what you're supposed to call is get user ID or something. And all of these, I don't know what they did. And maybe it's just prototypes. Maybe they're just making a class out of it or something. But I come, like I love to be able to debug things just by doing a console.log and trying to figure out what it is. But so often there's nothing about the object that is Googleable or that describes the object. So you have to know what the object is in order to go find the documentation and it may not exist. So I I'd like the idea that you can set things to non innumerable other than the very basic primitives that were part of the language from the beginning, like array that makes sense that dot length is non innumerable. I mean, personally, I think it should show up in object dot keys. I don't know whether it does or not, but no, it doesn't. Yeah. But this bike, how do you enumerate things that are non innumerable? Do you know, is there a way to do it?
DAN_SHAPPIR: I think that if you look at the, if you do the console log, you actually now, at least in DevTools, should be able to see the non-enumerable properties as well. Again, you can test it. But look, when constructing an API, sometimes, you know, if you're constructing an API that's supposed to resemble some sort of a collection, that means that people will enumerate over it, that it does make sense to specify certain things that you don't want to be enumerated as being having a numeral being set to false. But very few people actually use it. By the way, the way that you specify all of these, I did mention it before, because when you just do x.y equals seven, you create a property and you get the default values for all of these. So by default it's configurable and by default it's enumerable, and by default it's also writable, which is the next attribute that I was gonna mention. If you want to specify values other than these, then you use object defined property, or if you want to create multiple properties, at once you use object.definedproperties plural, and then you can explicitly set these attributes.
AIMEE_KNIGHT: I kind of googled. Yeah, go for it. I was going to say I googled because I was also curious of AJ's question about how do you get non-annumerable properties. And it looks like object has a method get own property names that returns a new mobile and non innumerable properties
AJ_O’NEAL: That's you
DAN_SHAPPIR: Let's see It's always the hack yeah, and we rely on these hats I kind of mentioned the next attribute which is writable which kind of controls whether it's a read-only or read-write attribute or alternatively, you can actually set getters and setters. There are other ways to specify getters and setters, but you can also do them using this way. And then you can either use, create, you know, something that is effectively like controlled your functions, but behaves as if it's a property, a simple property like the array length, which AJ mentioned before.
AJ_O’NEAL: Because we love to have side effects on reading a value, right?
DAN_SHAPPIR: For sure. To be honest, I've come to the point. I know that the getters and setters were a big thing in object-oriented programming. And there was like a point in time where everybody thought that by putting a ton of getters and setters, they were quote-unquote, doing good encapsulation. And I always hated it.
AJ_O’NEAL: Yeah. I didn't really get that. It just seemed like a lot of extra code for a value.
AIMEE_KNIGHT: Yes.
AJ_O’NEAL: So I, this, this is with the defined property and divine properties, I view these the same way that I view prototype. The average person shouldn't touch it. It should only be for people that are implementing libraries that are patching the language itself. Like, uh, you know, if you're, if you're creating a library, that's a polyfill library, that is maybe an appropriate case for defined property and defined properties. I hope that people don't use this in their regular day-to-day code or to show off their ninja skills?
DAN_SHAPPIR: I would say that it's kind of useful at the API layer. When you're creating an API, you may want to have greater control over, you know, the behavior of the API to, you know, any code that consumes it. But I doubt that people will overly use it because creating object literals in JavaScript, it's so easy and defined property and defined properties are so verbose that I doubt that a lot of people actually use them.
AJ_O’NEAL: You underestimate how many people like to look cool.
DAN_SHAPPIR: I've given up on looking cool a long time ago.
AJ_O’NEAL: Well, that's great, Dan, and I value you for that. Makes you a lot cooler in my eyes, even ice cold.
DAN_SHAPPIR: Thank you, AJ. Anything else about these before we move to the next one? Okay, then. So a while back in one of the episodes when we were speaking about things that JavaScript developers must know, I think it was in the third episode or whatever, Amy, you expressed shock and horror that we did not discuss the DOM as something that JavaScript developers must know. And we all apologize by saying, I think more or less that it seems so obvious to us that it just didn't even occur. But, and then we started talking about when by knowing the DOM does it mean that we actually need to memorize portions of the DOM? And I think it was you, AJ, who mentioned that maybe a certain small amount, and you gave us an example, the add event listener as a DOM API that everybody knows and everybody memorizes and knows how to use. And I kind of joked in response that everybody knows the first two arguments of add event listener, but very few people actually understand the third argument. In fact, most people just don't specify it at all and have no idea what it really does. And so in this case of things that JavaScript developers should know, bordering on things that I think they need to know is that third argument to add event listener. And in order to understand the purpose of that argument, we need to speak a little bit about how events actually work in JavaScript, which is a really important subject, and the concept of event bubbling and event capture. Event bubbling is the fact that if let's say I have a div or a button, let's say I have a button inside of a form inside of a body if I click on that button there it generates a click event and the target of that click event is that button which was clicked on but it and that event is given to any to be handled by any event listeners attached to that to that element, to that button. But after the button gets its chance at handling that event, the event then starts bubbling up the dome tree. So from the button, it then bubbles to the form, and from the form to the body, and from the body to the HTML, and from there to the document, and finally to the window. So it's kind of similar to bubbles in I don't know, in a soft drink, the event kind of goes up and up and up. So that's event bubbling.
AJ_O’NEAL: Now, I think there's an exception to that. Correct me if I'm wrong, but I think the submit event will only bubble as far as the form.
DAN_SHAPPIR: Well, there are a couple of events that behave somewhat differently. So for example, the focus event, I think, doesn't bubble at all, as I recall.
AJ_O’NEAL: Is that just on inputs? Is that the only place that you have focus?
DAN_SHAPPIR: On things that have a tabs that either inputs or have a tab stop attribute as I recall, you know, you're really stretching my my collection of the DOM API but yes so bubbling is is not always and not exactly the same everywhere but in most cases events do bubble and you can prevent bubbling by Canceling the bubbling so you actually on the event object there's this method whose exact name suddenly escapes me which is cancel bubble or something like that default No prevent default is something else stop propagation. I see you stop bubbling by stop propagation exactly we'll get to prevent to prevent default in a minute. So now that's the default behavior of Events and a lot of developers actually know this most of JavaScript developers are I think or hope aware of this event bubbling what most JavaScript developers don't know is that there's actually a phase ahead of this event bubbling, which is called event capture. Because it turns out that when you click on that button inside the form inside of the body, before bubbling from the button up to the form up to the body, first it goes from the body down into the form and into the button, which is the target. And that phase is called the capture phase. So it starts at the top, goes down to the target before going back from the public, back up from the target, back to the top. And that phase that happens before is called the capture phase. And that phase, if you want to be invoked in that phase, then you can specify a true value as the third parameter in the add event listener. And then the invocation order is kind of a reverse because it goes from the top most all the way down to the target. And also, this cannot be prevented by the target because these events get invoked before the event even gets to the target. So capturing kind of makes it possible for an external element to get informed of events that happen within it regardless of what the contained elements try to do about. And for a long time, that was what the third parameter was. It was an optional Boolean value that if it was false, you know, you were invoked in the normal order of things during the bubbling phase. But if you wanted to be invoked before the bubbling phase during the capture phase, you could pass through and hardly, fortunately, hardly anybody ever actually did that.
AJ_O’NEAL: So is that still valid with use strict and yes, 20 X DX or is that taken out?
DAN_SHAPPIR: It's part of the DOM. It has nothing to do with JavaScript.
AJ_O’NEAL: Well, I know, but sometimes these things are deprecated like the blank tag. Like I think that the, what is the, the, the synchronous XML HTTP request sync has been either deprecated or removed or.
DAN_SHAPPIR: It's still there. That's the way that events still work in the browsers and you can just test it. We'll put a link in the show notes for an excellent article that covers both of these. And, and I, uh, and you can actually, it contains code, you know, a live code examples that you can actually use. And it shows that this stuff totally, totally still works.
AJ_O’NEAL: And was there a reason it was useful? I didn't catch that part.
DAN_SHAPPIR: Like I said, I have no idea why it was added into the language other than to handle special cases where you as a containing object need to be informed that something is going to happen and you don't want your contained element to cancel it for whatever reason. Anyway, so it used to be that that third element, that third argument to add event listener was just this boolean value. Turns out that now because they wanted to support additional options, it's also possible to pass in an object which is an options object. So you can use it to specified certain other named behaviors. So that third parameter can now just be an object and it can have several fields. The one field is a capture field, which is set when when set to true behaves exactly like passing true and instead of that object to begin with. So it's therefore, you could say backward compatibility is an alternative, more modern way of achieving the same effect. But there are two other attributes there that from my perspective are are much more useful the first one is actually fairly easy to understand it's called once and if you specify that Then that event will be triggered once and then immediately removed so instead of remove event listener You know if you just want to be invoked once instead of doing the ad and then having to do the remove yourself You can just specify once there and it will be invoked once and that's it. It's removed automatically for you.
AJ_O’NEAL: Well, that's cool. I didn't know about that, but that's a common pattern. People have all these once functions that add and remove. So now we don't have those.
DAN_SHAPPIR: Yeah, I guess that's why they added it because it's in fact indeed very common and having it built in just makes life a whole lot easier. So that's the once attribute that you can pass there. The other one needs a little bit more explanation and that's passive. Passive means that you promise not to use the cancelDefault method on the event object. You promise not to try to cancel the default behavior. And why is that? And if you, by the way, if you do do it despite this quote-unquote promise, then it's ignored. The system assumes that you don't do it. And if you do it, well, you know, it ignores you. Now why is it important? It's important because it turns out that in some cases, if the system can assume that you cannot cancel the default behavior, it enables the browser to be much more efficient about doing certain things. And a common example that people give is when you capture the scroll event. Because it turns out that if you do that and you don't specify this passive attribute, the browser cannot perform its own scroll operation until after executing your JavaScript code. So the actual implementation of the scroll has to be synchronous with JavaScript, with the operation of the main thread. On the other hand, if you put in the prevent, the, sorry, the passive attribute, then the browser knows that you can't cancel the default operation and then it can do scrolling off of the main thread and which results in much smoother scrolling that can be done, let's say, under the GPU or something like that. So in general, if you are not going to, if you put in an event handler and you know for a fact that you're not going to be canceling the default action behavior under any event, then it's better from a performance point of view to just put in the passive attribute. It results in a nicer experience for the user. Is that clear? I hope it was.
AJ_O’NEAL: Do you forgot to talk about all of the memory leaks that happened with that event listener?
DAN_SHAPPIR: Yeah, I don't think we'll have time, but that's actually a topic that can come up at the very end of this list. But before that, I want to mention another attribute, the last one, which actually doesn't yet exist. It isn't supported on any browser that I know. I think it's behind a flag or something on V8. And I'm really looking forward to it being implemented. And that's the signal attribute, which is related to the abort controller object. What I dislike about add event listener is the fact that doing a remove event listener is really annoying. Unlike a set timer, for example, which returns an ID value that you can use for the cancel, with add EventListener, you don't get this sort of thing. If you want to remove an event listener, you have to specify the exact same parameters that you use during the addEventListener. The same event name, the exact same reference to the handler method, and the exact same options in the third parameter if you specified them. Otherwise, you're not removing it, which means that you have to keep reference to that handler function that you provided, because you will want to use it for removing. It's really annoying. And again, one of the reasons why the once attribute was so useful, because it removes that annoyance, at least when you only want to invoke that handler only once. Well, it turns out that they are looking to introduce a much nicer way of doing this. If you create an abort controller object, it has a signal property. If you pass that, the value of that into the add event listener, will, you know, again, not get supported. But if you, in the future, if you pass that, then when you abort that abort controller, it will cancel the event listener, which will make it much easier to cancel event listeners. And as an extra benefit, you can use that signal in multiple event listeners, so you can cancel a whole bunch of event listeners by just doing that single abort operation. And I think that's really useful and cool. But unfortunately, not yet really supported anywhere. So something to look forward to. Do we have time to discuss anything more? I think we are kind of approaching the end of the episode now.
AJ_O’NEAL: Hmm. There's one thing that I would like to add in here, which I think would be brief, which mostly applies to node because I don't, I don't know if it applies in browser JavaScript as much, but weak, weak references to events, which I, I don't know if that's the same as what you had here down at the bottom of the list, but things like set timeout, like, like people have this problem a lot, especially with Lambda and those other types of things that are supposed to run and then be done and then exit, but then they don't. And all the old database libraries and node have this problem. A lot of the ones that have been updated don't where you on almost everything that has a reference in the event loop has an unref function, whether it's a network socket or a timeout or whatever it is. And what that will do is we'll make it so that if you put that item in the event loop and only weak or unref items are in the event loop, then the event loop will stop and exit. And these weak items are only kept in the event loop as long as there are strong items to keep them or like the normal items to keep them alive. And that's something where, I don't know, it's probably not something most people should know. Cause again, it's, it's like people that are implementing database libraries or whatever. But with, with Lambda becoming so popular nowadays, I mean, I think it's actually worth, worth people knowing about. So when they come across this problem where the node process has done what it's supposed to do and won't exit. It's because somewhere.One of their libraries or an HTTP server that they created or something has a strong reference in the event loop. And if they were to go find that code and call unref on that, then the problem would go away.
DAN_SHAPPIR: So yes, it's kind of similar to the points and to some of the points I put at the bottom of the list, which we will not get to at this episode. Maybe we'll have a follow-up episode at some point where apparently, you know, so the unref that you just described is a convention. It's not really part of any standard. Maybe, you know, it's specified in some node interface APIs, but it's not part of the JavaScript of JavaScript itself. But it turns out that apparently this has impacted JavaScript because they've identified it as an actual need that's not properly addressed by the language itself, and they added several things in order to address it. So previously they added weak maps and weak sets which I guess we'll discuss in a future episode. And recently it's been introduced, it's been moved to stage three. They introduced the whole concept of weak references and finalizers, which sound really, really similar to what you just described, but are part of the language itself and are actually supported by the actual engine. So if you do them correctly, you're less likely to run into problems. And turns out that they're actually in Chrome since version 84, I think we're currently on version 88 as of the time of this recording. So you can actually play with them in your current Chrome browser. But I think these topics are kind of too complicated to touch on in the time that we have.
AJ_O’NEAL: Okay.
DAN_SHAPPIR: Anyway, you know, again, we've got, you know what? To leave us with a taste for the future episode, the other items that I have on the list are layout reflow thrashing, the virtual DOM as a concept, why it is, why it exists, how it works, stuff like that. It's present in so many frameworks. I think it's beneficial to know it is a distinct thing. And also there are other frameworks which kind of boast not actually having a virtual DOM. So there's whole discussion of whether or not it's a good thing. And then three things that have been added to JavaScript that you can't really mock or can't polyfill. That means that either you have them and can use them or you don't have them, in which case you can't. The weak map, weak set, which we just mentioned, weak references and finalizers, and also the concept of the proxy object. So all of these are things that we can discuss in the follow-up episode. And by the way, to our listeners, if you have ideas for items that you would like us to discuss, you know, as things that that JavaScript developers should know or maybe even must know, then you know what? Just send me a tweet. I'm Dan Shapiro on Twitter. Just tweet at me or DM me and I'll add them to the list. So that's the end of that.
AJ_O’NEAL: All right. Well, Dan, how do people get in touch with you? Oh, wait.
DAN_SHAPPIR: Yeah. And if they don't follow me on Twitter, then what's wrong with them? And they should follow me on Twitter and I follow back. So you know.
AJ_O’NEAL: All right. Well, thanks again for leading the discussion on a few things people may or may not, maybe should must know in JavaScript. And I'm sure that our next episode on the matter will be just as enthralling as it always is. In fact, I think we've gotten a lot of really good listener feedback on these episodes. Um, I've noticed a lot of the, the tweets seem to be in the, in the upward direction with these. So I think this has actually gone really well. And, uh, with that I guess is it time to move on to picks? Is that what we're going to do?
AIMEE_KNIGHT: I can't hear.
Hey folks, if you love this podcast and would like to support the show, or if you wish you could listen without the sponsorship messages, then you're in luck. We're setting up new premium podcast feeds where you can get all of the episodes released after Christmas 2020 without the ads signing up will help us pay for editing and production and you can go sign up at devchat.tv slash premium.
AJ_O’NEAL: All right, Amy, go ahead.
AIMEE_KNIGHT: It’s been a while. I feel like I haven't been on the show for a couple weeks because work has just been busy and per usual, I just keep picking like infrastructure picks. Although some of this is not necessarily infrastructure because that leads me to the pick. So it's a short article.
DAN_SHAPPIR: You keep moving into higher paid brackets and the picks reflected.
AIMEE_KNIGHT: So this is understanding the different types of load balancers because I feel like this can get confusing and there's load balancers that at different layers. So it's an article on understanding that. And that will be my pick for today. I kind of have like another pick, but I don't know. I guess I'll just say my pick is kind of what we were talking about before the show. I feel like people like to use buzzwords and they end up conflating things and not explaining them properly. And it's confusing to newcomers. So my pick is going to be not using buzzwords unless you really know what they mean. So that's it for me.
AJ_O’NEAL: Excellent. So tell us a buzzword we should be using.
AIMEE_KNIGHT: Okay. So as I'm digging more and more into Kubernetes and understanding like horizontal scaling, vertical scaling, all this different type of stuff, it came to me that a lot of people in the past have completed service oriented architecture and microservices and they are not the same thing and people should not be throwing these words around unless they really know the difference.
AJ_O’NEAL: Everything's a microservice Amy.
AIMEE_KNIGHT: It's not, microservices are at the infrastructure level service oriented architecture is at the application level.
AJ_O’NEAL: We need to get, oh gosh, I'm blanking on his name right now. The event loop guy, or not event loop, the event driven services guy, gosh. I'll remember later. Anyway, we need to get a show.
DAN_SHAPPIR: Either that or just get Amy to be the guest on an episode.
AIMEE_KNIGHT: Infrastructure for newbies.
DAN_SHAPPIR: Yeah, something like that.
AJ_O’NEAL: Okay, Ethan Garofalo or Garfafalo or? The name sounds familiar. I've been his friend for years, but I can't. Nobody knows his last name.
AIMEE_KNIGHT: I'm just so tired of people throwing these words around and they're not the same thing. And it's confusing to people. And like new people entering the industry just, ugh. Please don't.
AJ_O’NEAL: Well, I'm gonna, on that note, I'm going to pick Ethan. I'm gonna find his name in his YouTube channel and throw it in here in a second, but I'll let somebody else go first. Steve, could you go?
STEVE_EDWARDS: No, I was gonna leave me out since I'm really not here today. I didn't really contribute anything, so I was kind of bailed out.
AJ_O’NEAL: Not even contributing to the picks? So sad.
STEVE_EDWARDS: I don't have one to contribute. I've been thinking about it.
AJ_O’NEAL: Alrighty.
STEVE_EDWARDS: And just listening to Dan's words of wisdom all day.
DAN_SHAPPIR: All day, all day.
STEVE_EDWARDS: Well, I'll hour let's put it that way.
DAN_SHAPPIR: Yeah. Okay. So I have a I have a few picks too, actually Um, so my first pick, uh kind of mentioned before so it's going to be the tel aviv weather In tel aviv we're kind of at springtime. Actually, I have to say this this entire winter We had a whole bunch of rain, but in terms of temperature it never really went very low And now it's kind of springtime here although I assume we will have some more rainy days before it ends. Just so you know, it's 75 degrees and sunny So that's the temperature here. That's the weather here So be be very jealous and it's really annoying because we're only now coming out of lockdown and people are allowed to actually go outside. So previously we had this wonderful weather but you were restricted to within 1,000 yards of wherever you lived Although most a lot of people were actually ignoring this restrictions. So yeah, it's interesting. Anyway, so that was my first pick. My second pick is again, oh, I hope I'm going to say his name correctly. It's Axel Rauschmacher. Does anybody know how to, we should definitely have him on the show and then he can tell us how to actually say his name. He's one of the, I would consider him one of the leading JavaScript language experts. He has an excellent blog, which is called the Toality. So it's literally the the digit two followed by Ality, A-L-I-T-Y.com. And it's an excellent blog. If you're interested in all aspects of the JavaScript language, where it is, where it's going, how it works, and just an excellent blog. And it turns out that he's also written a book which is called JavaScript for Impatient Programmers, which specifically targets people coming to JavaScript from other programming languages. And, uh, and it's free to read online and I'll put the link to it in the show notes. And, you know, I haven't read the book, but, uh, given the quality of this blog post, I can only assume that it's a really good book. So those would be my two picks.
AJ_O’NEAL: Alrighty. And then I will make a couple of picks here. So first I'll go ahead and pick my good friend, Ethan Garofalo, which I should know how to say that. Cause he's probably said it a hundred times as he's given presentations. But anyway, he does a lot of talks on microservices and event oriented architecture, and he's got, I don't know what the meme is. I wish I could pull it up, but he's got this really funny slide that is in a lot of his presentations is basically. So what do you get if you break a monolith into small services, you get a lot of many monoliths and he does a really good job of explaining. Uh, a like good, good patterns for, for event oriented architecture that can lend itself to microservices. I'm also going to pick X mission. I'm not sure if I picked them before or not, but they're a kind of, well, they, they do a lot of different hosting stuff and some of their pricing is really good compared to competitors and some of it, not so much in particular, their VPS pricing is not really great comparison to like DigitalOcean and Scaleway and other stuff like that. But I got a VPS with them anyway, because they are very privacy oriented hosting company and they are very committed to being apolitical. So much so that they have a transparency report that shows all of the, uh, so they, they don't listen to social media at all, uh, when it comes to affecting who they choose to host or not host. And when it comes to the government, they have a transparency report that shows kind of like 90% of the requests, uh, that they've denied because they have deemed the warrants to not actually be a valid legal warrant or not having a warrant or not being in the proper jurisdiction or whatever. So I don't know if they've got like, uh, a legal team or whatever, but they put effort into making sure that information is only given away when it is legally required and not a willy nilly. And that's something where if you've been following for a while, you know, I traditionally have not really cared about privacy as such, but I think times as they are, it's kind of becoming more important and I think it's good to be able to identify some hosts that you can rely on to not let Twitter be the guide of who they choose to host and not host but let the law and the actual systems that we have in place to protect people's rights, as well as to persecute people, be the judge of that and not mob rule. So also, since we've been talking about this stuff, there's a, if you just do some Googling around LuaJet, if you're interested in how some of these optimizations work with JavaScript-like languages, Lua is a lightweight language, very similar to JavaScript created around the same time follows almost all the same principles has us almost all the same bugs. And there's some stuff out there and I'm linking to one article and, or post in particular that looks like it does a decent job, but there's some good stuff out there about the Lua JIT and how it works. And there's probably some good stuff out there about the VM or V8 JIT and whatnot and how it works, but that's the just in time compiler. So check that out if you're interested in that low level kind of stuff. And then two other quick things. Our clone can be a lot faster than our sync. If you need to do local copies where some things exist and some things don't exist. So CP is the fastest. If you need to copy a big bulky folder from one place to another wholesale, new, fresh, our sync is the fastest. If you need to find a lot of small changes in between files and folders, and our clone is almost as good as our sync but quite a bit faster. And so I'm linking to that. I actually don't have it up on webinstall.dev yet, but I will by the time this airs, most likely. I've been doing pretty good about that anyway. And then the Cozy adapters for your, now that everything's switching over to USB-C, like if you finally got one of the Macs that has one of the USB-C, there's this little thing called Cozy adapters and they're little silicone bands that wrap around the USB-A and the USB lightning adapters so that you can have your USB-C cables, but still be able to interrupt with other devices when you need the USB-A end or the lightning ends to be able to plug into something. And that the silicone just goes on there so you can tether it to the USB-C cable so that you don't have to deal with the problems of losing the little adapter bits. And so now I've reduced the number of cables I have by using this.
DAN_SHAPPIR: AJ, what you said about X mission reminds me of something. You remember how there was this, a while back, this thing where I think it was the FBI or some agency that wanted information off of an iPhone and Apple wouldn't give them the ability to, you know, and gain access to that iPhone. So they were kind of, they weren't able to actually read those exchanges or emails. You remember that story?
AJ_O’NEAL: I do and I'm very skeptical of it. I think that Apple had ulterior motives, but. Well,
DAN_SHAPPIR: it turns out that the Russian government was much more effective about these sort of things because one of the protesters had like this information on her, so there are protests going on in Russia right now and the Russian police is really cracking down on them and they wanted some information off of the iPhone of one of the protesters, one of the girl who was protesting there. So they managed to crack her iPhone. Do you know how they did that?
AJ_O’NEAL: I'm guessing they did it like in the TV shows where they spray something over the fingerprint scanner and then make a silicone mold and then press it against it.
DAN_SHAPPIR: No, easier actually. They told her that if she didn't give them the password, they would electrocute her.
AJ_O’NEAL: Oh, how quaint.
DAN_SHAPPIR: It turns out that that works.
AJ_O’NEAL: Yeah, that brings to mind the XKCD about encryption and security. The one where they say what people think, oh no, 4096 bit encryption foiled again. Our evil plans are ruined. What happens in reality? Give us the password or we'll hit you with a wrench.
DAN_SHAPPIR: Yes, so yeah, that's effectively what happened there. You know, we're joking, but it's not that funny really.
AJ_O’NEAL: Well, it's, yeah, I don't know if they have due process of law like we have here and that is kind of scary and sad and all of that.
DAN_SHAPPIR: I wouldn't bet on it. Let's put it this way.
AJ_O’NEAL: Yeah. Well, anyway, on that note, I've actually been defanging my phone, meaning getting rid of Facebook, Amazon, Netflix, and Google, which, gosh, knows how many apps those companies own. It's probably 90% of the ones I have on my phone, even though they don't carry their logo on it. But I have been defanging my phone.
DAN_SHAPPIR: Well, there is an interesting thing here, again, not picked, but it's worth mentioning and I don't have the link. I read somewhere that Apple is going to be changing their privacy policy which is going to prevent the Google and Facebook apps from accessing a lot of the information which they currently do.
AJ_O’NEAL: I just, I'm skeptical of Apple. Like I am switching to some of their stuff. Like I'm switching from Gmail to iCloud because I realized like, yeah, Gmail was really cool back in 2004, but now doesn't actually offer any particular advantage over anything else anymore. Like it's kind of weird. Some of these technologies are really great. You forget why you actually use them.
DAN_SHAPPIR: Yeah, I think that this is a, you know, I definitely don't think that Apple is doing this for altruistic reasons, but I think that this might be a situation where Apple is doing something which is positive for a wholly, you know, wholly for its own benefit, but the outcome is actually beneficial.
AJ_O’NEAL: Yeah. Well, I, yeah, I'm just, I'm just skeptical of them as on by default. I don't remember if they even gave you a little thing to warn you about it or whatever they must have. But if you have an iPhone, there's a thing called exposure notifications, which is quote-unquote for COVID-19 tracking. But basically, I mean, that came out of nowhere really quickly on the phone and it's a tracking thing. And so I turned that off. And then if you go into, there is a privacy settings in your in your, um, it's probably closer to get good enough privacy on an iPhone than it is to get good enough privacy on an Android phone, but you can get a completely de-Google the Android phone and the battery will last like twice as long, but anyway, in the iPhone, there is a privacy setting and you can go in there and see location services and you can turn off a lot of that stuff that it just makes no sense for it to be using your location. I mean, things like uh, SoundHound or, or Shazam or Redbox. I mean, well, no Redbox. That kind of makes sense. Cause you're going to be going to where the Redbox locations, but you'll find there's a whole bunch of stuff that you forgot you had turned on location. It says while using, but it's like, if you've ever opened the app the entire time, you've not rebooted it. Or even if you have rebooted it, like you double tap the home screen, all of those things are open. So technically you're using all of them. So I don't know if that's what while using means. But there's tons of stuff using your location all the time. And then if you also look at a Bluetooth, that's how a lot of these apps do contact tracing. Like you just walk by somebody else that has one of these Bluetooth app apps on, and then it signals or something, and you'll find like all sorts of stuff in there where you just, you know, clicked allow absentmindedly. And you're like, why is Shazam using Bluetooth or like, why is group me using Bluetooth or, you know, there's just a bunch of stuff where it's like, this makes no sense, like Chick-fil-A. Maybe they have a Bluetooth sensor in the register, but why would Chick-fil-A be using Bluetooth? Just ton of stuff like that. It's kind of really scary.
DAN_SHAPPIR: Yeah, well, it's turning into a long, big section, but because of what you said, I'll mention one more thing. And so just so you know that in Israel, in order to, you know, with this whole COVID thing, they wanted people who were exposed to people who actually got the virus to go into quarantine. And the way that they actually went about it is that the Israeli equivalent of the FBI actually started tracking the locations via the phones of all Israelis using the various cell towers. And if you were in the proximity of somebody who was identified as being positive for COVID for let's say more than X amount of minutes. You would actually get an SMS from the government telling you, you need to go into quarantine and you would then be expected to be in quarantine for the next two weeks. And if they found out that you broke quarantine, you could get fined for, you know, a large amount of money.
AJ_O’NEAL: That just sounds too scary to me because it, because it starts with good intentions, but there's no accountability. Like how can you say that that person was or wasn't there. I mean, it gets to the point where it's just, it's too many levels removed from reality. Like I could digitally, I can send you an SMS and say whatever I wanna say. Like, how do I prove to the person that's being persecuted in this way that they actually were in proximity of X person? I don't have any doubt that it starts out with good, well, I actually do have some doubt depending on what region of the world it's in, that it starts out with good intentions. Certainly it's publicized as good intentions. But once you open Pandora's box, once you say, okay, well now anytime we want to, we can tell you that you're basically under house arrest because we said so. Where's the accountability? Where's the, where's the transparency to be able to prove that these things happened and it wasn't just, well, you have unpopular ideas and so you need to stay at home now.
DAN_SHAPPIR: That's totally accurate what you just said and all I would say in response is remember everything that happened in the US following 9-eleven and that was crazy and I can't believe that we let that happen and I I Can't believe that it's continuing till this day, but that was Anyway,
DAN_SHAPPIR: yeah anyway how to help your stuff. So I think that more or less concludes everything no.
AJ_O’NEAL: Oh, yeah I was concluded a while ago, but Hopefully the rambling doesn't bother people. If they stayed this long, if you listen this long, it's your own fault. It's your own problem. You could have stopped. Yeah, we're way back.
DAN_SHAPPIR: We're way past the JavaScript technical stuff.
AJ_O’NEAL: Well, technical, we're still in technical. How much of the tracking is done in JavaScript? How much of the Bluetooth? Anyway. All right. Adios guys.
DAN_SHAPPIR: Bye.
AJ_O’NEAL: And I would say gals, but Amy's gone. So TRD adios. Peace.
Bandwidth for this segment is provided by Cashfly, the world's fastest CDN. To deliver your content fast with Cashfly, visit cachefl.com to learn more.
JSJ 474: Things JavaScript Developers Should Know, Part 1
0:00
Playback Speed: