Save 10% off ANY FITC event with discount code 'slideshare'
See our upcoming events at www.fitc.ca
ECMA5 has given JavaScript a number of new ways to define and manipulate objects. In this session, attendees will learn how to combine Require.js and ECMA5’s object manipulation functions to create an inheritance model similar to class-based languages.
UiPath Community: Communication Mining from Zero to Hero
ECMA5 approach to building JavaScript frameworks with Anzor Bashkhaz
1. ECMA5 approach to writing JavaScript
frameworks
Anzor Bashkhaz
@anzor_b
Isaac Gordezky
@igordezky
2. ECMA5
What is ECMA5?
• ECMAScript = language of JavaScript
• Final draft for v5 presented in April 2009
• Object creation/manipulation
• Supported in all major platforms
http://kangax.github.io/es5-compat-table/
3. API design
What is an API?
• API exposes ways to use a library/framework
• Ex: underscore
• Users of API can’t see implementation
• aka. Public API
6. Type
What is a type?
• Instance factory
• JavaScript ‘Object’ is a type
• Made up of:
• Constructor (returns new instance)
• Static methods (create, call,…)
• Prototype
7. Type
What is a type?
• Instance factory
• JavaScript ‘Object’ is a type
• Made up of:
• Constructor (returns new instance)
• Static methods (create, call,…)
• Prototype
8. Prototype
What is a prototype?
• Prototype = definition for new instances
• = Public API
• Object.prototype
9. Prototype
What is a prototype?
• Prototype = definition for new instances
• = Public API
• Object.prototype
10. Inside an instance
Ex: Dissecting the instance of Object
var foo = {
hello : function(){
return “hello world”;
}
};
console.log(foo);
11. Inside an instance
Ex: Dissecting the instance of Object
var foo = {
hello : function(){
return “hello world”;
}
};
console.log(foo);
12. Inside an instance
Ex: Dissecting the instance of Object
var foo = {
hello : function(){
return “hello world”;
}
};
console.log(foo);
What is __proto__?
13. __proto__
“Special” property on every JavaScript Object.
• foo was created from Object.
var foo = {}
• __proto__ of foo points at prototype of Object.
• Object.create(definition)
• Returns object (instance) with __proto__ pointing at
definition
• Returned object can be Object.create’d again and again
15. __proto__
Ex: Prototype chain and simple inheritance
var foo = {};
var bar = Object.create(foo);
bar inherits methods from foo, while foo inherits methods from Object.
17. Custom Types
Ex: create type with name “type<Shape>”
var Shape = {};
Shape.constructor = { name: “type<Shape>" };
• Makes it easier to read in console versus “Object”
18. Custom Types
Ex: Add a prototype so instance are called “Shape”
• Add a prototype property
Shape.prototype = {};
• Set prototype.constructor.name to “Shape”
Shape.prototype.constructor = { name: “Shape” };
19. Custom Types – constructor
Ex: Add a constructor that returns instance of Shape
• Object.create() creates a new unique instance of Shape
Shape.create = function(){
return Object.create(Shape.prototype);
};
var shape1 = Shape.create();
var shape2 = Shape.create();
shape1.color = “blue”;
20. Custom Types – constructor
Ex: Add a constructor that returns instance of Shape
• Object.create() creates a new unique instance of Shape
Shape.create = function(){
return Object.create(Shape.prototype);
};
var shape1 = Shape.create();
var shape2 = Shape.create();
shape1.color = “blue”;
22. Defining Properties
• Good API design = preventing unintended use
• Read-only properties
Object.defineProperty(object, propertyName, descriptor)
• Descriptor
• Enumerable
• Configurable
• Writable
• Value
Read more at MDN (http://mzl.la/1cCtwPN)
23. Defining Properties
• Enumerable
true if the property is present while iterating through the object. (for prop in obj).
Defaults to false.
• Configurable
true if the property descriptor can be modified or property deleted on object.
Defaults to false.
• Writable
true if the property’s value can be changed? ( radius= 20)
Defaults to false.
• Value
Value of the property
31. Getters and Setters
• Important concept in framework design (especially UI)
• Backbone.js uses “set()” method
Ex: model.set(propertyName, value);
> “change” event triggered
> Views update their UI
• Ideally we want:
shape1.color = “blue”;
> This should trigger a color change (using DOM/canvas)
• Possible with Object.defineProperty
ECMA5 way to define setters/getters
32. Getters and Setters
Ex: Define setter for color to notify of change
var circle = {},
var currentValue;
Object.defineProperty(circle, “color”,
{
get: function(){
return currentValue;
},
set : function(value){
currentValue = value;
console.log(“color changed to “ + value);
}
});
33. Getters and Setters
Ex: Define setter for color to notify of change
var circle = {},
var currentValue;
Object.defineProperty(circle, “color”,
{
get: function(){
return currentValue;
},
set : function(value){
currentValue = value;
console.log(“color changed to “ + value);
}
});
34. Getters and Setters
Ex: Helper function for defining properties
var defineProperty = function(object, propertyName) {
Object.defineProperty(object, propertyName, {
get : function() {
return object[propertyName];
},
set : function(value) {
object[propertyName] = value;
console.log(propertyName + "changed to " + value);
}
});
};
var circle2 = {};
defineProperty(circle2, "color");
35. Beyond Private
Covered so far:
Public
• Leverages inheritance pattern
• Final instance has access to all methods in __proto__ chain
Private
• Instance specific data unexposed to the outside
What about inheriting non-public methods?
Protected to the rescue!
Protected
• Leverages inheritance pattern
• Allows child types to re-implement methods from their parents.
• Provides non-public APIs to child types.
37. extend!
• Declarative syntax for public, private and protected
functions
• hooks for init and destroy
• Public values are defined as:
• Property getters/setters on public
• Property stored in privateArea
• Non-functions in public create notifiable properties
Ex: size triggers sizeChanged()
• All methods have ‘this’ pointing to the privateArea
• Uses require.js’ plugin system to hide parser
39. Shapes
Objective: Build an API to draw shapes using HTML5 canvas.
type<Shape>
• Manage canvas and DOM
• Properties: color
• Protected interface: resize
• Abstract interface: draw
type<Circle> extends type<Shape>
• Implements draw interface
• Properties: radius
• Leverages resize interface
40. Shape.color: a property
Shape.color (Public)
• Property available on any shape object
Shape.colorChanged (Private)
• Automatically triggered when the color
property is changed
• Triggers a re-draw
Shape.color (Private)
• Stores the value of color in Shape’s privateArea
• Allows Shape’s methods to access color
without the setter/getter
41. Shape.resize: a protected interface
Size
• Public read-only property of Shape
• Stored in the privateArea of Shape
Resize
• Exposed to child types through protected
• Sets size in the privateArea of Shape
• Resizes DOM elements
Radius
• Public property of Circle
• Triggers protected Shape.resize
42. Shape.draw: a virtual method
Shape.draw (Public)
• Public draw API for all Shapes
• Calls virtual draw with canvas context
from Shape’s privateArea
Shape.draw (Protected)
• Abstract protected draw function
must be overridden by child classes
Circle.draw (Protected)
• Overrides Shape.draw (Protected)
• Doesn’t know or care where context
came from
Since the purpose of a type is to create an instance out of the protoype, our Shape type needs a create function, that returns a new instance of a shape.(We need to Object.create the prototype, otherwise every instance of shape will point at the same prototype instead of being separate instances.)Next, we’ll create two instances of Shape and assign a blue color to one.[var shape1 = Shape.create();var shape2 = Shape.create();shape1.color = “blue”;>shape1>shape2](Both shapes have a color property of blue, and this is because they both point at the same object (Shape.prototype).What we need to do is to Object.create(Shape.prototype).)Now only shape1 has a color of blue, which is the desired effect.So we have our Shape type which spawns shape instances, but there are a few problems.The constructor object is visible and users can edit it. This will lead to unintended use of the type or instance, which needs to be avoided when desiging a good API. Therefore, we need to lock constructor so users are not able to override it or delete it. This brings us to the next section: Property Definitions.
Since the purpose of a type is to create an instance out of the protoype, our Shape type needs a create function, that returns a new instance of a shape.(We need to Object.create the prototype, otherwise every instance of shape will point at the same prototype instead of being separate instances.)Next, we’ll create two instances of Shape and assign a blue color to one.[var shape1 = Shape.create();var shape2 = Shape.create();shape1.color = “blue”;>shape1>shape2](Both shapes have a color property of blue, and this is because they both point at the same object (Shape.prototype).What we need to do is to Object.create(Shape.prototype).)Now only shape1 has a color of blue, which is the desired effect.So we have our Shape type which spawns shape instances, but there are a few problems.The constructor object is visible and users can edit it. This will lead to unintended use of the type or instance, which needs to be avoided when desiging a good API. Therefore, we need to lock constructor so users are not able to override it or delete it. This brings us to the next section: Property Definitions.
After we have sensed the user, the device and its surrounding environment comes UNDERSTAND. What it really means is we need to take all our senses together and marry them with data on the device and the cloud and interpret those senses in our app’s context. This could be as simple as reading PIM data on the device to all the way up to retrieving relevant data from the cloud. Let me show you what we’ve done to enable this.
The purpose of this session is to go over patterns that help design good APIs using tools provided by ECMA5.