Download presentation
Presentation is loading. Please wait.
1
Martin Kruliš 9. 4. 2015 by Martin Kruliš (v1.0)1
2
Closure function make() { var x = 1; return function() { alert(x++); } } var f1 = make(); var f2 = make(); f1(); f2(); 9. 4. 2015 by Martin Kruliš (v1.0)2 make() f1() f2() make() f1() f2() global context [[Scope]] f1 function [[Scope]] f2 function x = 1 make() act. obj x = 1 make() act. obj
3
Binding Function Parameters ◦ Especially useful in case of callbacks function myCallback(data) {... handle callback with data... } function bindArg(fnc, data) { return function() { fnc(data); } myAjax.oncomplete = bindArg(myCallback, reqData); 9. 4. 2015 by Martin Kruliš (v1.0)3 Closure automatically snapshots arguments
4
Hiding Encapsulated Functionality ◦ Private functions, related data structures, … var searcher = (function(){ var lookupTable = [... ]; function findPattern(needle) {... } return function(needle, haystack) { var ptrn = findPattern(needle);... } })(); 9. 4. 2015 by Martin Kruliš (v1.0)4 Hidden data structure and function The outer function is immediately invoked and then forgotten
5
Accidental Closures ◦ Unnecessary closures increases memory footprint function addLinkHandler(link) { if (!link) return; link.onclick = function() { this.href += "?marked=1"; return true; } addLinkHandler(document.getElementById("link1")); 9. 4. 2015 by Martin Kruliš (v1.0)5 Event handler accidentally get hold of parents variable object which is not required by the handler
6
Naming Collisions in Scope Chain var module = (function(){ var param = 1; function updateParam(param) { param += 1; } return { func: function() { updateParam(param); } }; })(); 9. 4. 2015 by Martin Kruliš (v1.0)6 Function argument hides param variable, which was privatized by the scope chain Empty operation (does not modify param )
7
Methods (Functions in Object Properties) ◦ this keyword var obj = { x: 1; next: function() { this.x += 1; } }; obj.next(); ◦ Default value is the global context (e.g., window ) ◦ Using/binding different this (and arguments) fnc.apply(this, [args]), fnc.call(this,...) var fnc2 = fnc.bind(this,...); 9. 4. 2015 by Martin Kruliš (v1.0)7
8
Object Oriented Programming ◦ A way to model program components with objects ◦ Comprehensible way to express program parts ◦ Provide some useful concepts Encapsulation, Inheritance, and Polymorphism JavaScript ◦ Gives you objects and prototype chain ◦ Many ways how to implement OOP None is “the correct one” Use whatever fits your problem 9. 4. 2015 by Martin Kruliš (v1.0)8
9
Constructors var Circle = function(r) { // initialization this.radius = r; }; Circle.prototype = new GeometricObject(); var myCircle = new Circle(42); 9. 4. 2015 by Martin Kruliš (v1.0)9 this refers to the newly created object (geometric object) GeometricObject Circle.prototype Circle.prototype myCircle [[Prototype]] myCircle [[Prototype]] new
10
Naïve Approach function MyClass(init) { var privateMember; function privateMethod() {... } this.member = init; this.method = function() {... }; } var myObject = new MyClass(42); 9. 4. 2015 by Martin Kruliš (v1.0)10 Privacy achieved by closure Methods are created over and over with every instance
11
Naïve Approach function MyClass(init) { var privateMember; function privateMethod() {... } this.member = init; } MyClass.prototype.method = function() {... } var myObject = new MyClass(42); 9. 4. 2015 by Martin Kruliš (v1.0)11 Better, since the method is created only once and shared
12
Naïve Approach function MyClass(init) { var privateMember; function privateMethod() {... } this.privilegedMethod = function() {}; } MyClass.prototype.publicMethod = function() { … } var myObject = new MyClass(42); 9. 4. 2015 by Martin Kruliš (v1.0)12 Privileged method is public, but it can access private members
13
Private Members ◦ In the closure created by the constructor invocation ◦ Consider memory footprint of privileged methods ◦ Do you really need private members? Naming convention can achieve similar thing Static Members ◦ ~ members of the constructing function function MyClass() {... } MyClass.staticMember = 42; Virtual Methods ◦ No need – remember how prototype chain works 9. 4. 2015 by Martin Kruliš (v1.0)13
14
Simple Inheritance ◦ Using the prototype chain function Person() {... } Person.prototype.registerHobby = function(h)... function Student() {... } Student.prototype = new Person(); Student.prototype.visitCourse = function(c)... 9. 4. 2015 by Martin Kruliš (v1.0)14 Base “class” Makes Student inherit from Person The prototype object can be augmented
15
Operator instanceof ◦ Tests whether an object is instance of a constructor obj instanceof constructor ◦ Follows the prototype chain (respects inheritance) Instance without inheritance can be tested as Object.getPrototypeOf(o) === constr.prototype Multiple Inheritance ◦ Not directly supported ◦ Can be replaced by Swiss inheritance, traits, mixins, class augmentation, … 9. 4. 2015 by Martin Kruliš (v1.0)15
16
Parasitic Inheritance ◦ Using the prototype chain function Person() {... } Person.prototype.registerHobby = function(h)... function Student() { var that = new Person(); that.visitCourse = function(c)...... return that; } 9. 4. 2015 by Martin Kruliš (v1.0)16 Base “class” this is thrown away and replaced by augmented object of a different class
17
Efficiency Considerations ◦ Problem with simple inheritance SubClass.prototype = new ParentClass(); The parent class may have heavy constructor New parent object is required for each derived class ◦ Possible solution function ParentClass() {... } function SubClass() {... } var tmp = function() {}; tmp.prototype = ParentClass.prototype; SubClass.prototype = new tmp(); 9. 4. 2015 by Martin Kruliš (v1.0)17 New lightweight constructor, which uses the same prototype as parent class
18
Object.prototype.constructor ◦ Reference to a constructor that created the object ◦ Objects inherit constructor from their prototype ◦ Make sure, the constructor is set properly function ParentClass() {... } function SubClass() {... } SubClass.prototype = new ParentClass(); SubClass.prototype.constructor = SubClass; ◦ The constructor may be required when parent constructor needs to be called, or for object cloning 9. 4. 2015 by Martin Kruliš (v1.0)18
19
Prototypal Inheritance ◦ Complicated due to constructor indirection ◦ We can create a direct way to link prototypes function createPrototypeOf(o) { function F() {} F.prototype = o; return new F(); } ◦ Modern way in ECMAScript 5 Object.create(proto, params) 9. 4. 2015 by Martin Kruliš (v1.0)19
20
Class Augmentation ◦ Traits, Aggregates, Mixins, Swiss inheritance ◦ Copy (selected) methods (or other members) from one class (prototype) to current class for (var key in aggreg.prototype) { if (!(aggreg.prototype[key] instanceof Function)) continue; if (key in restictedNames) continue; this.prototype[key] = aggreg.prototype[key]; } ◦ You need to deal with overwriting problem 9. 4. 2015 by Martin Kruliš (v1.0)20
21
Creating Classes ◦ Getting complicated, many technical details ◦ Most implementations wraps the functionality function createClass(init) {... } Function.prototype.extend = function(init)... ◦ The parameter is an initialization object containing Initial and static values Methods List of mixin/augmentation classes … 9. 4. 2015 by Martin Kruliš (v1.0)21 Example
22
Object Properties ◦ obj.name = value or obj['name'] = value ◦ Object.defineProperty(obj, name, desc) Sets or modifies object property ◦ Descriptor object may contain: configurable – whether the descriptor can be changed enumerable – whether property is visible in keys and for data properties writeable – whether the value can be changed value – initial value of the property and for accessor properties get, set – getter/setter function 9. 4. 2015 by Martin Kruliš (v1.0)22
23
Object Properties ◦ Prevent adding new properties Object.preventExtensions(obj) Object.isExtensible(obj) ◦ Preventing adding or removing properties Object.seal(obj) Object.isSealed(obj) ◦ Preventing any property modifications Object.freeze(obj) Object.isFrozen(obj) 9. 4. 2015 by Martin Kruliš (v1.0)23
24
Making an Object Copy function clone(obj, deep) { if (typeof(obj) != 'object' || obj == null) return obj; // obj is simple value var res = new obj.constructor(); for (var attr in obj) if (obj.hasOwnProperty(attr)) { res[attr] = (deep === true) ? clone(obj[attr], deep) : obj[attr]; } return res; } 9. 4. 2015 by Martin Kruliš (v1.0)24
25
9. 4. 2015 by Martin Kruliš (v1.0)25
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.