WebFund 2024F Lecture 22

From Soma-notes
Revision as of 00:32, 4 December 2024 by Soma (talk | contribs) (Created page with "==Video== Video from the lecture for December 3, 2024 is now available: * [https://homeostasis.scs.carleton.ca/~soma/webfund-2024f/lectures/comp2406-2024f-lec22-20241203.m4v video] * [https://homeostasis.scs.carleton.ca/~soma/webfund-2024f/lectures/comp2406-2024f-lec22-20241203.cc.vtt auto-generated captions] ==Notes== <pre> Lecture 22 ---------- Last class is Thursday - will go over Assignment 4 solutions then Assignment 4 is due Wednesday night - accepted until...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Video

Video from the lecture for December 3, 2024 is now available:

Notes

Lecture 22
----------

Last class is Thursday
 - will go over Assignment 4 solutions then

Assignment 4 is due Wednesday night
 - accepted until 11:30 AM on Thursday
 - no time for extensions, sorry

A3 & A4 will be graded before the final exam on Dec 12, 9 AM

I've sent out emails for interviews
 - if you got one, please schedule one or contact me if you can't find a slot

Openstack
 - will be open through exam
 - I'll send out notice, but please back up your work soon after the exam

I will be conducting interviews after the final exam
 - will take place the week of Dec 16th
 - only requires 15 minutes, no prep needed
 

Q&A session?
 - I could do one on Dec. 10th, during regular class time

Last lecture quiz will be for today
 - officially due Friday, but will give a few extra days to submit

Exam will be on the code from Assignment 4
 - it has everything we've covered!



Strict mode
 - original javascript was VERY loose, made it hard to see when you made an error
 - strict mode catches a lot of errors
    - in particular, assigning to a variable that hasn't been declared
 - Deno defaults to strict mode
    - node does not!
 - JavaScript modules default to strict mode

To ensure strict mode
 - put "use strict"; before any other code (with quotes) at top of file
 - can also enable per function, just put "use strict"; at the top

While strict mode will detect assigning to undeclared variables, it won't stop assignment to undefined properties of objects.

Objects, prototypes, & classes
------------------------------
JavaScript is an object-oriented language
 - it does support inheritance & classes, even though we haven't used them in class

While JavaScript supports classes and has special syntax for it, this support is mostly "syntactic sugar"
 - the underlying functionality was already there

JavaScript's model is prototype-based inheritance, not class-based inheritance
 - in the end, we just have objects
 - to inherit, we have a prototype chain
    - if an object doesn't have a property or method, we check its
      prototypes for the functionality, going back in a chain


So if you want to do inheritance, you can inherit from *any* object
 - you just set it as the prototype for the new object

But doesn't that mean that the prototype could change at runtime?
 - YES
 - this can be a good thing or a bad thing, depending
 - but it is dynamic


As you might notice, I'm really bad with doing object-based inheritance in JavaScript
 - that's because I don't like inheritance, I just use objects as key-value stores
 - and I instead use functions

So what does "new" and "this" do?
 - this has the value of the object a function is associated with
 - if it is just a bare function, this has no value (undefined)
 - if you call the function with "new", then this has the value of {}, and
   is what the function returns normally
     - this empty object will have the prototype of the function,
       so in this case the function is acting as a constructor

If I want an object with methods, I just make an object and assign methods to its properties
 - if I want that method to access the object, I use "this"
 - rather than use new, just make a function that returns the object you want


Note that modules are almost class-like in JavaScript
 - when you import, you can assign all exported values (functions, variables, constants) to properties of an object
    - see what we did with authdb.js
 - so prototype-based inheritance isn't used that often in modern javascript

Code

Note the code below is different from that shown in lecture. In particular, the prototype-based example now works, as I fumbled this in lecture. As you can see below, you can approximate the functionality of JavaScript classes with prototypes, but it isn't exactly the same.

If you're wanting to create an object hierarchy in modern JavaScript, use classes. But Object.create() gives fine-grained control that can be useful for "mixins" or other more advanced inheritance patterns (has-a rather than is-a inheritance).

// Class example

class Rectangle {
    name = "Rectangle"

    // joke is only accessible from the class object
    // but is also available in inheriting class objects
    static joke = "I'm not classy"
    
    constructor(height, width) {
        this.height = height;
        this.width = width;
    }

    area() {
        return this.width * this.height;
    }
}

class Square extends Rectangle {
    name = "Square"
    constructor(size) {
        super(size, size);
    }
}

var s = new Square(4);
s.area();  // 16
s.name;  // "Square"
s.joke; // undefined
Square.joke // "I'm not classy"
Rectangle.joke //  "I'm not classy"


// with prototypes & Object.create()

function Oval(width, height) {

    // Classes don't need the check below,
    // they automatically generate an error
    // if you call the constructor without new    
    if (!this) {
        console.error("Please call with new");
        return;
    }

    this.width = width;
    this.height = height;
}

Oval.joke = "I'm really not classy";
Oval.prototype.name = "Oval";
Oval.prototype.area = function () {
        return Math.PI * this.height * this.width;
};

function Circle(r) {
    return Oval.call(this, r, r);
}

Circle.prototype = Object.create(Oval.prototype, {
    constructor: {
        value: Circle,
        enumerable: false,
        writeable: true,
        configurable: true,
    },
});

Circle.prototype.name = "Circle";

var c = new Circle(4);
c.area();  // 50.26548245743669
c.name;  // "Circle"
c.joke; // undefined
Circle.joke // undefined
Oval.joke //  "I'm really not classy";