Это сообщение в блоге предназначено для разработчиков, которые уже знают, как писать программное обеспечение и хотят узнать о Javascript. Я не учу вас писать программное обеспечение, потому что предполагаю, что вы можете писать код на другом языке. Я также предполагаю, что даже Javascript-ниндзя любят немного обсуждать темы, которые они могут знать или не знать.
- Синтаксический сахар
- Паттерны Javascript / Объекты в JavaScript
- Функции в JavaScript
- « Это означает указание на это»
- ООП (объектно-ориентированное программирование)
Функции в Javascript
Функции имеют решающее значение для работы Javascript. В этом сообщении блога не будут рассмотрены все аспекты функций Javascript, но я упомяну основные моменты, которые делают Javascript более удобным в использовании. В конце этого поста вы найдете ссылку, которая перенаправит вас на очень полный источник функций.
Они предоставляют группу повторно используемого кода и могут быть вызваны в любом месте вашей программы. Функции могут быть адаптированы для различных контекстов, а объем может быть инкапсулирован и сохранен. Они ведут себя иначе, чем другие языки, которые вы, возможно, знаете, и имеют определенный порядок их именования. Функции Javascript можно использовать как функцию или как объект. Функции Javascript могут быть:
- Конструкция нормальной функции
- Анонимная функция
- Или обычная функция с присвоенной переменной
// Normal function construct function function myFunction(arguments){ // some code }; // An anonymous function myFunction = function (arguments) { // some code }; // A normal function construct with an assigned variable myFunction = function myFunction(arguments) { // some code };
Я почти уверен, что вы уже видели хотя бы одно из них? Если да, вы должны знать об их контексте и поведении.
Контекст Javascript
Есть определенные приложения, которые ожидают, что вы объявите функции внутри оператора. Это не очень распространено, но когда вы делаете это, используйте следующий пример в качестве шаблона. Это поддерживается во всех текущих браузерах с использованием назначенных анонимных функций, и это правильный способ добиться желаемого эффекта:
var functionName; if( someCondition ) { functionName = function () { ... }; }
Затем эти функции могут быть вызваны при необходимости, и код, содержащийся в них, будет запущен. Для вызова функции обычно используются следующие методы:
- myFunction (listOfVariables);
- window.myFunction (listOfVariables);
- object.onEventName = myFunction;
Я не могу сосчитать количество опрошенных мной кандидатов-разработчиков JavaScript, которые не могли сказать мне разницу между объявлением функции и выражением функции, и , которые не понимали, что такое немедленно вызываемое выражение функции. . Я не разглагольствую об этом, но я знаю: D
Самозапускающиеся функции Javascript
Шаблон, используемый в Javascript, - это так называемые самозапускающиеся функции. Самозапускающаяся анонимная функция запускается сразу после создания во время выполнения. Чтобы вы знали, как это выглядит, вот формат самоисполняющейся анонимной функции, обертывающей некоторый код:
(function(){ // some code… })();
Интересно, что если вы посмотрите исходный код jQuery, вы увидите, что все обернуто между ними, чтобы установить новый контекст:
(function( window, undefined ) { // jQuery code })(window);
Если вы находитесь в ситуации, когда вы хотите многократно запускать фрагмент кода или если вы хотите установить новую область видимости. Новая область видимости важна, если вы используете другие плагины и файлы поставщиков Javascript, которые также могут использовать ваши переменные и мешают работе вашего глобального пространства имен. Предположим, у нас есть переменная в глобальной области видимости, доступ к которой можно получить, просто вызвав ее:
// app.js var myVariable = ['this','is','my','message']; // another.js if(myVariable){ // true console.log('your var is global'); }
На самом деле это не считается лучшей практикой. myVariable будет добавлена в область окна и видна во всех других файлах вашего приложения. Что вы хотите сделать для каждого файла, так это то, что вы хотите установить область для вашего var с помощью функции самообращения. Давайте попробуем это на мгновение:
(function(){ var myVariable = ['this','is','my','message']; })(); // another.js if(myVariable){ // false because it it undefined console.log('your var is global'); }
Чтобы решить эту проблему, вы можете использовать самоисполняющуюся анонимную функцию и создать инкапсулированный контекст для этой переменной. Итак, давайте немного порефакторим эту функцию, чтобы показать вам что-нибудь забавное. На самом деле это забавно, только если вы знаете, что делает Javascript в этой ситуации.
(function(){ var myVariable = ['this','is','my','message']; for(var i in myVariable) { setTimeout(function () { // will be exectured delayed by 10 milliseconds console.log(myVariable[i]); // output: message message message message },10); } })();
Так что же здесь происходит? На самом деле он печатает сообщения четыре раза. Поэтому люди могут подумать, что давайте просто уменьшим время setTimeout до единицы, и каждый раз, когда вы его печатаете, оно будет возвращать правильное предложение из массива, а не. setTimeout задерживает выполнение, следовательно, к моменту его вызова я уже будет «сообщением», или 3, поскольку мы имеем дело с массивом.
Итак, чтобы показать вам, как исправить это, мы должны реорганизовать функцию менее интуитивно понятным способом.
(function(){ var myVariable = ['this','is','my','message']; var say = function (i) { // the variable i will setTimeout(function () { console.log(myVariable[i]); // output: message message message message },10); }; // So by the time i is executed it is no longer referring // to this i in the for loop it is referring to the // scoped i inside the say function for(var i in myVariable) { say(i); // output: this is my message } })();
По сути, на данный момент у вас есть инкапсулированная область видимости внутри области видимости. Помните, когда вы звоните, говорите, что i передается этой функции и создает новую область видимости функции. Таким образом, к моменту вызова функции i больше не ссылается на i в цикле for. Это относится к index. Это очень мощная концепция в Javascript для создания отдельного контекста. Дайте мне знать, если у вас когда-либо была эта проблема в прошлом, в области комментариев.
Образец закрытия
У нас есть функция, которая ссылается на переменную вне функции. Давайте реорганизуем последний пример, чтобы сделать его закрытием и заставить его работать в этом контексте.
(function(){ var myVariable = ['this','is','my','message']; var say = function (i) { // the variable i will scoped return function () { console.log(myVariable[i]); // Will be called later. }; }; // So by the time i is executed it is no longer referring // to this i in the for loop it is referring to the // scoped i inside the say function for(var i in myVariable) { setTimeout(say(i),1000); // output: this is my message } })();
Эта концепция является общим шаблоном для функции закрытия. Замыкание - это функция упаковки, которая захватывает аргумент, а аргументы фиксируют этот контекст внутри функции. Затем эта функция возвращает другую функцию, единственная цель которой - вызвать позже. Он использует аргумент, который был инициализирован в его области видимости. Это мощный инструмент, но вы должны изучить его, пока не получите правильного ответа. Это подводит нас к другому распространенному шаблону, называемому модульным шаблоном.
Шаблон модуля
Этот шаблон действительно полезен, когда вы хотите инкапсулировать частные функции и переменные для доступа. Кроме того, шаблон модуля предоставляет общедоступный API-интерфейс, который вы можете использовать для работы и создания своего приложения. Давайте посмотрим на хороший пример шаблона модуля:
var MODULE = (function () { var privateVariable = 1; function privateMethod() { // do something in here } return { moduleProperty:1, moduleMethod:function () { /** * A function that can utilizes a private method * or a private variable. */ } }; }());
Обратите внимание, что мы объявили глобальный модуль с именем MODULE с двумя общедоступными свойствами: методом с именем MODULE.moduleMethod и переменной с именем MODULE.moduleProperty. Кроме того, он поддерживает частное внутреннее состояние, закрывая анонимную функцию. Кроме того, мы можем легко импортировать необходимые глобальные объекты, используя шаблон, который мы узнали выше. Этот шаблон широко используется при создании плагинов и легко переводится в другой шаблон, называемый CommonJS.
CommonJS
Когда мы говорим, что приложение модульное, мы обычно имеем в виду, что оно состоит из набора сильно разделенных, отдельных частей функциональности, хранящихся в модулях. Как вы, наверное, знаете, слабая связь упрощает сопровождение приложений за счет удаления зависимостей, где это возможно.
Предложение модуля CommonJS определяет простой API для объявления модулей на стороне сервера и, в отличие от AMD, пытается охватить более широкий набор проблем, таких как io, файловая система, обещания и многое другое.
CommonJS Javascript часто используется в NodeJS. Так что, если вы много занимаетесь разработкой NodeJS, вы часто это увидите. По сути, вы назначаете интерфейс класса для module.export. Для этого вам не нужна самоисполняющаяся анонимная функция. Давайте избавимся от лишних круглых скобок:
/** * Define more behaviour we would like to expose. * And expose foobar to other modules as well. */ exports.myFunction = function myFunction(){ this.one = function(){ console.log('Hello one'); } this.two = function(){ console.log('Hello two'); } } /** * Access the module relative to the path where both usage * and module files exist in the same directory. * @type {exports.myFunction|*} */ var myFunction = require('./myFunction').myFunction, test = new myFunction(); /** * Make use of exported variables */ test.two(); // output 'Hello two'
В качестве хорошей практики, когда вы имеете дело с functions. Не используйте анонимные функции. Причина в том, что вы должны отлаживать минифицированный код и имеете дело с множеством анонимных функций. Скорее всего, вы бросите полотенце и начнете с нуля. Какая боль!
Я считаю, что этого достаточно о функциях, поскольку многие из них были рассмотрены в других местах. Итак, просмотрите ссылки ниже, и я перейду к четвертой части, посвященной ключевому слову «this» и области действия.
Электронная почта - [email protected]
Twitter - @MHerszak (twitter.com/MHerszak)
Хотите знать, как я работаю? Отлично, вы можете начать с обзора моего подхода к проекту прямо здесь.
Подробный пост в блоге обо всех аспектах функций Javascript можно найти здесь. Действительно очень хорошо!
Использование шаблонов CommonJS на стороне сервера:
Первоначально опубликовано на www.browserstudios.com 21 декабря 2015 г.