WebFund 2024F Lecture 4

From Soma-notes
Revision as of 02:49, 17 September 2024 by Soma (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Video

Video from the lecture for September 17, 2024 (given on Sept. 16th) is now available:

Notes

Lecture 4
---------
This is the lecture that would have been on Tuesday, Sept 17th, at 11:30 AM
 - but I'm at a workshop :-) (New Security Paradigms Workshop)


For this class, you can use whatever text editor you want
 - but try to use the class VMs on openstack if you can, good practice
 - Deno in other places may work the same but may not

A good setup is to have a local editor that is remotely editing files in the cloud
 - can even do remote debugging

VSCode is a great tool for this
But it is not the only solution
 - you can use editors like Emacs for remote code editing and debugging
 - use what you want! but please try to have things live in the cloud


JavaScript
 - be sure to look at the bottom of the main course web page, lots of JavaScript resources
 - please start going through one so you can learn the basics of JavaScript
 - it isn't that different, I'll go over key differences in class

At the center of a JavaScript runtime is a read-eval-print loop
 - present in "interpreted" languages, not compiled ones
 - REPL in Python, JavaScript, Ruby, but not Java or C


In JavaScript, variables do not have an inherent type (like Python)
 - they are names for values
 - the value can be anything
 - the value has a type, the variable doesn't (and can refer to any value)

If you use a variable without initializing, no problem, it will have a value by default - "undefined"
 - it is also often returned by expressions when there is nothing else to return

So why undefined? Why not something like 0?
 - because with undefined, you KNOW it is a value that should never be used
 - (zero has uses after all!)

This is probably one of the most annoying things about JavaScript, especially when coming from compiled languages
 - simple issues such as undefined variables turn into runtime problems (NOT ERRORS), when they could have been runtime or compile-time errors
 - can make debugging very annoying, because you keep finding "undefined"'s rather than getting compile-time errors to fix
 - note that undefined isn't an exception, it is just a value!

The only time this sort of behavior is a feature is if you have to run broken code. And well, the web is filled with broken code. But maybe that is because JavaScript is this way? We'll never know.

If you treat an undefined value as a string, it will often get converted into a string. Used in a numeric expression, it will probably turn into NaN (not a number).

JavaScript has arrays
 - they start at 0
 - they can be sparse
 - you can assign to arbitrary indices
 - values without an explicit value will have the value undefined

JavaScript will be too forgiving of errors, leading to nonsensical code
 - so you need to be aggressive in your error checking, especially
   validating you have reasonable values


JavaScript is kind of a functional language
 - functions are first-class datatypes
 - like integers or strings

So you can treat functions like any value
 - define on the fly
 - assign to variables
 - return values

But why would you want to do this?! Seems a bit silly right?

Have you heard of lexical scoping?

Associated with every function is a scope
 - all variables/symbols defined in the function go in the function's scope

A function's scope at runtime is actually a JavaScript object
 - and JavaScript objects are basically dictionaries (hash tables) which
   associate keys with values


Note that dictionaries in JavaScript are called objects, because to JavaScript they are the same (kinda weird I know)

What is an object, really?
 - datatype
 - has state (object variables)
 - has code (object functions)
 - inheritance

It used to be a big thing in programming theory, this idea that objects should be arranged in an inheritance hierarchy
 - so you'd have a class animal, and a subclass bird, so a parakeet would be a bird object which is also an animal object (because bird inherits from animal)
 - this is "is-a" inheritance

We mostly don't do is-a inheritance anymore
 - getting the class hierarchies right gets messy
 - and it makes code brittle, in that later changes can break old code that used to work (i.e., changing how animal works could break bird objects)

What we do instead today is "has-a" inheritance
 - so now objects are really just data types, so private data + methods
 - if we want to make a bird, we have an animal object inside of it which handles the animal-related things, it is completely separate from bird-level code and data



Another weird thing about JavaScript that while it is object oriented, it doesn't really have classes
 - you can define classes but it is mostly syntactic sugar
 - it has prototypes instead

Classes are abstract (can't do anything with them), objects are concrete
- with prototype-based inheritance, the prototype is concrete and is used as a template for making new objects

JavaScript and Java only have similar names because Java was hot when JavaScript was created and their syntax is superficially similar (because both kinda look like C)

Code

// Demo of scoping rules


function outer(a) {

    function inner(b) {
        return a + b;
    }

    return inner;
}