Памятка часто используемых JavaScript функций
Дата публикации 23.06.2018
Несколько часто применяемых модулей на JavaScript. Ничего необычного, все широко известно, просто, чтобы были под руками. Описывается работа с Cookie, исключениями, адресной строкой.
1. Работа с Cookie.
Взято с javascript.ru. Оформил в виде класса.
class Cookie { constructor() {} get(name) { let matches = document.cookie.match(new RegExp( "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)" )); return matches ? decodeURIComponent(matches[1]) : undefined; } /** * options is contains: * expires: * Digit - time of live at minutes. * Expire Date (past for delete, 0 for session) * path: default / * domain: default is current domain * secure: ssl only */ set(name, value, options = {}) { let expires = options.expires; if (typeof expires == "number" && expires) { let d = new Date(); d.setTime(d.getTime() + expires * 1000); expires = options.expires = d; } if (expires && expires.toUTCString) { options.expires = expires.toUTCString(); } value = encodeURIComponent(value); let updatedCookie = `${name}=${value}`; for (let propName in options) { updatedCookie += `; ${propName}`; let propValue = options[propName]; if (propValue !== true) { updatedCookie += `=${propValue}`; } } document.cookie = updatedCookie; } delete(name) { this.set(name, "", { expires: -1 }) } }
2. Исключения
Вот так можно оформить обработку исключений. В результате в консоль выведется красивое человекопонятное описание.
customException - базовый класс. В производных классах задаем только свое имя исключения.
class customException { constructor(name, message, e) { this.name = name; this.message = message; this.stack = e.stack; this.toString = () => {`Error: ${this.name}: ${this.message}\n${this.stack}`}; } } class parserException extends customException { constructor(message, e) { let name = 'Here is Exception Name'; super(name, message, e); } }
Использование:
try { someFunc();//undefined function } catch(e) { throw new parserException('Exception Description', e); }
3. Чтение строки запроса
Класс для работы с QueryString. Читает параметры запроса из адресной строки и помещвет их в объект Имя=Значение. Теперь можно читать нужные параметры, менять их значение, удалять. После изменений собирается новая строка запроса. Использовал, когда требовалось сделать фильтр по параметрам для каталога магазина.
/** * QueryString to Object: * key:value => parametr-name:value * */ class queryStringObject { constructor(queryString = location.search.substring(1)) { this.queryString = queryString; this.queryObject = {}; this._queryStringToObject(queryString); } _queryStringToObject(queryString) { if(!queryString) return false; queryString = decodeURIComponent(queryString).split('&'); queryString.forEach(pair => { pair = pair.split('='); let value = pair[1] || ''; this.queryObject[pair[0]] = value; }); } getQueryString() { let temp = []; for (let item in this.queryObject) { temp.push(item + '=' + this.queryObject[item]); } return temp.join("&"); } getFieldsFilter() { return this.queryObject; } getParam(str) { if (typeof this.queryObject[str] != 'undefined') return this.queryObject[str]; return false; } addParam(str, value) { if (!str.trim()) return false; this.queryObject[str] = value; return true; } deleteParam(name){ if (typeof this.queryObject[name] != 'undefined') delete this.queryObject[name]; } toString(){ return '?' + this.getQueryString(); } }
Пример использования, показано добавление нового параметра и удаление. Методом toString() собирается новая строка запроса. Методом history.pushState обновляется ее отображение в адресной строке браузера.
let queryObject = new queryStringObject();//global query string object queryObject.addParam(ParametrName, ParametrValue);//Add new parametr to QueryString queryObject.deleteParam(ParametrName);//Delete try { history.pushState(null, null, queryObject.toString()); //Modify Address Bar } catch(e) { //do something }
Тот же класс, в котором преобразовывал строку в многоуровневый объект. Чисто академический интерес, на практике достаточно простого первого варианта.
const PRICE_FILTER = 'price_filter'; const FIELDS_FILTER = 'fields_filter'; const ORDER_FILTER = 'order_filter'; let isDef = (name) => typeof name == 'undefined' ? false : true; /** * * * @return queryStringObject = { * param1: value, * param2: value2, * order_filter: { * field_name: 1, //may be 1 or 0 * price_filter: { * 0: min_price //this subkeys may be 0 and 1 * 1: max_price, * fields_filter: { * field_name: { * field_id1: field_id1// subkeys 'field_id' may be an integer * field_id2: field_id2 * } * } * } * */ class queryStringObject { constructor(queryString = location.search.substring(1)) { this.queryString = queryString; this.queryObject = {}; this._queryStringToObject(queryString); } _queryStringToObject(queryString) { if(!queryString) return false; queryString = decodeURIComponent(queryString).split('&'); queryString.forEach(pair => { pair = pair.split('='); let value = pair[1] || ''; this.addParamFromString (pair[0], value); }); } getQueryString() { return this.serializetoQueryString() } getPriceFilter() { return this._getFilterType(PRICE_FILTER); } getFieldsFilter() { return this._getFilterType(FIELDS_FILTER); } getOrderFilter() { return this._getFilterType(ORDER_FILTER); } addParamFromString(str, value) { let arr = str.replace(/]/g, '').split('['); this.addParamFromArray(arr, value); } addParamFromArray(paramsArray, value) { let sz = paramsArray.length - 1; let tmp = ''; for (let i = 0; i <= sz; i++) { tmp += `['${paramsArray[i]}']`; new Function('result, tmp, last, value', ` if (typeof result${tmp} == 'undefined') result${tmp} = {}; if (last) result${tmp} = value;` )(this.queryObject, tmp, (i == sz ? true : false), value); } } deleteParamFromSrting(name){ let paramsArray = name.replace(/]/g, '').split('['); let sz = paramsArray.length - 1; let tmp = ''; for (let i = 0; i <= sz; i++) { tmp += `['${paramsArray[i]}']`; let def = new Function('result, tmp', ` if (typeof result${tmp} == 'undefined') return false; else return true;` )(this.queryObject, tmp); if(!def) { return false; } } new Function('queryObject, tmp', ` if (typeof queryObject${tmp} != 'undefined') delete queryObject${tmp}; ` )(this.queryObject, tmp); } _getFilterType(param_name) { if (isDef(this.queryObject[param_name])) { if (param_name == PRICE_FILTER) { return this.queryObject[param_name][PRICE_FILTER]; } else { return this.queryObject[param_name]; } } return false; } serializetoQueryString() { let result = [];// temp array for parts of query_string storage /** * @param obj - object of property * @param rootKey - first-level property of queryObject. * It's need because the first part of parameter is not wrapping by '[]' * @param tmpArray - for storage history of navigate throght object's hives * * @return query string of any parameter */ function iterator(obj, rootKey, tmpArray) { for (let key in obj) { if (typeof obj[key] == 'object') { tmpArray.push(key); iterator(obj[key], rootKey, tmpArray); } else { tmpArray.push(key); result.push(`${rootKey}[${tmpArray.join('][')}]=${obj[key]}`); tmpArray.pop(); } } tmpArray.pop(); } for(let key in this.queryObject) { if(typeof this.queryObject[key] == 'object'){ iterator(this.queryObject[key], key, []); } else { result.push(`${key}=${this.queryObject[key]}`); } } return result.join('&'); } }