меню

Раннее в JavaScript, когда почти для всего нужна была специальная функция, потому что браузеры реализовывали по своему не только новые, но и базовые функции, такие как addEventListener и attachEvent. Времена изменились, но есть несколько функций, которые каждый разработчик должен иметь в своем арсенале, чтобы повысить производительность работы.

debounce

Функция debounce крайне полезна, когда дело доходит до производительности обработчиков событий. Если вы не используете функцию debounce с событиями scroll, resize, key*, вы, вероятно, не правы. Вот функция debounce, которая сделает ваш код более эффективным:

		
	// Returns a function, that, as long as it continues to be invoked, will not
	// be triggered. The function will be called after it stops being called for
	// N milliseconds. If `immediate` is passed, trigger the function on the
	// leading edge, instead of the trailing.
	function debounce(func, wait, immediate) {
		var timeout;
		return function() {
			var context = this, args = arguments;
			var later = function() {
				timeout = null;
				if (!immediate) func.apply(context, args);
			};
			var callNow = immediate && !timeout;
			clearTimeout(timeout);
			timeout = setTimeout(later, wait);
			if (callNow) func.apply(context, args);
		};
	};

	// Usage
	var myEfficientFn = debounce(function() {
		// All the taxing stuff you do
	}, 250);
	window.addEventListener('resize', myEfficientFn);
		
	

Функция debounce не позволяет обработчику события выполниться более одного раза в заданный промежуток времени. Это особенно выжно для часто срабатывающих событий.

poll

Иногда у вас не будет возможности отследить событие наступления желаемого состояния — если события не существует, необходимо периодически проверять определенное состояние:

		
	function poll(fn, callback, errback, timeout, interval) {
	    var endTime = Number(new Date()) + (timeout || 2000);
	    interval = interval || 100;

	    (function p() {
	            // If the condition is met, we're done! 
	            if(fn()) {
	                callback();
	            }
	            // If the condition isn't met but the timeout hasn't elapsed, go again
	            else if (Number(new Date()) < endTime) {
	                setTimeout(p, interval);
	            }
	            // Didn't match and too much time, reject!
	            else {
	                errback(new Error('timed out for ' + fn + ': ' + arguments));
	            }
	    })();
	}

	// Usage:  ensure element is visible
	poll(
	    function() {
	        return document.getElementById('lightbox').offsetWidth > 0;
	    },
	    function() {
	        // Done, success callback
	    },
	    function() {
	        // Error, failure callback
	    }
	);
		
	

Такой подход периодического опрашивания уже давно используется в веб и будет использоваться в будущем!

once

Иногда необходимо, чтобы какая-то функция выполнилась только однажды, подобно событию onload. Код ниже позволит вам добавить такую функциональность:

		
	function once(fn, context) { 
		var result;

		return function() { 
			if(fn) {
				result = fn.apply(context || this, arguments);
				fn = null;
			}

			return result;
		};
	}

	// Usage
	var canOnlyFireOnce = once(function() {
		console.log('Fired!');
	});

	canOnlyFireOnce(); // "Fired!"
	canOnlyFireOnce(); // nada
		
	

Функция once гарантирует, что функция будет вызвана только один раз, тем самым позволяет избежать повторной инициализации!

getAbsoluteUrl

Получение абсолютного URL из строки не такая простая задача, какой кажется. Существует конструктор URL, который не работает, если не передать ему требуемые параметры (которые иногда невозможно передать). Вот хороший трюк для получения абсолютного URL из строки:

		
	var getAbsoluteUrl = (function() {
		var a;

		return function(url) {
			if(!a) a = document.createElement('a');
			a.href = url;

			return a.href;
		};
	})();

	// Usage
	getAbsoluteUrl('/something'); // http://proweb63.ru/something
		
	

Обработка атрибута href элемента предоставляет надежный способ получения абсолютного URL.

isNative

