Changes to JavaScript, Part 1: EcmaScript 5 Mark S. Miller, Waldemar Horwat, Mike Samuel Your EcmaScript committee representatives.

Slides:



Advertisements
Similar presentations
JavaScript I. JavaScript is an object oriented programming language used to add interactivity to web pages. Different from Java, even though bears some.
Advertisements

Introducing JavaScript
Semantics Static semantics Dynamic semantics attribute grammars
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Winter 2013.
Composition CMSC 202. Code Reuse Effective software development relies on reusing existing code. Code reuse must be more than just copying code and changing.
1 CSC 551: Web Programming Spring 2004 client-side programming with JavaScript  scripts vs. programs  JavaScript vs. JScript vs. VBScript  common tasks.
WEAVING CODE EXTENSIONS INTO JAVASCRIPT Benjamin Lerner, Herman Venter, and Dan Grossman University of Washington, Microsoft Research.
GATEKEEPER MOSTLY STATIC ENFORCEMENT OF SECURITY AND RELIABILITY PROPERTIES FOR JAVASCRIPT CODE Salvatore Guarnieri & Benjamin Livshits Presented by Michael.
Presented by Vaibhav Rastogi.  Advent of Web 2.0 and Mashups  Inclusion of untrusted third party content a necessity  Need to restrict the functionality.
Compilation Encapsulation Or: Why Every Component Should Just Do Its Damn Job.
Jacaranda – language properties Statically verifiable subset of bug-fixed ES3. Object-capability language with strongly encapsulated objects. Methods can.
JSON, ADsafe, and Misty Douglas Crockford Yahoo!.
Working with JavaScript. 2 Objectives Introducing JavaScript Inserting JavaScript into a Web Page File Writing Output to the Web Page Working with Variables.
Javascript Client-side scripting. Up to now  We've seen a little about how to control  content with HTML  presentation with CSS  Javascript is a language.
Kevin Reuter & Brian Guthrie.  Multi-paradigm  Prototype based objects  Dynamic, weak typing.
Liang, Introduction to Programming with C++, Second Edition, (c) 2010 Pearson Education, Inc. All rights reserved Chapter 9 Objects and Classes.
XP Tutorial 1 New Perspectives on JavaScript, Comprehensive1 Introducing JavaScript Hiding Addresses from Spammers.
Taking JavaScript Seriously IS NOT THE WORST IDEA.
CSE 331 Software Design & Implementation Hal Perkins Autumn 2012 Java Classes, Interfaces, and Types 1.
1 JavaScript. 2 What’s wrong with JavaScript? A very powerful language, yet –Often hated –Browser inconsistencies –Misunderstood –Developers find it painful.
JavaScript: The Language Andrew Miadowicz Program Manager DEV307.
Functional Programming in Scheme and Lisp. Overview In a functional programming language, functions are first class objects. You can create them, put.
Programming Language C++ Xulong Peng CSC415 Programming Languages.
Introduction to JavaScript Gordon Tian
CMPS 211 JavaScript Topic 1 JavaScript Syntax. 2Outline Goals and Objectives Goals and Objectives Chapter Headlines Chapter Headlines Introduction Introduction.
1 JavaScript in Context. Server-Side Programming.
XP Tutorial 10New Perspectives on Creating Web Pages with HTML, XHTML, and XML 1 Working with JavaScript Creating a Programmable Web Page for North Pole.
Functional Programming and Lisp. Overview In a functional programming language, functions are first class objects. In a functional programming language,
20-753: Fundamentals of Web Programming 1 Lecture 12: Javascript I Fundamentals of Web Programming Lecture 12: Introduction to Javascript.
Hello.java Program Output 1 public class Hello { 2 public static void main( String [] args ) 3 { 4 System.out.println( “Hello!" ); 5 } // end method main.
Formal Semantics Chapter Twenty-ThreeModern Programming Languages, 2nd ed.1.
Objects & Dynamic Dispatch CSE 413 Autumn Plan We’ve learned a great deal about functional and object-oriented programming Now,  Look at semantics.
Martin Kruliš by Martin Kruliš (v1.0)1.
4.4 JavaScript (JS) Deitel Ch. 7, 8, 9, JavaScript & Java: Similarities JS (JavaScript) is case-sensitive Operators –arithmetic: unary +, unary.
Recap form last time How to do for loops map, filter, reduce Next up: dictionaries.
XP Tutorial 10New Perspectives on HTML and XHTML, Comprehensive 1 Working with JavaScript Creating a Programmable Web Page for North Pole Novelties Tutorial.
Topic 1 Object Oriented Programming. 1-2 Objectives To review the concepts and terminology of object-oriented programming To discuss some features of.
CSE 341 Lecture 29 a JavaScript, the bad parts slides created by Marty Stepp see also: JavaScript: The Good Parts, by.
JavaScript Scripting language What is Scripting ? A scripting language, script language, or extension language is a programming language.
ECMAScript 3.1 Object Model Allen Wirfs-Brock Microsoft.
Java Basics Opening Discussion zWhat did we talk about last class? zWhat are the basic constructs in the programming languages you are familiar.
1 JavaScript in Context. Server-Side Programming.
1 JavaScript 2.0: Evolving a Language for Evolving Systems Waldemar Horwat Netscape.
Understanding Character Encodings Basics of Character Encodings that all Programmers should Know. Pritam Barhate, Cofounder and CTO Mobisoft Infotech.
Rich Internet Applications 2. Core JavaScript. The importance of JavaScript Many choices open to the developer for server-side Can choose server technology.
IS2803 Developing Multimedia Applications for Business (Part 2) Lecture 2: Introduction to IS2803 Rob Gleasure
CSE 374 Programming Concepts & Tools Hal Perkins Fall 2015 Lecture 4 – Shell Variables, More Shell Scripts.
CMSC 330: Organization of Programming Languages Operational Semantics.
Announcements Assignment 2 Out Today Quiz today - so I need to shut up at 4:25 1.
XP Tutorial 10New Perspectives on HTML, XHTML, and DHTML, Comprehensive 1 Working with JavaScript Creating a Programmable Web Page for North Pole Novelties.
IST 210: PHP Basics IST 210: Organization of Data IST2101.
Operational Semantics of Scheme
CSE 374 Programming Concepts & Tools
CS5220 Advanced Topics in Web Programming JavaScript and jQuery
Game-Changing Features in ES2015
September 4, 1997 Programming Languages (CS 550) Lecture 6 Summary Operational Semantics of Scheme using Substitution Jeremy R. Johnson TexPoint fonts.
Dr. Charles W. Kann III JavaScript Objects Dr. Charles W. Kann III
Scope, Objects, Strings, Numbers
Modern JavaScript Luke Hoban Program Manager — JavaScript
Intro to PHP & Variables
JavaScript an introduction.
CS5220 Advanced Topics in Web Programming JavaScript Basics
CS5220 Advanced Topics in Web Programming Node.js Basics
CS3220 Web and Internet Programming JavaScript Basics
6.001 SICP Variations on a Scheme
JavaScript CS 4640 Programming Languages for Web Applications
CS3220 Web and Internet Programming JavaScript Basics
Chengyu Sun California State University, Los Angeles
JavaScript CS 4640 Programming Languages for Web Applications
Presentation transcript:

Changes to JavaScript, Part 1: EcmaScript 5 Mark S. Miller, Waldemar Horwat, Mike Samuel Your EcmaScript committee representatives

Brief History EcmaScript stuck at ES3 since 1999 Several attempts at feature “rich” ES4. Successful ES3.1 simplification, renamed ES5 IE, FF implementations almost beta. Progress at Opera,v8, …. Not yet Safari. meld(ADsafe,Caja, … ) → Secure EcmaScript Four synergies between SES and ES5 ES-Harmony agreement on future directions Lexical scoping, classes as sugar

EcmaScript 5 Overview Theme: Emulate Platform (DOM) Objects Accessor (getter / setter) properties Property attribute control Theme: More Robust Programming Tamper-proof objects Wart removal, clarifications, and exchanges Strict mode Theme: New APIs Higher order array methods JSON Function.prototype.bind

EcmaScript 5 Overview Theme: Emulate Platform (DOM) Objects Accessor (getter / setter) properties Property attribute control Theme: More Robust Programming Tamper-proof objects Wart removal, clarifications, and exchanges Strict mode Theme: New APIs Higher order array methods JSON Function.prototype.bind

Aren't standards doomed to grow? New standard must be practically upward compatible Not from ES3, but from cross-browser web corpus. Annoying differences → opportunity for committee. 3 of 4 browser rule + experience & sense.

Aren't standards doomed to grow? New standard must be practically upward compatible Not from ES3, but from cross-browser web corpus. Annoying differences → opportunity for committee. 3 of 4 browser rule + experience & sense. Opt-in for strict code: "use strict"; Mostly subtractive! Better for new code, for novices & experts. Not purely compatible, but good code ports easily.

Problem: Can’t emulate platform objects domObject.innerHTML = …; Object.prototype.myToString = …; for (var k in {}) { //Sees ‘myToString’ but not ‘toString’. } Primitives have powers unavailable in JS. Can’t transparently emulate or wrap.

Accessor (getter/setter) properties domNode.innerHTML ES3 can’t create properties which compute on assignment or reading. Mozilla, others, provide getter/setter properties, though with divergent semantics. Popular, useful. Codify proven practice.

Accessor (getter/setter) properties… …by enhanced object literal: var domoid = { foo: ‘bar’, get innerHTML() { return …; }, set innerHTML(newHTML) { … } }; …by explicit control (later)…

Need property attribute control ES3 semantics define per-property attributes: ReadOnly → writable: does assignment work? DontEnum → enumerable: does for-in see it? DontDelete → configurable: can its shape change? ES3 code can only create properties that are writable, enumerable, and deletable. Now controllable by ES5 code.

Property attribute control API Object.create(p,{(n:attrs)*}).defineProperty(o,n,attrs).defineProperties(o,{(n:attrs)*}).getOwnPropertyNames(o) → names.getOwnPropertyDescriptor(o,n) → attrs.freeze(o) → o attrs ::= { value:v, writable:b, enumerable:b, configurable:b } | …

Example: Unobtrusive Convenience Methods Object.defineProperty(Object.prototype, ‘myToString’, { value: …, writable: true, enumerable: false, configurable: true } for (var k in {}) { //Doesn’t see ‘myToString’ or ‘toString’ }

Accessor (getter/setter) properties… …by enhanced attribute control API Object.defineProperty(domoid, 'innerHTML',{ get: function() { return …; }, set: function(newHTML) { … } }); attrs ::= … | { get:f()→v, set:f(v), enumerable:b, configurable:b }

Practical emulation of host objects Property attribute control + Accessor (getter/setter) properties = Able to emulate DOM API in ES code Puts library developers more on par with platform (browser) providers

ES3 Makes Robustness Too Hard ES3 is full of traps and minefields. Defensive programming impossible Objects are merely mutable maps of properties. Silent errors. Did this assignment really happen? Even lexical closures aren't quite encapsulated. Toxic leaks of the global object ( window )

More Robust Programming in ES5 Tamper proof objects Objects can be sealed or frozen. Primordial objects should be frozen after initialization. Wart removal, clarification, and exchanges Defensive "strict " code Noisy errors – assumption violations throw. Static scoping. Functions really encapsulated. No implicit wrapping. No global object leakage.

What’s the Point? Can’t preserve invariants in ES3 function Point(x, y) { this.x = +x; this.y = +y; } var pt = new Point(3,5); pt.x = 'foo'; //Clobbers pt’s consistency Modular oo programming: Clients make requests of providers. Provider’s responsibility to maintain own invariants.

Tamper proof objects Object.create(p,{(n:attrs)*}).defineProperty(o,n,attrs).defineProperties(o,{(n:attrs)*}).getOwnPropertyNames(o) → names.getOwnPropertyDescriptor(o,n) → attrs.freeze(o) → o attrs ::= { value:v, writable:b, enumerable:b, configurable:b } | …

Tamper proof points, first try function Point(x, y) { return Object.freeze({ x: +x, y: +y }); } But Doesn’t inherit methods from Point.prototype. (new Point(3,4) instanceof Point) === false When adequate, stop here.

Tamper proof points, second try function Point(x, y) { return Object.freeze( Object.create(Point.prototype, { x: { value: +x, enumerable: true }, y: { value: +y, enumerable: true } })); } Correct. But verbose boilerplate.

Object.defineProperty(Function.prototype, ‘build’, { value: function(attrMap) { return Object.freeze(Object.create( this.prototype, attrMap)); }, writable: false, enumerable: false, configurable: false }); for (var k in n) … // not hurt Definition fails if Function.prototype frozen. Frozen object builder helper

Tamper proof points function Point(x, y) { return Point.build({ x: {value: +x, enumerable: true}, y: {value: +y, enumerable: true} }); } var pt = new Point(3,5); pt.x = 'foo'; // fails, as it should new Point(3,5) instanceof Point === true Point(3,5) instanceof Point === true

Scoping accident 1: Nested named function expressions function foo() { var x = 8; bar(function baz() { return x; }); } Object.prototype.x = 'foo'; Which x does “ return x ” return?

Scoping accident 1: Nested named function expressions function foo() { var x = 8; bar(function baz() { return x; }); } Object.prototype.x = 'foo'; Which x does “ return x ” return? ES3: 'foo'. Editorial error deployed by some browsers. ES5: Statically scoped where possible, so 8.

Finding Opportunity in Confusion When ES3 spec didn’t say what was meant, Some browsers obeyed letter. Some obeyed saner spirit. So cross-browser web is compatible with saner. ES5 can then be saner.

Scoping accident 2: Throwing a function function foo() { this.x = 11; } var x = ‘bar’; try { throw foo; } catch (e) { e(); … x … } ES3: Another editorial error deployed. ES5: Normal static scoping again.

Scoping accident 3: “as if by” initial or current? Object = Date; x = {}; //Assign to x a new what?

Scoping accident 3: “as if by” initial or current? Object = Date; x = {}; //Assign to x a new what? ES3 spec language: “ as if by the expression ' new Object() ' ” ES5 clarifies: initial values are meant.

Wart exchange: keyword collision ES3: domNode.className But html attribute is “class”. Renamed to avoid collision with keyword ES5:. { : … } Covers simple JSON property use. No syntactic ambiguity with keywords. Doesn't fix DOM, but stops digging deeper hole. OTOH, complicates grammar.

Wart removal: Backchannel function foo() { return (/x/); } ES3: foo() === foo() //Shared mutable state ES5: (/x/) ≡ new RegExp('x')

Wart exchange: eval in what scope? function foo(a, b, c) { return a(b); } foo(eval, 'c', 37); ES3: Returns 37? unclear ES5: An indirect eval. Uses global scope. But introduces additional concept.

Wart clarifications: Internal “ types ” Function vs Callable typeof f === 'function' → f is Callable ({}).toString.call(f) === '[object Function]' → f is a Function Non-functions may not claim to be functions Non-arrays, non-dates, etc… Implied invariants Non-array arguments inherits from Array.prototype. Dates try ISO format first

Strict mode: Support Defensive Code pt.x = 'foo'; // fails how? In ES3 or ES5-nonstrict: Failure is silent. Execution proceeds assuming success. Defense impractical. Can't check after every assignment to see if it succeeded. In ES5-strict code: Failed assignments throw.

Strict mode: Per script opt-in “use strict”; //… strict program

Strict mode: Per script or per function opt-in “use strict”; //… strict program … //… nonstrict program function foo() { “use strict”; //… body of strict function foo }

Strict mode: Per script or per function opt-in “use strict”; //… strict program … //… nonstrict program function foo() { “use strict”; //… body of strict function foo } Still parses on ES3 as a noop.

Nonstrict global object leakage function Point(x,y) { this.x = +x; this.y = +y; } var pt = Point(3,5); //Oops. Forgot “new” Nonstrict: {window.x = 3; window.y = 5;} Strict: {undefined.x = 3; undefined.y = 5;} Safer. And happens to throw quickly in this case

Nonstrict this-coercion hazards Boolean.prototype.not = function() { return !this; }; true.not() // ? false.not() // ?

Nonstrict this-coercion hazards Boolean.prototype.not = function() { return !this; }; Nonstrict: true.not() // false false.not() // false Strict: true.not() // false false.not() // true

ES5 functions encapsulated? function foo(x,y){bar();} function bar() { foo.arguments[0] = ‘gotcha’; }

ES5 functions encapsulated? function foo(x,y){bar();} Nonstrict: arguments joined to parameters. de facto: foo.caller, foo.arguments, arguments.caller de jure: arguments.callee function bar() { foo.arguments[0] = ‘gotcha’; }

ES5-strict functions encapsulated function foo(x,y){bar();} Nonstrict: arguments joined to parameters. de facto: foo.caller, foo.arguments, arguments.caller de jure: arguments.callee Strict: arguments not joined defused: foo.caller, foo.arguments, arguments.caller defused: arguments.callee All throw on access, to help catch porting bugs. Strict functions safe even from non-strict code.

function foo() { var xfoo = 4; … xFoo = 8; //Misspelling makes global var } with (o) {…} //Attractive idea badly botched delete foo; //Dynamically delete static var eval('var x=8'); x //Dynamically add static var All are fixed or rejected by ES5-strict. ES5-nonstrict isn't statically scoped

ES5-strict is statically scoped, but… function sqFnList(a) { var b = []; for (var i = 0; i < a.length; i++) { var sq = a[i] * a[i]; b[i] = function() { return sq; }; } return b; } sqFnList([3,4,5])[0]() // ?

But static scoping isn’t lexical scoping function sqFnList(a) { var b = []; for (var i = 0; i < a.length; i++) { var sq = a[i] * a[i]; b[i] = function() { return sq; }; } return b; } sqFnList([3,4,5])[0]() //Returns 25. Why?

But static scoping isn’t lexical scoping function sqFnList(a) { var b = []; for (var i = 0; i < a.length; i++) { var sq = a[i] * a[i]; b[i] = function() { return sq; }; } return b; } sqFnList([3,4,5])[0]() //Returns 25. Why? Because of var hoisting.

But static scoping isn’t lexical scoping function sqFnList(a) { var b = []; var sq; for (var i = 0; i < a.length; i++) { sq = a[i] * a[i]; b[i] = function() { return sq; }; } return b; } sqFnList([3,4,5])[0]() //Returns 25. Why? Because of var hoisting.

Lexical Scoping just missed ES5 train. How to cope? function sqFnList(a) { var b = []; var sq; for (var i = 0; i < a.length; i++) { sq = a[i] * a[i]; b[i] = function() { return sq; }; } return b; } sqFnList([3,4,5])[0]() //Returns 25. Why? Because of var hoisting.

Higher order array methods function sqFnList(a) { return a.map(function(ai) { var sq = ai * ai; return function() { return sq; } }); } sqFnList([3,4,5])[0]() //Returns 9. Whew. Closure-based iteration helps avoid var hoisting hazards

Higher order array methods anArray.forEach(fn(e,i)).map(f(e,i)→r) → array of rs.every(f(e,i)→boolean) → boolean // ∀.some(f(e,i)→boolean) → boolean // ∃.filter(f(e,i)→boolean) → subset.reduce(f(r,e,i)→r, r?) → r.reduceRight(f(r,e,i)→r, r?) → r

JSON: S-expressions of the web XML supposed to be S-expressions of the web. JSON: S-expression simplicity regained From instigator of ES3.1 simplification. Cross origin requests (XHR2,XDR) coming. How to obtain remote data? Today: Can parse quickly or safely, choose one JSONP → script tag → full vulnerability json2.js → regex guarded eval, thin ice full parser in JavaScript code → safe but slow json_sans_eval → best compromise today

JSON in ES5 JSON.stringify(value, replacer?) → string JSON.parse(string, reviver?) → value Structured (un)serialization customization The replacer/reviver idea from Java Serialization Streams. Immune to textual quoting confusions. Should be in Ecma or w3c DOM standard? EcmaScript. Also needed server side. Remaining hazard: Avoid \u2028, \u2029

Closures don’t capture “this” Foo.prototype.meth = function() { this.x = 3; this.y = 4; }

Closures don’t capture “this” Foo.prototype.meth = function() { this.x = 3; setTimeout(function(){this.y = 4;}, 2000); }

Function.prototype.bind() helps Foo.prototype.meth = function() { this.x = 3; setTimeout(function(){this.y = 4;}, 2000); } //Oops. Foo.prototype.meth = function() { this.x = 3; setTimeout( (function(){this.y = 4;}).bind(this), 2000); } //Whew.

Imperfect Lambda Abstraction in ES5 Tennet Correspondence Principle (TCP) Litmus test of lambda abstraction Blocks: {…} ≡ (function(){…})(); but for return, break, continue, this, arguments, var, function Expressions: (…) ≡ (function(){return …;})() but for this, arguments Non-TCP arguments, others don't hurt much. Non-TCP this is a common trap repaired by “.bind(this) ”.

Remaining fixable ES5 warts Static, not Lexical Scoping: const, let, nested named function declarations. Ambient global at bottom of scope chain. Spec wart: Multiple global objects? Regular Expressions process UTF-16 code units. Non-BMP, Combining chars → breaking change i18n → insufficient interest? Decimal? Mozilla to test the waters. Extensible numerics?

Conclusions ES3 decent for scripting in the small Hostile to robust serious programs. Too many odd corners between what beginners learn what they need to know. ES5-strict easier language to teach Better for scripting in the small. Much better for real programs. Actually good.

Further Reading Final draft standard “EcmaScript Fifth Edition” Pratap’s “JScript Deviations” wiki.ecmascript.org mail.mozilla.org/listinfo/es-discuss