Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

JavaScript OOP

3,593 views

Published on

Лекция Константина Кичинского по ООП в JavaScript в рамках курса по ООП. Каф. Вычислительная математика и программирование, МАИ

Published in: Technology

JavaScript OOP

  1. 1. JavaScript
  2. 2. Общие сведения o JavaScript
  3. 3. JavaScript: The World's Most Misunderstood Programming Language — Douglas Crockford, senior JavaScript Architect at Yahoo!
  4. 4. JavaScript != Java
  5. 5. JavaScript ~ ECMAScript JavaScript 1.5 ~ ECMAScript 3 JavaScript 2.0 ~ ECMAScript 5
  6. 6. Реализации JavaScript — V8, Google Chrome — TraceMonkey, SpiderMonkey, Gecko, Mozilla Firefox — Jscript, Trident, IE — Futhark, Presto, Opera — KJS, KHTML, Konqueror — JavaScriptCore, SquirreFish, WebKit, Safari, Adobe AIR
  7. 7. Инструменты для работы — Firebug, Firefox — DevTools (F12), IE8 — Dragonfly, Opera — Visual Studio, Expression Web — Aptana — Dreamweaver — …
  8. 8. Библиотеки на JavaScript — Prototype — jQuery — Mootools — Dojo — Ext — Qooxdoo — YUI — ASP.NET Ajax — …
  9. 9. Nearly all of the books about JavaScript are quite awful. They contain errors, poor examples, and promote bad practices. — Douglas Crockford, senior JavaScript Architect at Yahoo! http://javascript.crockford.com/
  10. 10. OOP в JavaScript
  11. 11. Типы данных: примитивы + объекты. Примитивы в общем-то тоже объекты.
  12. 12. Примитивы — Number — 1, 3, 1011, 11.12, 2e+3 — String — ―a‖, ―bla-bla-bla‖, ―0‖ — Boolean — true | false — null — undefined
  13. 13. Ссылочные типы — Date — new Date(1211623944453); — Error — new Error(―Oops!‖); — RegExp — /^web.*$/i; — Array — [ ―apple‖, ―banana‖ ] — Function — function(x) { return x*x; }
  14. 14. Примитивы Ссылочные типы Boolean Date Number Error String Object RegExp null Array undefined Function
  15. 15. Объекты — ассоциативные массивы, хеш-таблицы — Ключ: Значение
  16. 16. Простой объект var ufo= {}; ufo.name = ‗Mars UFO‘; ufo.stealsCows = true;
  17. 17. Простой объект var ufo= { stealsCows: true, isCowsStealer: function() { return this. stealsCows; } }; ufo.isCowsStealer(); //true
  18. 18. Объекты как хеш o.name = ―Moon UFO‖; o[―name‖] = ―Moon UFO‖; for ( var key in o ) { alert( key + ―: ― + o[key] ); }
  19. 19. Object literal notation { a: 1, b: ―js‖ }
  20. 20. Массивы тоже объекты [, ] typeof [ 1, 2, 3 ]; // ―object‖
  21. 21. Array literal notation [ 1, ―js‖ ]
  22. 22. JavaScript Object Notation (JSON ) { num: 1, str: ―abc‖, arr: [ 1, 2, 3 ] }
  23. 23. Функции Функции являются объектами! — Имеют свойства — Имеют методы — Могут копироваться, удаляться, … — Особенность: их можно вызвать/выполнить
  24. 24. Функции function steal(what) { return what; }
  25. 25. Функции var steal = function (what) { return what; }; * Здесь используется анонимная функция, об этом позже
  26. 26. Функции var steal = function steal(what) { return what; };
  27. 27. Функции являются объектами steal.length // 1 steal.name //‖steal‖
  28. 28. Функции являются объектами var snaffle = steal; snaffle(―Cow‖); //‖Cow‖ snaffle.call(null, ―Calf‖); //‖Calf‖ snaffle.apply(null, [ ―Calf‖ ]); //‖Calf‖
  29. 29. Возвращаемое значение • Все функции возвращают значение • Если функция ничего не возвращает явным образом, возвращается undefined • Функции могут возвращать объекты, включая другие функции
  30. 30. Вызов метода с нужной областью видимости При вызове moo this ссылается на указанную область видимости scope function moo() { this.BigSaucerEyes(); }; moo.call( scope, arg1, arg2, …); moo.apply( scope, [arg1, arg2, …] );
  31. 31. Тут начинается магия  Область видимости «по умолчанию» — Window var UFO = function UFO() { this.name = ―FO‖; return this; // посмотрим, что это за this }; UFO // UFO() UFO() // Window… Oops!!! Window.name is ―FO‖ new UFO() // Object name=―FO‖
  32. 32. Тут продолжается магия  var ufo = new UFO() эквивалентно var ufo = {}; UFO.call(ufo, null) ufo // Object name=―FO‖ Если this возвращается вручную внутри конструктора (return this), тогда можно писать var ufo = UFO.call({}, null);
  33. 33. Замыкания (Closures) • Соседние функции • Вложенные функции имеют доступ к локальным переменным даже после выполнения внешней функции
  34. 34. Замыкания (Closures) function outer() { var count = 1; function inner() { count++; }; return inner; } var myClosure = outer(); myClosure(); // count == 2 myClosure(); // count == 3
  35. 35. Функции-конструкторы • При вызове с оператором new функции возвращают объект, обозначаемый как this • Этот объект можно изменять перед передачей из фунции
  36. 36. Функции-конструкторы function UFO(name){ this.name = name; this.getName = function() { return this.name; }; };
  37. 37. Вызов функции-конструктора var ufo = new UFO(―Mars UFO‖); ufo.getName(); //‖Mars UFO‖
  38. 38. instanceof var ufo= new UFO(―Moon UFO‖); ufo instanceof UFO; // true
  39. 39. Конструкторы — всего лишь функции
  40. 40. Свойство constructor function UFO() {}; var ufo = new UFO(); ufo.constructor; // function(); UFO | function ufo.constructor === UFO; // true ufo | object constructor
  41. 41. Свойство constructor var o = {}; o.constructor === Object // true [1, 2].constructor === Array; // true
  42. 42. Встроенные конструкторы • Object • Array • Function • RegExp • Number • String • Boolean • Date • Error, SyntaxError, ReferenceError, …
  43. 43. Эффективность использования Хорошо Плохо var o = {}; var o = new Object(); var a = []; var a = new Array(); var re = /[a-z]/gmi; var re = new RegExp(‗[a-z]‘, ‗gmi‘); var fn = function(a, b) { var fn = new Function(‗a, b‘, ‗return return a+b; a+b‘); }
  44. 44. Статические свойства и методы Функции — объекты. Свойства и методы конструктора — работают как статические. UFO.COUNT = ―100500‖; UFO.getCount = function() { return UFO.COUNT; };
  45. 45. Private-члены function UFO(name) { var _name = name; // private variable this.getName = function() { return _name; }; }; var ufo= new UFO(―Mars UFO‖); alert( ufo.getName() );
  46. 46. Private-члены function UFO(name) { var _name = name; // private method var _fixName = function() { return _name.toUpperCase(); }; this.getName = function() { return _fixName(); }; };
  47. 47. Namespace if (typeof FlyingObjects== ―undefined‖) { FlyingObjects = {}; } if (typeof FlyingObjects.Undefined == ―undefined‖) { FlyingObjects.Undefined = {}; } FlyingObjects.Undefined.UFO = function() {}; var smallUFO = new FlyingObjects.Undefined.UFO;
  48. 48. В JavaScript нет классов.
  49. 49. Наследование копированием (примеси)
  50. 50. Два объекта var roundShinyObject= { shiny: true, round: true }; var ufo = { name: ―UFO‖, getName: function() { return this.name; } };
  51. 51. extend() function extend(parent, child) { for (var key in parent) { child[key] = parent[key]; } } extend(roundShinyObject, ufo); ufo.round; // true
  52. 52. Прототипное наследование
  53. 53. Prototype Специальное свойство функциональных объектов. prototype – это объект! var UFO = function () {}; typeof UFO.prototype; //‖object‖
  54. 54. Изменение prototype UFO.prototype.name = ―UFO‖; UFO.prototype.stealCow = function(){};
  55. 55. Перезапись prototype UFO.prototype= {name: ―UFO‖, cows: 2};
  56. 56. prototype используется при вызове функции-конструктора
  57. 57. Использование prototype var UFO = function(name) { this.name = name; }; UFO.prototype.stealCow = function() { // steal a cow };
  58. 58. Использование prototype var ufo= new UFO(―Mars UFO‖); ufo.name; // ―Mars UFO‖ ufo.stealCow(); // Cows--
  59. 59. Использование prototype stealCow() — метод объекта prototype, но ведет себя так, как будто является методом самого объекта ufo ufo.hasOwnProperty(‗name‘); // true ufo.hasOwnProperty(‗stealCow‘); // false ufo.prototype.hasOwnProperty(‗stealCow‘); // true
  60. 60. Привязка свойств и методов // к объекту this function Cow(name) { this.moo = function() { alert(―Moo‖) }; }; // к объекту prototype function Cow(name) {}; Cow.prototype.moo = function () { alert(―Moo‖) }; };
  61. 61. prototype используется при поиске метода или свойства
  62. 62. Поиск свойств и методов no undefined FO no found? yes UFO found? no yes ufo: UFO found? yes ufo.stealCow
  63. 63. isPrototypeOf() UFO.prototype.isPrototypeOf(ufo); // true Object.prototype.isPrototypeOf(ufo); // true
  64. 64. __proto__ Объекты имеют «секретную» ссылку на прототип конструктора, который их создал __proto__ может не поддерживаться в некоторых браузерах var UFO = function(){}; var ufo = new UFO; ufo.__proto__ == UFO.prototype //true
  65. 65. __proto__ ufo.__proto__.hasOwnProperty(‗stealCow‘) // true ufo. __proto__. __proto__. hasOwnProperty(‗toString‘) // true
  66. 66. prototype наследуются
  67. 67. «Живые» prototype typeof ufo.isCowsStealer; // ―undefined‖ UFO.prototype.isCowsStealer = true; ufo. isCowsStealer; // true
  68. 68. Наращивание prototype • Затрагивает все новые объекты • Затрагивает все созданные объекты(!) • Позволяет модифицировать существующие объекты String.prototype.trim = function() { return this.replace(/^s+/, ―‖); }; alert(― ufo‖.trim());
  69. 69. Наращивание prototype Number.prototype.times = function(f) { for (var i = 0; i < this; i++) f(); }; (5).times(function(){ alert(―Moo‖); });
  70. 70. Родительский конструктор function FlyingObject() { this.name = ―Flying Object‖; this.getName = function() { return this.name; }; };
  71. 71. «Детский» конструктор function UFO() { this.shiny = true; this.round = true; };
  72. 72. Замена prototype UFO.prototype = new FlyingObject; var ufo = new UFO(); ufo.name = ―Mars UFO‖; ufo.round; // true ufo.getName(); // ―Mars UFO‖
  73. 73. Вызов «superclass»- конструктора function FlyingObject(name) { this.name = name; } function UFO(name) { // super(name) FlyingObject.call( this, name ); this.stealCow = function() {}; }; UFO.prototype = new FlyingObject;
  74. 74. Переопределение методов function UFO(){}; UFO.prototype.stealCow = function() { /*Steal a Cow*/ }; function MegaUFO(){}; MegaUFO.prototype = new Dow; MegaUFO.prototype. stealCow = function() { // super.stealCow(); UFO.prototype.stealCow.call(this); alert(―Yahoo!‖); };
  75. 75. Абстрактные «классы» function UFO() { if (this._id == UFO._id) { throw new Error(―No UFOs, please!‖); } } UFO._id = ―UFO‖; UFO.prototype._id = ―UFO‖; var ufo = new UFO(); // Error
  76. 76. Улучшение наследования При использовании абстрактного класса появляется ошибка MegaUFO.prototype = new UFO; // Error Решение: использовать пустой порождающий объект для создания наследования
  77. 77. Порождающий объект function inherit(o) { function Dummy(){}; Dummy.prototype = o.prototype; return new Dummy(); } MegaUFO.prototype = inherit(UFO);
  78. 78. FP в JavaScript
  79. 79. Nested Functions: Globals function stealCow(cow) { // steal a cow } function stealCows() { this.radar(―foundCow‖, stealCow); } stealCows();
  80. 80. Nested Functions: Variables var stealCow = function(cow) { // steal a cow } var stealCows = function() { this.radar(―foundCow‖, stealCow); } stealCows();
  81. 81. Nested Functions: Function First- style function stealCows() { function stealCow(cow) { // steal a cow } this.radar(―foundCow‖, stealCow); } stealCows();
  82. 82. Nested Functions: Pyramid Order Переменная stealCow создается до инициализации конкретной функцией function stealCows() { this.radar(―foundCow‖, stealCow); function stealCow(cow) { // steal a cow } } stealCows();
  83. 83. Nested Functions: Inline function function stealCows() { this.radar(―foundCow‖, function stealCow(cow) { // steal a cow }); } stealCows();
  84. 84. Nested Functions: Amomymous function stealCows() { this.radar(―foundCow‖, function(cow) { // steal a cow }); } stealCows();
  85. 85. Передача функций как параметров function moo(m) { return m + ―moo‖; } function twice(fn) { return function(x) { return fn(fn(x)); } } var moomoo = twice(moo); moomoo(―Save your bodies‖);
  86. 86. Хранение функций в таблице var mooTable = { ―+moo‖: function(x) { return x + ―Moo!‖; }, ―+mo2‖: function(x) { return x + ―Moo-Moo!‖; } }; mooTable[―+moo‖](―UFOs!‖); mooTable[―+mo2‖](―Fresh Grass!‖);
  87. 87. Построение реестра var mooTable = {}; function register(name, fn) { FnTable[name] = fn; } function makeMoomer(moo) { return function(x) { return x + moo; } } register(―+moo‖, makeMoomer(―Moo!‖)); register(―+mo2‖, makeMoomer(―Moo-Moo!‖)); mooTable[―+moo‖](―UFOs!‖); mooTable[―+mo2‖](―Fresh Grass!‖);
  88. 88. Ручные стражи for (var cow in cows) steal(cow); function callIfFat(fn) { return function(x) { return isFat(x) ? fn(x) : undefined; } } var stealFat = callIfFat(steal); for (var cow in cows) stealFat(cow);
  89. 89. Guard Construction function guard(fn ,g) { return function(x) { return g(x) ? fn(x) : undefined; } } var stealFat = guard(steal, isFat); for (var cow in cows) stealFat(cow);
  90. 90. Замыкания function callLater(o, property, value){ return function(){ o[property] = value; }; } var shine = callLater(ufo, ―shiny‖, false); wowEffect=setTimeout(shine, 500);
  91. 91. «Кража» методов var ufo = { shine: function() { this.shiny = true; } }; var cow = {}; ufo.shine(); // ufo is shiny ufo.shine.call(cow); // cow is shiny! ufo.shine.apply(cow, []); // cow is shiny! Это лучше, чем cow.shine = ufo.shine; cow.shine();
  92. 92. arguments arguments – специальное свойство внутри функции, но это не Array! // не работает! function joinInHerd() { var herd = arguments.join(―, ―); } // «кража» метода у Array function joinInHerd() { var herd = [].join.call(arguments, ―, ―); } // вытаскивание метода из prototype function joinInHerd() { var herd = Array.prototype.join.call(arguments, ―, ―); }
  93. 93. Наращивание prototype Function.prototype.twice = function() { var fn = this; return function() { return fn.call(this, fn.apply(this, arguments)); }; } function moo(x) { return x + ―Moo!‖; } var mo2 = moo.twice(); mo2(―Ufos!!!‖);
  94. 94. Анонимные функции var UFO = function(name){ Анонимная this.name = name; функция this.getName = function() { return this.name; }; $&*# | function }; UFO.name // ―‖ UFO | function
  95. 95. Анонимные функции function guard(fn ,g) { return function(x) { Анонимная return g(x) ? fn(x) : undefined; функция } }
  96. 96. Анонимные функции Анонимные функции позволяют ограничить область видимости и область выполнения — idempotent function function() { var cow = { name: ―Cow‖ }; stealCow (cow); }();
  97. 97. bind function shine() { this.shiny = true; } shine(); // Window is shiny y = shine.bind(cow); y(); // cow is shiny
  98. 98. bind (prototypejs) function bind(context) { if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; var __method = this, args = slice.call(arguments, 1); return function() { var a = merge(args, arguments); return __method.apply(context, a); } }
  99. 99. Слайд #100

×