Знание того, является ли функция встроенной или нет может быть полезно, если вы собираетесь ее переопределить. Следующий код может вам в этом помочь:

		
	;(function() {

	  // Used to resolve the internal `` of values
	  var toString = Object.prototype.toString;
	  
	  // Used to resolve the decompiled source of functions
	  var fnToString = Function.prototype.toString;
	  
	  // Used to detect host constructors (Safari > 4; really typed array specific)
	  var reHostCtor = /^\[object .+?Constructor\]$/;

	  // Compile a regexp using a common native method as a template.
	  // We chose `Object#toString` because there's a good chance it is not being mucked with.
	  var reNative = RegExp('^' +
	    // Coerce `Object#toString` to a string
	    String(toString)
	    // Escape any special regexp characters
	    .replace(/[.*+?^${}()|[\]\/\\]/g, '\\$&')
	    // Replace mentions of `toString` with `.*?` to keep the template generic.
	    // Replace thing like `for ...` to support environments like Rhino which add extra info
	    // such as method arity.
	    .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
	  );
	  
	  function isNative(value) {
	    var type = typeof value;
	    return type == 'function'
	      // Use `Function#toString` to bypass the value's own `toString` method
	      // and avoid being faked out.
	      ? reNative.test(fnToString.call(value))
	      // Fallback to a host object check because some environments will represent
	      // things like typed arrays as DOM methods which may not conform to the
	      // normal native pattern.
	      : (value && type == 'object' && reHostCtor.test(toString.call(value))) || false;
	  }
	  
	  // export however you want
	  module.exports = isNative;
	}());

	// Usage
	isNative(alert); // true
	isNative(myCustomFunction); // false
		
	

Эта функция выглядит не симпатично, но выполняет свою работу!

insertRule

Все мы знаем, что можно получить список элементов DOM по селектору (с помощью document.querySelectorAll) и для каждого из них добавить атрибут style, но более эффективным будет задать стиль для селектора (как это делается в CSS):

		
	var sheet = (function() {
		// Create the <style> tag
		var style = document.createElement('style');

		// Add a media (and/or media query) here if you'd like!
		// style.setAttribute('media', 'screen')
		// style.setAttribute('media', 'only screen and (max-width : 1024px)')

		// WebKit hack :(
		style.appendChild(document.createTextNode(''));

		// Add the <style> element to the page
		document.head.appendChild(style);

		return style.sheet;
	})();

	// Usage
	sheet.insertRule("header { float: left; opacity: 0.8; }", 1);
		
	

Это особенно полезно для динамичных сайтов. Если вы добавляете правило к селектору, вам не нужно перебирать и стилизовать все элементы, удовлетворяющие этому селектору.

matchesSelector

Мы часто валидируем пользовательский ввод, проверяем, что все поля формы заполнены корректно, прежде, чем двигаться дальше. Но как часть мы проверяем элемент? Вы можете использовать функцию ниже для проверки, удовлетворяет ли элемент заданному селектору:

		
	function matchesSelector(el, selector) {
		var p = Element.prototype;
		var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) {
			return [].indexOf.call(document.querySelectorAll(s), this) !== -1;
		};
		return f.call(el, selector);
	}

	// Usage
	matchesSelector(document.getElementById('myDiv'), 'div.someSelector[some-attribute=true]')
		
	

Мы привели семь JavaScript-функций, которые каждый разработчик должен иметь в своем арсенале. Есть функции, которые я пропустил? Пожалуйста, поделитесь!


Возможно, вам будет интересно

This в JavaScript

Ключевое слово this в JavaScript, так же, как и во многих других языках программирования, используется подобно местоимению в естественном языке. Так же, как в естественном языке, с помощью местоимений мы указываем на определенного человека, животное, предмет, в JavaScript мы можем использовать this для указания на определенный объект.

Управление версиями Node.js с помощью nvm в Windows

Вопрос экономии времени и удобства окружения разработчика — штука сложная. Работая с Node.js, иногда приходится тестировать своё приложение не только в той версии, которую используете вы, но и в тех, что были выпущены до неё или даже после.

Семь необходимых операторов RxJS

Как front-end разработчик вы знаете, что управление асинхронными данными - это не легкая задача. Иногда кажется, что нужна целая команда клоунов, чтобы держать все эти мячи в воздухе! Но в этом и заключается сила библиотеки RxJS. Она помогает легко манипулировать потоками асинхронных данных.

Чистый код на JavaScript, 5 рекомендаций которые улучшат Ваш код.

Написание хорошо переиспользуемого кода иногда может быть сложным. Мы можем программировать на разных языках и придерживаться определенных ограничений или шаблонов, которые несут смысл от конкретного контекста.

Оформление заявки

Документы на создание сайта

Изучите наше коммерческое предложение, заполните БРИФ и отправьте его на почту maxidebox@list.ru. Изучив все пожелания из БРИФ-а, обратным ответом оповестим Вас по стоимости разработке, ответим на вопросы.

КП на создание сайта Коммерческое предложение на созданеи сайта

Мы берем на себя ответственность за все стадии работы и полностью избавляем клиентов от забот и необходимости вникать в тонкости.

Скачать БРИФ (акета) на создание сайта Скачать БРИФ (акета) на создание сайта

Зополните у БРИФ-а все необходимые поля. Сделайте краткое описание к каждому из пунктов анкеты, привидите примеры в соответсвующий пунктах - это позволит лучше понять Ваши ожидания и требования к сайту