Skip to content

Instantly share code, notes, and snippets.

@mike-gusiev
Last active August 29, 2015 14:22
Show Gist options
  • Save mike-gusiev/aee7f0842fb7d7b9fcc2 to your computer and use it in GitHub Desktop.
Save mike-gusiev/aee7f0842fb7d7b9fcc2 to your computer and use it in GitHub Desktop.
JavaScript Design Patterns syllabus
Глава 2. Основы:
1. Добавление функции в прототип любого объекта {code}
2. В parseInt() всегда использовать систему вычисления month = parseInt(month, 10); //09 нормально спарсится
3. Всегда в if() используй ===
4. Всегда используй {}, даже где можно без них
5. function MyConstructor() {...} //функции-конструкторы должны начинатся с большой буквы
6. ВЕРХНИЙ регистр для переменных, которые не должны менятся (константы)
7. Префиксы: _private; или _protected и __private;
8. Автодокументация с помощью комментариев YUIDoc
9. jsLint
Глава 3. Литералы и конструкторы:
1. var dog = {}; //называется литералом
2. var car = new Object(); //антишаблон: создание объекта через встроенный конструктор
3. Пример создания объекта {code}
4. В конструкторе можно возвращать другой произвольный объект (и только объект, а не число/строку) {code}
5. Не забывай указывать new в функциях-конструкторах: var good_morning = new Waffle();
6. Можно вручную инициализировать объект, если кто-то забыл поставить new перед запуском функции {code}
7. Литералы массивов var a = ["itsy", "bitsy", "spider"];
8. Если создавать массив через var a = Array(3); //число 3 оно посчитает размером массива a.length=3
9. Чтобы проверить на массив, используем Array.isArray([1, 2]); // true. typeof [1, 2] === 'object'
10. JSON.parse(jstr) и JSON.stringify(str) //В JSON и ключи и значения должны быть в скобках ""
11. В JSON можно только объекты или массивы. Функции запрещены
12. var re = /pattern/gmi; //литерал регулярных выражений. g - global, m - многострочный текст, i - без учета регистра
13. RegExp()// – можно использовать только когда шаблон не известен заранее и создается как строка во время выполнения
14. В ES3 если одно и то же регулярное выражение создается в цикле, будет возвращаться один и тот же объект
15. В языке JavaScript имеется пять простых типов данных: число, строка, логическое значение, null и undefined
16. Объекты-обертки могут быть созданы с помощью встроенных конструкторов Number(), String() и Boolean()
17. Если проинициализировать переменную через обертку, к ней можно добавлять свойства
18. Можно выбрасывать исключение любого типа {code}
Глава 4. Функции:
1. Именнованная функция-выражение: var add = function add(a, b) { return a + b; };
2. Неименнованная функция-выражение (анонимная функция): var add = function (a, b) { return a + b; };
3. Функция-объявление: function add(a, b) { return a + b; }
4. Функции могут создавать свои области видимости (privat-переменные)
5. Внутри функции переменные созданные через var - локальные (privat). И они автоматом подымаются вверх.
6. Функции содержут параметр name {code}
7. Присваивать именнованную функцию другой переменной нельзя: var foo = function bar() {}; //из-за проблем с IE
8. Подьем метода в локальной области видимости срабатывает только для функций-обьявлений. (var func = f..() {} - подымится только название переменной)
9. Можно передавать callback-функции другим функциям. при передачи указываются без круглых скобок {code}
10. Если в callback будут передавать обьект с методом, то надо поебать себе мозг {code}
11. Функция может возвращать другую функцию {code}
12. Самоопределяемые функции - функция может перезатерать себя. Во второй раз будет вызываться уже другая ф-я {code}
13. Немедленно вызываемые функции: //с privat-окружением
(function (a) { console.log('watch out!', a); } (13) );
(function (a) { console.log('watch out!', a); }) (13);
14. С помощью НВФ, переменную можно вычислять динамечески во время создания:
var result = (function () { return 2 + 2; }());
var result = (function () { return 2 + 2; })();
var result = function () { return 2 + 2; }();
15. НВФ может возвращать функцию, и хранить privat-переменые в замыкании {code}
16. НВФ может использоваться в обектах {code}
17. <a href="javascript:void(function () { document.body.style.backgroundColor='gray'; alert(1); }());">bookmarklets</a>
18. Немедленно вызываемые объекты (НВО) - ({ a: 'hello', init: function() { alert(this.a); } }).init(); {code}
19. Варианты НВО: ({...}).init(); и ({...}.init());
20. Недостаток НВО: все компресоры кроме Google Closure Compiler не могут присваивать короткие имена объекту
21. Для кроссбраузерности, вместо ветвления кода и проверок на IE можно заранее реализовать один общий интерфейс {code}
22. length у функции - кол-во ожидаемых аргументов: function func(a, b, c) {} console.log(func.length); // 3
23. Кеширование (мемоизацию, memorization) любой фун-ции можно сделать по хешу входящих параметров {code}
24. Если у функции слишком много параметров - надо вынести их в отдельный объект function(obj) {}
25. В анг. языке функции применяются (apply): sayHi.apply(null, ["hello"]); //this = null
26. Тоже самое, только для одного параметра: sayHi.call(null, "hello");
27. Если у нас в функцию часто передается один из параметров - можем использовать каррирование {code}
//2.1. Добавление функции в прототип любого объекта
if (typeof Array.prototype.avg !== "function") {
Array.prototype.avg = function () {
'use strict';
var sum = 0, i;
for (i = 0; i < this.length; i += 1) {
if (isNaN(this[i])) { //если не число
return false;
}
sum += parseFloat(this[i]);
}
return sum / i;
};
}
//3.3 Пример создания объекта
var Person = function (name) {
'use strict';
this.name = name;
this.say = function () {
console.log("I am " + this.name);
};
};
var adam = new Person("Adam");
adam.say();
//3.4 В конструкторе можно возвращать другой объект (и только объект, а не число/строку)
var ObjectMaker = function () {
'use strict';
var newObj = {'fuck' : 'yeah'};
return newObj;
};
var o = new ObjectMaker();
console.log(o);
//3.6. Можно вручную инициализировать объект, если кто-то забыл поставить new перед запуском функции
function Waffle() {
if (!(this instanceof Waffle)) { //если вызывается как функция
return new Waffle();
}
this.tastes = 'yummy';
}
Waffle.prototype.wantAnother = true;
// и то и то создаст новый объект через функцию-конструктор
var first = new Waffle(),
second = Waffle();
//3.18. Можно выбрасывать исключение любого типа
var genericErrorHandler = function () {console.log(this);};
try {
throw {
name: "MyErrorType",
message: "oops",
extra: "This was rather embarrassing",
remedy: genericErrorHandler
};
} catch (e) {
if(e.name === "MyErrorType") {
e.remedy();
} else {
console.log(e.name, ': ', e.message, e.extra);
}
}
//4.6. Функции содержут параметр name
function foo() {} // функция-­объявление
var bar = function () {}; // функция-­выражение
var baz = function baz() {}; // именованная функция-­выражение
console.log(foo.name); // “foo”
console.log(bar.name); // “” - В IE может отсуствовать это свойство
console.log(baz.name); // “baz”
//4.9. Можно передавать callback-функции другим функциям. при передачи указываются без круглых скобок
var findNodes = function (callback) {
// в данном примере передавать параметр callback в функцию findeNodes необязательно
if(typeof callback !== 'function') {
callback = false;
}
if(callback) {
callback('param1');
}
};
findNodes(function (a) {
console.log(a);
});
//4.10. Если в callback будут передавать обьект с методом, то надо поебать себе мозг
var myapp = {
color: 'green',
paint: function (param) {
console.log(this.color + ' ' + param); //в callback не будет this работать.
//надо еще передать сам обьект
}
};
var findNodes = function (callback, obj) { //передача obj нужна для работы this
// в данном примере передавать параметр callback в функцию findeNodes необязательно
if(typeof callback !== 'function') {
callback = false;
}
if(callback) {
if(typeof obj === 'object') {
callback.call(obj, 'param1'); //теперь this === obj
} else {
callback('param1');
}
}
};
findNodes(myapp.paint, myapp); //передача callback вместе с обьектом
findNodes(function (a) { //передача обычной callback-фунции
console.log(a);
});
//4.11. Функция может возвращать другую функцию
var setup = function () {
var count = 0;
return function () {
return (count += 1);
};
}
var next = setup();
console.log( next() ); //1
console.log( next() ); //2
console.log( next() ); //3
//4.12. Самоопределяемые функции - функция может перезатерать себя. Во 2й раз будет вызываться уже другая ф-я
var scareMe = function () {
console.log("Boo!");
scareMe = function () {
console.log("Double boo!");
}; };
scareMe(); // Boo!
scareMe(); // Double boo!
//4.15. НВФ может возвращать функцию, и хранить privat-переменые в замыкании
var getResult = (function () {
var res = 2 + 2; //сохранится как privat в замыкании
return function () {
return res;
};
}());
console.log( getResult() );
//4.16. НВФ может использоваться в объектах
var o = {
message: (function () {
var who = 'me',
what = 'call';
return what + ' ' + who;
}()),
getMsg: function () {
return this.message;
}
};
// пример использования usage
console.log(o.getMsg()); //'call me'
console.log(o.message); //'call me'
//4.18. Немедленно вызываемые объекты (НВО) - ({ a: 'hello', init: function() { alert(this.a); } }).init();
({
maxwidth: 'hello',
init: function () {
console.log(this.maxwidth);
}
}).init();
//4.21. Для кроссбраузерности, вместо ветвления кода и проверок на IE можно заранее реализовать один общий интерфейс
var utils = {
addListener: null,
removeListener: null
};
// реализация очереди событий. аргументы: element, event, function
if (typeof window.addEventListener === 'function') {
utils.addListener = function (el, type, fn) {
el.addEventListener(type, fn, false);
};
utils.removeListener = function (el, type, fn) {
el.removeEventListener(type, fn, false);
};
} else if (typeof document.attachEvent === 'function') { // IE
utils.addListener = function (el, type, fn) {
el.attachEvent('on' + type, fn);
};
utils.removeListener = function (el, type, fn) {
el.detachEvent('on' + type, fn);
};
} else { // устаревшие броузеры. цепляем только одно событий
utils.addListener = function (el, type, fn) {
el['on' + type] = fn;
};
utils.removeListener = function (el, type, fn) {
el['on' + type] = null;
};
}
//пример вызова
var elem = document.querySelector('input[type=submit]');
utils.addListener(elem, 'click', function () {
alert(1);
return false;
});
//4.23. Кеширование (мемоизацию, memorization) любой фун-ции можно сделать по хешу входящих параметров
var pow = function (base, exponent) {
if(typeof pow.cache === 'undefined') {
pow.cache = {};
}
//делаем из arguments массив
var array = Array.prototype.slice.call(arguments);
//var array = [].slice.call(arguments); //менее производительно
var key = JSON.stringify(array);
//если нету в хэше, то считаем
if(!pow.cache[key]) {
var result = Math.pow(base, exponent);
pow.cache[key] = result;
console.log('from scratch');
}
return pow.cache[key];
}
console.log( pow(2, 3) ); //from scratch
console.log( pow(2, 3) );
console.log( pow(2, 4) ); //from scratch
//4.27. Если у нас в функцию часто передается один из параметров - можем использовать каррирование
function curry(x, y){
if (typeof y === 'undefined') { // partial
return function (y) {
return x + y;
};
}
// полное применение
return x + y;
}
console.log( curry(4, 5) ); // 9
console.log( curry(4)(5) ); // 9
//использование каррирования - сохранения параметра, который часто передаем
var curry1 = curry(4);
console.log( curry1(5) ); //9
console.log( curry1(6) ); //10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment