Presentation is loading. Please wait.

Presentation is loading. Please wait.

JavaScript The Good and The Bad.

Similar presentations


Presentation on theme: "JavaScript The Good and The Bad."— Presentation transcript:

1 JavaScript The Good and The Bad

2 Caveat We are not studying JavaScript so that you can write better scripts for your web pages (although if you’ve done some JavaScript in the past, the info here may help you understand more about what’s really happening) We will not cover the DOM or many techniques used in web pages We will take a look at some of the more interesting aspects of JavaScript from a programming language design perspective Info from this lecture will be included on the next exam

3 Language Design An object “encapsulates” data and methods
Assume you want to create a new language that contains objects You want to keep it simple How can you create something that’s quick and easy to implement? Discuss with your partner: How would you implement classes? (what data structures would you use, etc.)

4 Data Types and Objects Primitive types are numbers, strings, boolean, null and undefined Everything else is an object An object is simply a mutable, keyed collection There are no classes! var my_cat = { name: "Geronimo", // no quote if legal name "coat-color": "orange" // coat_color legal }; document.writeln(my_cat.name); document.writeln(my_cat["coat-color"]); document.writeln(my_cat["color"]); //document.writeln(my_cat.coat-color);

5 More on objects Can add a property by assigning a value
my_cat.age = 3; document.writeln(my_cat.age); Objects are passed by reference Object keys are all strings

6 Prototypes In addition to the key/value properties, each object has a pointer to the object’s prototype document.writeln(Object.getPrototypeOf(my_cat)); If not set explicitly, this will be [object Object] Prototype link is used only in retrieval

7 Prototypes – simple example
Wordy version (new syntax) Object.create(proto[, propertiesObject]) var cat = Object.create(null); Object.defineProperty(cat, 'sound', {value: "meow", writable: true }); // can also set enumerable and configurable var stray_cat = Object.create(cat); Object.defineProperty(stray_cat, 'name', {value: "Sigfried", writable: true}); stray_cat['coat-color'] = "tuxedo"; document.writeln(stray_cat['name']); document.writeln(stray_cat['coat-color']); document.writeln(stray_cat['sound']);

8 Prototypes, continued common to override toString
The process of using the chain of prototypes to retrieve properties is known as delegation. If the property is not on the chain, the result is undefined. Example from:

9 Augmenting the basic types
Number.prototype.integer = function(){ return Math[this < 0 ? 'ceil':'floor'](this); } document.writeln(10/3); document.writeln((-10 / 3).integer()); document.writeln((10 / 3).integer()); How does this compare to Ruby? See:

10 Augmenting Object o1 = {x: 2};
Object.prototype.doSomething = function() { document.writeln("Just do it!"); } o1.doSomething(); o2 = {y: 3}; o2.doSomething(); How do you accomplish this in other languages? Think about: features to add behavior, vs features to organize behavior

11 Namespace JavaScript issue: there’s a tendency to use global variables to contain all the data for an app. Clearly this can lead to reliability and maintainability issues. A namespace is a container which allows developers to bundle up all functionality under a unique, application-specific name. In JavaScript a namespace is just another object containing methods, properties and objects. Some guidelines (beyond our scope, really): Place the namespace declaration in its own file That file can be included in all app files (e.g., XUL) Link has some guidelines for naming convention For this course, interesting aspect is how JS handles namespace compared to other languages.

12 Functions – Powerful Stuff!
Functions are objects Include two additional hidden properties: context and code Object Object.prototype hidden { name: value name2: value2 fnName: function} Object hidden Function.prototype { name: value name2: value2 } context code

13 First-class objects Can be stored in variables, objects and arrays
Can be passed as arguments to functions Can be returned from functions Can have methods Special property: they can be invoked var add = function(a, b) { return a + b; } document.writeln(add(5,6)); document.writeln(add(5,6,7));

14 Function invocation Invocation operator is ()
Parameters inside (), separated by commas May have more values than parameters (just ignored) May have more parameters than values (set to undefined) No type checking Two additional parameters, this and arguments Four different invocation patterns: Method invocation – similar to instance method Function invocation Constructor invocation Apply invocation Differ in how this is initialized from JavaScript: The Good Parts

15 #1 Method invocation Function can be stored as property of an object
this will be bound to the calling object var myObject = { value: 0, increment: function(inc) { this.value += typeof inc === 'number' ? inc : 1; } }; myObject.increment(); document.writeln(myObject.value); myObject.increment(3);

16 #2 Function invocation this is bound to global object
causes issues with inner functions (covered later)

17 #3 Constructor invocation
If objects are hash tables, how do we create an object? With a function that sets up the table (i.e., properties) Functions intended to be used with new prefix are called constructors The new prefix causes an object to be created with a hidden link to the function’s prototype method, and this is bound to the new object This syntax is typically used with classes… but JavaScript has prototypes. Just caused confusion (not recommended, and JavaScript has Object.create syntax) NOTE: Why cover this, if it’s not recommended? Because it’s good to think about mistakes that have been made in language design. Also, lots of old examples online… in many languages.

18 Constructor example var Quo = function(string) { this.status = string; // implicit return value is this }; // Must have prototype, otherwise not shared with // new object. Quo.prototype.get_status = function() { return this.status; // Quo is a function object // Putting new in front of it causes a new // object to be created, with properties defined in ctor var myQuo = new Quo("confused"); document.writeln(myQuo.get_status()); Quick Ex: Review slide 12, draw pictures of what’s going on here NOTE: we don’t know exactly, but good to think about

19 #4 Apply/call invocation function
function sum() { var result = 0; // note the use of the arguments array for (var i = 0; i < arguments.length; i++) { result += arguments[i]; } return result; var args = [1,2,3]; // first argument to apply is the context // in other words, this // second is an array sum.apply(null, args); // will return 6 From:

20 Apply invocation with context
var obj = { data:'Hello World' } var displayData = function() { document.writeln(this.data); displayData(); //undefined, no global data displayData.apply(obj); //Hello World // call is similar to apply, but it takes // an argument list rather than an array displayData.call(obj); // empty arg list From:

21 Another call/apply example
var x, o1, o2, r1, r2, r3; x = 4; o1 = {x: 2}; o2 = {x: 7}; f = function(m, n) {return m * n * this.x;}; r1 = f(3, 1); r2 = f.call(o1,3, 1); r3 = f.apply(o2,[3, 1]); document.writeln(r1); document.writeln(r2); document.writeln(r3); From:

22 Usage brainstorm How/when might we use apply and/or call?
// Say a greeting to any object with a name say_hello = function() { return "Hello " + this.name; } // Add random health to any object with health inc_health = function() { this.health = Math.floor((Math.random() * 100) + 1); } // Assumes o1 already exists as an object o1.name = "Cyndi"; o1.health = 5; document.writeln(say_hello.call(o1)); inc_health.call(o1); document.writeln(o1.health); Quick Discussion: How does this compare to Ruby?

23 Scope Most C-inspired languages have block scope
JavaScript has blocks… but not block scope (function scope) var foo = function() { var a=3, b=5; var bar = function() { var b=7, c=11; a += b + c; document.writeln("a: "+a+" b: "+b+" c: " + c); } bar(); document.writeln("a: " + a + " b: " + b); foo(); Info: Crockford +

24 Scope example C# doesn’t compile JavaScript
public void TestScope() { if (true) { int i = 5; } i.ShouldEqual(5); // does not compile var foo = function() { // this is recommended: // var a; if (true) { // but this works var a = 5; } alert(a); foo(); From:

25 Inner functions Inner functions get access to the parameters and variables of the functions they are defined within except this and arguments Issues!!

26 Inner functions example
var add = function(a, b) { return a + b; } var anObject = { value: 4, }; // this not set properly anObject.doubleIt = function() { var helper = function() { this.value = add(this.value, this.value); helper(); document.writeln("before doubleIt"); document.writeln(anObject.value); anObject.doubleIt(); document.writeln("after doubleIt");

27 Inner function - workaround
anObject.doubleMe = function() { var that = this; var helper = function() { that.value = add(that.value, that.value); }; helper(); document.writeln("before double"); document.writeln(anObject.value); anObject.doubleMe(); document.writeln("after double");

28 Sidebar: first-class functions
// avoid repeated code on previous slide anObject.someFn = function(func) { document.writeln("before fn value"); document.writeln(anObject.value); func.call(this); document.writeln("after fn value"); }; // passing the function as an argument anObject.someFn(anObject.doubleIt); anObject.someFn(anObject.doubleMe);

29 Closure (from Wikipedia)
technique for implementing lexically scoped name binding in languages with first-class functions lexical scope – based on program text, determined statically (compile time, not runtime) first-class functions - treats functions as first-class citizens. Specifically, this means the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures. Operationally, a closure is a record storing a function together with an environment: a mapping associating each free variable of the function (variables that are used locally, but defined in an enclosing scope) with the value or storage location to which the name was bound when the closure was created.

30 Closures* *brief intro, you’ll explore in homework var quo2 = function(status) { // returning an object with get_status method return { // even after quo2 ends, will have access to // copy of parameter, via the context get_status: function() { return status; } }; var myQuo = quo2("amazed"); document.writeln(myQuo.get_status()); myQuo.status = "dazed"; Examples from JavaScript: The Good Parts

31 Another closure example
var fade = function (node) { var level = 1; var step = function() { var hex = level.toString(16); node.style.backgroundColor = '#FFFF' + hex + hex; if (level < 15) { level += 1; setTimeout(step, 100); } }; // will call step after 100 milliseconds (1/10th sec) // fade already returned, but its variables (e.g., level) // live on inside this closure. fade(document.body);

32 Final closure example var addScore = (function(points) {
var score = 0; return function (points) { return score+=points; } })() document.writeln(addScore(5)); document.writeln(addScore(7)); Idea: if points stored in global var, anything could change. This way, score is protected in a closure.

33 Related var scoreChanger = (function(points){ var score = 0; var operation = { add: function(points) {return score += points;}, sub: function(points) {return score -= points;}, mult: function(points) {return score *= points;}, div: function(points) {return score /= points;} } return operation; })() scoreChanger.add(1); document.writeln(scoreChanger.add(2)); document.writeln(scoreChanger.mult(5));

34 Callbacks Another use for functions, dealing with asynchronous events
Naïve way to make a server request (freeze til get response): request = prepare_the_request(); response = send_request_synchronously(request); display(response); A better approach send_request_asynchronously(request, function(response) { }); Again, passing a function as an argument

35 Memoization Remembering the results of previous operations, so as to avoid unnecessary work call_count = 0; var fibonacci = function(n) { call_count += 1; return n < 2 ? n : fibonacci(n-1) + fibonacci(n-2); }; document.writeln("\nNAIVE FIBONACCI"); for (var i=0; i<=10; i += 1) { document.writeln('// ' + i + ':' + fibonacci(i)); } document.writeln("count of calls: " + call_count); In-Class: TRACE these pages Cool example from JavaScript: The Good Parts

36 Memoized Fibonacci for (var i=0; i<=10; i += 1) {
var fib_count = 0; var fibonacci2 = function() { var memo = [0,1]; var fib = function(n) { fib_count += 1; var result = memo[n]; if (typeof result != 'number') { result = fib(n-1) + fib(n-2); memo[n] = result; } return result; }; return fib; }(); for (var i=0; i<=10; i += 1) { document.writeln('// ' + i + ':' + fibonacci2(i)); } document.writeln("count of calls: " + fib_count); fib_count is 29 11 calls in for loop only 18 to calculate values

37 General purpose memoizer
var memoizer = function (memo, fundamental) { var shell = function(n) { var result = memo[n]; if (typeof result != 'number') { result = fundamental(shell, n); memo[n] = result; } return result; }; return shell; var fibonacci3 = memoizer([0,1], function(shell, n) { return shell(n-1) + shell(n-2); }); document.writeln("Fibonacci 10: " + fibonacci3(10)); var factorial = memoizer([1,1], function(shell, n) { return n * shell(n-1); document.writeln("Factorial 5: " + factorial(5));

38 Object-based vs Object-oriented

39 Closures Recap Closure = function + environment
a mapping associating each free variable of the function (variables that are used locally, but defined in an enclosing scope) with the value or storage location to which the name was bound when the closure was created. If value – can’t change If storage location – can change

40 Recap continued function startAt(x) function incrementBy(y) return x + y return incrementBy variable closure1 = startAt(1) variable closure2 = startAt(5) closure1(3) will return 4 closure2(3) will return 8 Both have same function (incrementBy) but different environments.

41 Summary – Important topics
Object representation Function representation = Object + context + code Prototype-based (vs class-based) language Functions as first-class objects Closures Memoization

42 Less important 4 ways to call functions apply vs call namespace scope


Download ppt "JavaScript The Good and The Bad."

Similar presentations


Ads by Google