Программирование на Python и Objective-C в Mac OS

Программирование на Python и Objective-C под Mac OS и для iPhone / iPod Touch

Для описания функции в javascript достаточно указать: Параметры по умолчанию — JavaScript

Содержание

Функции в языке TypeScript. Введение | by Sergey Bakaev

Функции — это одна из фундаментальных основ любого приложения на языке JavaScript. С помощью них строятся уровни абстракции, классы, сокрытие информации и модули. В TypeScript есть классы, пространства имен, модули, но функции при всем этом играют ключевую роль. Язык TypeScript немного расширяет возможности функций по сравнению с JavaScript, делая работу с ними еще удобнее.

Как и в JavaScript, функции в TypeScript могут быть как именованные, так и анонимные. Это позволяет вам выбрать наиболее удобный подход для разработки вашего приложения, будь то выстраивание списка в функций в API, либо вкладывая одну функцию в другую.

Рассмотрим простой пример именованной и анонимной функции:

Функции могут использовать переменные, определенные вне тела функции. В этом случае говорят, что функция захватывает эти переменные. Понимание того, как это происходит, выходит за рамки данной статьи. Но вы должны понимать, как работает этот механизм, поскольку это очень важная часть при работе с JavaScript и TypeScript.

Добавим типы для функций из первого примера:

Как видно, мы добавили типы не только к параметрам, передаваемым в функцию, но и на возвращаемое функцией значение.

Теперь опишем полный тип этой функции:

Функциональный тип состоит из двух частей: типов аргументов и типом возвращаемого значения. Тип возвращаемого значения определяется после =>. В том случае, если функция не возвращает никакого значения, должно быть указано void.

Также в примере выше мы изменили названия параметров, передаваемых в функцию. Это сделано для лучшей читабельности кода. Нужно стараться всегда давать “говорящие” или понятные имена параметрам. Так будет легче другим читать ваш код, также как и вам, когда вернетесь к нему спустя какое-то время.

Стоит отметить, что только параметры, передаваемые в функцию и возвращаемое значение определяют ее тип. Захваченные переменные не входят в описание типа. Поэтому они являются частью некого “скрытого состояния” функции и не входят в API.

Вывод типов

Рассмотрим пример:

TypeScript может автоматически вычислять тип, если вы описали типы в одной части выражения, а в другой — нет. Это называется “контекстной типизацией” . Это помогает упростить код и в тоже время поддерживать код типизированным.

При вызове функции, в нее нужно передавать все описанные параметры. Это не означает, что вы не можете передать вместо значения параметраnull или undefined, но в любом случае компилятор проверит количество параметров, переданных в функцию с ее описанием. Помимо этого, компилятор также убедится, что тип параметров соответствует описанным типам данных.

В Javascript, каждый параметр, передаваемый в функцию, является необязательным. Если он не указан, то передается undefined. Для того, чтобы добавить данную возможность в TypeScript, нужно поставить ? в конце имени параметра перед :. Например:

Необязательные параметры всегда должны следовать после обязательных при описании функции. Нельзя сделать первый параметр необязательным, а второй — наоборот. Если необходимо именно первый параметр сделать необязательным, то нужно поменять их местами при описании функции.

В языке TypeScript также можно задать значение параметра по умолчанию, которое будет передано в функцию, если значение будет не указано или вместо него будет передано undefined. Например:

Параметры по умолчанию, которые идут после всех обязательных параметров в описании функции, являются необязательными и могут не указываться при вызове функции. В данном конкретном случае их отличием от необязательных параметров, описанных выше, является наличие значения по умолчанию.

Таким образом, функции

function concat(s1: string, s2?: string) { //... }
и
function concat(s1: string, s2 = "string2") { //... }

имеют один и тот же тип: (s1: string, s2?: string) => string.

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

Об обязательных, необязательных и параметрах по умолчанию говорится в контексте только одного конкретного параметра. Но иногда требуется работать сразу с несколькими параметрами, как с группой, поскольку, например, вы можете не знать сколько параметров должна принимать функция. В JavaScript можно работать с набором таких параметров, используя одну переменную, передаваемую в функцию, используя оператор расширения (spread operator). Например:

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

Функция, описанная выше, будет иметь тип:
(fname: string, …rest: string[]) => string;

При использовании this внутри функций JavaScript вы должны четко понимать, на что в данный момент эта переменная ссылается. Ну а поскольку TypeScript — надстройка над JavaScript, разработчикам также необходимо знать, как правильно пользоваться этой переменной. К счастью, TypeScript позволяет отлавливать неправильное использование this.

this and arrow functions

В языке JavaScript this — это переменная, которая инициализируется в момент вызова функции. Это очень мощная и гибкая особенность языка, за которую приходится платить тем, что программист всегда должен помнить про контекст вызова самой функции, понимать, что за значение будет в this. Это может показаться достаточно запутанным, особенно если функция возвращает другую функцию или функция передается в качестве аргумента.

Рассмотрим пример:

В данном примере createCardPicker — это функция, которая возвращает другую функцию. Если запустить пример, то будет получено сообщение об ошибке вместо ожидаемого вывода в консоль. А все потому, что значение this, используемое в функции, созданной в createCardPicker будет установлено в window, хотя подразумевалось, что оно будет равно объекту deck. Потому что мы вызвали cardPicker() отдельно. А в этом случае в значении this будет window(если, конечно, не используется strict mode — в этом случае значением this будет undefined).

Это можно исправить если использовать в выражении “стрелочные функции” (arrow functions) из ECMAScript 6. Данные функции захватывают значение this при создании функции, а не при выполнении:

Более того, если установить флаг компиляции --noImplicitThis, то вы получите уведомление от компилятора о возможной ошибке.

В нашем примере this вthis.suits[pickedSuit] имеет тип any.

К сожалению, тип this.suits[pickedSuit] все ещеany. Это потому, что this приходит и функционального выражения внутри литерала объекта. Для того, чтобы это исправить, мы должны явно передать this в качестве параметра. this параметры — “не настоящие, ложные” параметры, которые приходят первыми в списке параметров функции:

Добавим к нашему примеру описание интерфейсов Card и Deck:

Теперь TypeScript знает, что при вызовеcreateCardPicker в качестве this ожидается объект типа Deck. В этом случае флаг --noImplicitThis не приведет к появлению никаких ошибок.

this параметры в функциях обратного вызова (callbacks)

Вы можете столкнуться с ошибками при использовании this в функциях обратного вызова, когда передаете функцию в библиотеку, которая будет позже ее выполнять. Поскольку библиотека, которая вызывает вашу функцию, вызовет ее как обычную, this будет иметь значение undefined. Однако, используя this в качестве параметра, можно избавиться от ошибок. Первое, что нужно — это чтобы у функции обратного вызова был определен тип с использованием this:

this: void означает, что addClickListener ожидает, чтоonclick — функция, которой не требуется тип this. Второе, что вы должны сделать — написать функцию, которая будет передана в addClickListener:

Согласно описанию, функция onClickBad должна быть вызвана как экземпляр Handler. После этого TypeScript определит, что addClickListener принимает функцию с описанием this: void, что приведет к ошибке. Для того, чтобы это исправить, нужно поменять тип this:

Теперь все в порядке. Но это также означает, что мы не можем использовать this.info. Если все же нам нужно его использовать, то стоит воспользоваться стрелочной функцией:

Этот пример сработает, поскольку стрелочные функции не захватывают this, так что всегда можно передавать такую функцию туда, где ожидается this: void. С одной стороны, стрелочная функция создается для каждого объекта с типом Handler. С другой, — методы создаются только один раз и привязываются к прототипу Handler'a и являются общими для всех объектов типа Handler.

В JavaScript не является редкостью, когда одна функция может возвращать различные типы объектов в зависимости от входных параметров. Например:

Функция pickCard возвращает два различных результата в зависимости от того, что передано в функцию. Если передается объект, который представляет собой колоду карт, функция вернет карту из этой колоды. Если нет, карта сгенерируется случайным образом. Как это можно описать по-другому в TypeScript?

Нужно использовать перегрузку функций. Перегрузка функций — это набор одноименных функций с разным набором параметров. Перепишем пример, рассмотренный выше:

Теперь мы можем вызывать функции с проверкой типов передаваемых аргументов.

Компилятор при выборе нужной функции действует аналогично JavaScript. Он смотрит на список перегруженных функций и пробует вызвать первую. Если удачно, то это корректная перегрузка. Если нет — идет дальше. Поэтому важно указывать перегрузки в порядке, начиная от наиболее часто используемой.

Стоит также отметить, что function pickCard(x): any не входит в список перегрузок. В нашем примере только две перегрузки функции: одна принимает объект, другая — число. Попытка вызвать функцию pickCard с другими параметрами приведет к ошибке.

Компоненты и пропсы – React

Компоненты позволяют разбить интерфейс на независимые части, про которые легко думать в отдельности. Их можно складывать вместе и использовать несколько раз. На этой странице мы ознакомимся с самой идеей компонентов — детальное описание API находится здесь.

Во многом компоненты ведут себя как обычные функции JavaScript. Они принимают произвольные входные данные (так называемые «пропсы») и возвращают React-элементы, описывающие, что мы хотим увидеть на экране.

Функциональные и классовые компоненты

Проще всего объявить React-компонент как функцию:

function Welcome(props) {
  return <h2>Привет, {props.name}</h2>;
}

Эта функция — компонент, потому что она получает данные в одном объекте («пропсы») в качестве параметра и возвращает React-элемент. Мы будем называть такие компоненты «функциональными», так как они буквально являются функциями.

Ещё компоненты можно определять как классы ES6:

class Welcome extends React.Component {
  render() {
    return <h2>Привет, {this.props.name}</h2>;
  }
}

С точки зрения React, эти два компонента эквивалентны.

Функциональным и классовым компонентам доступны дополнительные возможности, о которых мы поговорим в следующих главах.

Как отрендерить компонент

Пока что мы только встречали React-элементы, представляющие собой DOM-теги:

Но элементы могут описывать и наши собственные компоненты:

const element = <Welcome name="Алиса" />;

Когда React встречает подобный элемент, он собирает все JSX-атрибуты и дочерние элементы в один объект и передаёт их нашему компоненту. Этот объект называется «пропсы» (props).

Например, этот компонент выведет «Привет, Алиса» на страницу:

function Welcome(props) {  return <h2>Привет, {props.name}</h2>;
}

const element = <Welcome name="Алиса" />;ReactDOM.render(
  element,
  document.getElementById('root')
);

Посмотреть на CodePen

Давайте разберём, что именно здесь происходит:

  1. Мы передаём React-элемент <Welcome name="Алиса" /> в ReactDOM.render().
  2. React вызывает наш компонент Welcome с пропсами {name: 'Алиса'}.
  3. Наш компонент Welcome возвращает элемент <h2>Привет, Алиса</h2> в качестве результата.
  4. React DOM делает минимальные изменения в DOM, чтобы получилось <h2>Привет, Алиса</h2>.

Примечание: Всегда называйте компоненты с заглавной буквы.

Если компонент начинается с маленькой буквы, React принимает его за DOM-тег. Например, <div /> это div-тег из HTML, а <Welcome /> это уже наш компонент Welcome, который должен быть в области видимости.

Чтобы узнать больше про это соглашение, прочитайте Углублённое изучение JSX.

Композиция компонентов

Компоненты могут ссылаться на другие компоненты в возвращённом ими дереве. Это позволяет нам использовать одну и ту же абстракцию — компоненты — на любом уровне нашего приложения. Неважно, пишем ли мы кнопку, форму или целый экран: все они, как правило, представляют собой компоненты в React-приложениях.

Например, компонент App может отрендерить компонент Welcome несколько раз:

function Welcome(props) {
  return <h2>Привет, {props.name}</h2>;
}

function App() {
  return (
    <div>
      <Welcome name="Алиса" />      <Welcome name="Базилио" />      <Welcome name="Буратино" />    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

Посмотреть на CodePen

В приложениях, написанных на React с нуля, как правило, есть один компонент App, который находится на самом верху. В случае, если вы переписываете существующее приложение на React, имеет смысл начать работу с маленького компонента типа Button и постепенно двигаться «вверх» по иерархии.

Не бойтесь разбивать компоненты на части.

Допустим, у нас есть компонент Comment:

function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <img className="Avatar"
          src={props.author.avatarUrl}
          alt={props.author.name}
        />
        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

Посмотреть на CodePen

Этот компонент представляет собой комментарий в социальной сети. Его пропсы включают в себя author (объект), text (строка), и date (дата).

С этим компонентом может быть не очень удобно работать из-за излишней вложенности. Мы также не можем повторно использовать его составные части. Давайте извлечём из него пару компонентов.

Для начала извлечём Avatar:

function Avatar(props) {
  return (
    <img className="Avatar"      src={props.user.avatarUrl}      alt={props.user.name}    />  );
}

Компоненту Avatar незачем знать, что он рендерится внутри Comment. Поэтому мы дали его пропу чуть менее конкретное имя — user, а не author.

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

Теперь можно немножко упростить наш Comment:

function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <Avatar user={props.author} />        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

Следующим шагом извлечём компонент UserInfo, который рендерит Avatar рядом с именем пользователя:

function UserInfo(props) {
  return (
    <div className="UserInfo">      <Avatar user={props.user} />      <div className="UserInfo-name">        {props.user.name}      </div>    </div>  );
}

Это позволит ещё сильнее упростить Comment:

function Comment(props) {
  return (
    <div className="Comment">
      <UserInfo user={props.author} />      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

Посмотреть на CodePen

Извлечение компонентов может сначала показаться неблагодарной работой. Тем не менее, в больших приложениях очень полезно иметь палитру компонентов, которые можно многократно использовать. Если вы не уверены, извлекать компонент или нет, вот простое правило. Если какая-то часть интерфейса многократно в нём повторяется (Button, Panel, Avatar) или сама по себе достаточно сложная (App, FeedStory, Comment), имеет смысл её вынести в независимый компонент.

Пропсы можно только читать

Компонент никогда не должен что-то записывать в свои пропсы — вне зависимости от того, функциональный он или классовый.

Возьмём для примера функцию sum:

function sum(a, b) {
  return a + b;
}

Такие функции называют «чистыми», потому что они не меняют свои входные данные и предсказуемо возвращают один и тот же результат для одинаковых аргументов.

А вот пример нечистой функции — она записывает данные в свои же аргументы:

function withdraw(account, amount) {
  account.total -= amount;
}

React достаточно гибкий, но есть одно правило, которое нельзя нарушать:

React-компоненты обязаны вести себя как чистые функции по отношению к своим пропсам.

Конечно, интерфейсы приложений обычно изменяются с течением времени. В следующей главе мы узнаем о том, что такое «состояние» компонента. Состояние даёт компонентам возможность реагировать на действия пользователя, ответы сервера и другие события, не нарушая чистоту компонента.

используем JSDoc, Flow и Documentation.js

От автора: для чего нужно документировать проекты на Javascript? Мы все (надеюсь) знаем, насколько важна хорошая документация и справочные материалы для успешного программного проекта. Без хорошей документации конкретная библиотека может быть недоступна для использования. Без описания того, как разные компоненты и методы работают изолированно, не говоря уже о примерах того, как разные части проекта соотносятся друг с другом, нам остается только интерпретировать первоначальное намерение автора, просто изучая исходный код, или, если повезет, читать StackOverflow и гуглить посты о подобных ошибках. Если это внутренний или небольшой проект, вы, вероятно, можете особо не переживать по этому поводу. Берете на вооружение подход черной магии вуду — копи-паст, и надеетесь, что все будет работать по назначению!

Но сравните это с хорошо зарекомендовавшими себя проектами, которые имеют отличную документацию, и совершенно противоположный опыт. Например, документация API Stripe не только чиста и удобна для просмотра, для нее также реализован удобная навигация, и она аннотируется примерами на 8 разных языках относительно того, как правильно взаимодействовать с их API-интерфейсом разработчика. Хотите узнать, как создать новый клиент? Конечно! На каком языке вы хотите написать код?

Подобный уровень надежности становится необходимым при использовании огромных, публичных проектов, таких как платежи по Stripe, но может быть необязательным для ваших собственных или небольших проектов. Это не значит, что вы можете пренебречь документацией! Это просто означает, что наша цель при документировании личных проектов должна состоять в том, чтобы получить максимальную отдачу от каждого доллара. Способ, которым мы можем это сделать, — правильно комментировать наш код и использовать существующие в сообществе Javascript инструменты, чтобы предоставить понятную и полезную документацию с минимальными затратами сил и времени.

Документация API Stripe — это та-а-ак красиво …

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее

В этой статье мы поговорим о том, как использовать два разных инструмента, а именно JSDoc и Documentation.js, чтобы получить доступную, согласованную документацию на уровне API для вашего кода Javascript с минимальными усилиями. В студии 4Thought мы являемся поклонниками использования Flow, поэтому мы применим его, чтобы сделать вещи еще более понятными. Стремясь быть максимально полезными и краткими, мы не будем углубляться в полный синтаксис JSDoc, но стоит упомянуть, что документация THEIR (хотя и выглядит не очень красиво) хорошо читаема, и вам стоит потратить 20 минут или около того, чтобы ознакомиться с ней.

JSDoc

JSDoc — это стандартизированный способ написания комментариев в коде для описания функций, классов, методов и переменных в вашей базе кода. Если вы знакомы с JavaDocs или любыми его производными (например, доступными в PHP), то JSDocs будет вам понятен. Идея заключается в том, что мы описываем, как наш код работает с помощью нескольких специальных ключевых слов и конвенции форматирования, и мы можем использовать синтаксический анализатор для парсинга всего кода с комментариями и создания хорошей, читаемой документации, основанной на комментариях, которые мы пишем. Как это выглядит на практике? Вот краткий пример:

/**
* Складываем числа
*
* @param {number} first — первое число
* @param {number} second — второе число
* @returns {number}
*/
function add(first, second) {
return first + second;
}

/**

* Складываем числа

*

* @param {number} first — первое число

* @param {number} second — второе число

* @returns {number}

*/

function add(first, second) {

  return first + second;

}

Итак, что здесь происходит? Ну, мы сначала хотим сказать, что собираемся написать специальный комментарий JSDoc, начав комментарий с / **. Если мы начнем с одной звездочки, или добавим третью, JSDoc просто проигнорирует комментарий, поэтому обратите внимание на количество звездочек!

Затем мы выписываем краткое описание функции, которую мы документируем на понятном языке, чтобы кто-то, читающий нашу документацию по коду или API, понимал назначение функции. Наконец, мы аннотируем наши два параметра, а также аннотируем возвращаемое значение. И … это в основном все!

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

Documentation.js

После того, как ваша база кода достаточно задокументирована, пришло время обратиться к инструменту, который поможет создать документацию на основе всех замечательных комментариев, которые вы только что написали. В студии 4thought мы используем фантастический проект Documentation.js, но есть несколько других вариантов. Все эти проекты делают одно и то же — они переписывают ваши тщательно написанные комментарии кода JSDoc в читаемую документацию html или markdown.

Documentation.js — это node-пакет, предназначенный для анализа JSDoc и вывода документации в нескольких разных форматах. Мы используем Markdown, чтобы иметь возможность напрямую ссылаться на документацию API непосредственно в нашей вики проекта, но для вас может быть более приемлемо выводить документы как полностью функционирующий веб-сайт. Какой бы подход вы ни выбрали, вам придется вводить Documentation.js в качестве общесистемной или проектной зависимости:

yarn global add documentation

yarn global add documentation

(или npm install -g documentation, если вы предпочитаете npm)

Затем мы можем ссылаться на документацию Documentation.js (примерно в 5 раз быстрее), чтобы указать, как парсировать ваши файлы javascript в читаемую документацию (извините за то, что я повторяюсь, я не думаю, что есть другой способ сказать «документация»).

documentation build path/to/your/javascript.js -f html

documentation build path/to/your/javascript.js -f html

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее

Мы используем пакет documentation для создания документации из указанного исходного файла (ов) и отформатировать его в html с помощью флага -f. Мы могли бы также выводить документацию в формате markdown, для этого нужно изменить приведенную выше команду:

documentation build path/to/your/javascript.js -f md

documentation build path/to/your/javascript.js -f md

Я знаю, о чем вы сейчас думаете — все это здорово, но значит ли это, что я должен парсировать файлы по одному за раз? Это совсем не экономия времени!

Придержите лошадей — конечно, вам не нужно парсировать файлы по одному за раз! Предположим, что все ваши файлы javascript находятся в папке src/ проекта. Вы можете парсировать их все одним махом:

documentation build src/** -f html -o docs

documentation build src/** -f html -o docs

Эта команда запустит парсинг всех файлов javascript в папке src и подкаталогах, отформатирует их в html и выведет результаты в папку docs/. Довольно аккуратно!

В качестве бонуса, когда вы выполните приведенную выше команду, включите ее в качестве дополнительного скрипта в папке package.json, чтобы упростить все в будущем:

// package.json
{

«scripts»: {
«docs:build»: «documentation build src/** -f html -o docs»
}
}

// package.json

{

  …

  «scripts»: {

    «docs:build»: «documentation build src/** -f html -o docs»

  }

}

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

yarn docs:build
# or
npm run docs:build

yarn docs:build

# or

npm run docs:build

Ваша документация!

Веб-сайт, который четко сообщает, что создает инструменты разработки!

Бонус: интеграция Flow

Если вы используете Flow, как и мы в 4Thought Studios, вы можете еще упростить процесс документирования. Зачем переписывать информацию о типе ваших параметров, если вы уже записываете все свои параметры и возвращаете типы в коде?
Благодаря интеграции Flow с Documentation.js мы можем изменить наш оригинальный пример:

// @flow
/**
* Слагаем числа
*/
function add(first: number, second: number): number {
return first + second;
}

// @flow

/**

* Слагаем числа

*/

function add(first: number, second: number): number {

  return first + second;

}

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

Автор: Brad Dunn

Источник: //medium.com/

Редакция: Команда webformyself.

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Смотреть

Александр Галицкий: по натуре я фаталист

Основатель венчурного фонда Almaz Capital Partners — в спецпроекте «Первые лица бизнеса»

Часть 1

О водителе, гитарах, отце, выборе, «звездных войнах» и трансформации

— Говорят, кто не рискует, тот не пьет шампанское. Это о венчурных инвесторах, Александр?

— Шампанское употребляю, но к любимым напиткам не отношу. Из легкого алкоголя предпочитаю рислинг. В юности и студенчестве считал его самым противным вином — кислятиной. Лишь со временем понял, что есть и другой рислинг. Франция, Германия, Австрия производят очень неплохой.

Но красные вина я тоже люблю. Как говорится, был бы повод, чтобы поднять бокал.

— Закрытие сделки наверняка отмечаете?

— Команда нашего фонда разбросана по миру, люди сидят в самых разных местах, вместе собираемся дважды в год. Тогда и празднуем все, что накопилось за это время.

— Где встречаетесь?

— Да по-разному. Например, на острове Ольхон на Байкале, в Лас-Вегасе, Сан-Франциско, Лондоне, Италии, Португалии… Выбираем места, чтобы нормально провести время всей командой. И пообщаться, и поработать, и отдохнуть. Точнее, выбирали.

К сожалению, о поездках пока приходится говорить в прошедшем времени: пандемия внесла коррективы.

— Сколько человек в Almaz Capital?

Сейчас — 14. Не очень много. Основная база — Калифорния. Обычно там происходит так называемый exit из наших портфельных компаний, но главное даже не в этом. Именно в Силиконовой долине есть спрос на нашу работу. Так сложилось в мире, что потребление инноваций, по крайней мере в области информационных технологий, наиболее востребовано там. Доля США в этом процессе весьма значительна. Особенно в первые три года после появления какой-то новой технологии.

В Штатах все построено на конкуренции даже традиционных бизнесов через внедрение инновационных подходов или покупку компаний, ими обладающих.

Европейцы решения принимают медленно, боятся, не рискуют, взвешивают: вдруг новый проект не выживет? В Америке мыслят иначе: а если он выстрелит и в течение первых трех лет принесет колоссальное преимущество по сравнению с конкурентами?

Поэтому наш основной офис, связанный с анализом спроса и предложения, — там, в Калифорнии. А еще люди есть в Лондоне, Берлине, Варшаве, Киеве и здесь, в Москве.

До пандемии примерно треть времени я проводил в Америке. В России, думаю, четверть, остальное — в Европе и Азии. Можно сказать, еще год назад фактически жил в самолете. Три-четыре перелета в неделю были нормой.

— У вас свой борт?

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

Давно ввел в обиход определенные привычки. К примеру, принципиально езжу без водителя. Обычно за рулем внедорожника BMW Х5 с затемненными стеклами. Из-за этого регулярно бывают забавные случаи. Когда подъезжаю к подмосковному загородному дому кого-нибудь из знакомых, охрана или прислуга по привычке распахивает заднюю дверь в расчете увидеть там пассажира, потом с недоумением смотрит на меня, мол, а гость-то где? Иногда шучу: «Хмм… Неужели потерял по дороге?»

Лишь для каких-то официальных приемов беру машину с водителем. Чтобы избегать двусмысленностей.

Мне действительно проще ездить самому. Нормальный европейско-американский подход. В России на ситуацию смотрят несколько иначе. Была смешная история. Приехал на встречу в офис, откуда меня забрали на следующие переговоры на другой машине. Потом вернулся за своим автомобилем и… не нашел его. Удивился: вроде припарковался в правильном месте, ничего не нарушил, а авто эвакуировали на штрафстоянку… Оказалось, товарищ решил надо мной подшутить. Сказал: «Нечего жмотиться на шофера…»

© Сергей Бобылев/ТАСС

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

У меня был ненормированный рабочий день по 12–14 часов. У «личника» вроде тоже. Правда, я вкалывал с утра до вечера, постоянно чем-то занимался, участвовал в совещаниях, вел переговоры, а водитель откидывал кресло в салоне машины и спал. Его функции — отвезти шефа из точки А в точку Б. В чем смысл этой процедуры? Помню, все водители были гораздо старше меня и жаловались на переработки. Понятно, человек отвлекается от семьи и дома, но эта ситуация всегда меня очень раздражала. Когда стал работать за рубежом, увидел, что владельцы крупных бизнесов, миллиардеры совершенно спокойно приезжают на работу за рулем. Обычная практика.

‘ Максим Чурусов/ТАСС’

— А как произошла ваша трансформация физика-теоретика в международного инвестора?

— Это жизнь. Она преобразовывает нас, ставя перед выбором. Но сначала она переформатировала меня в международного технологического предпринимателя, а уже потом в инвестора.

Думаю, на стартовом этапе многое предопределило то, что, окончив с золотой медалью среднюю школу в Житомире, я решил ехать на учебу в Москву, поступать в Физтех. С формальной точки зрения в юности у меня все складывалось легко и просто. Хотя, если копнуть, всякие любопытные истории всплывают.

— Например?

— Классе в восьмом мы с ребятами наладили производство электрогитар. Это был жуткий дефицит в ту пору. Не купить! Сначала собрали для себя, создали, как тогда говорили, ВИА — вокально-инструментальный ансамбль. Потом запустили процесс изготовления пары десятков инструментов, пока нас не остановили.

— Кто?

— Те, кому по долгу службы положено.

— А вы продавали гитары?

— Конечно! Даже перестали думать про наш ВИА. Пробовали, экспериментировали…

Что-то изготавливали на местной музыкальной фабрике, радиоэлектронику делали сами. Муж моей сестры работал в Днепропетровске на заводе «Южмаш». Я попросил его по чертежам выточить недостающие для десяти комплектов детали из металла, а он сделал их из титана. «Южмаш» — предприятие оборонное, там ракеты собирали…

Еще я сглупил и поставил в радиоэфир «Восточную песню» для любимой девушки Светы. Ее в свое время исполнял Валерий Ободзинский.

Льет ли теплый дождь,

Падает ли снег —

Я в подъезде против дома

Твоего стою…

Разумеется, разрешения на самостоятельное вещание нам никто не давал, это было запрещено…

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

— Ваш отец же был председателем крупного колхоза, уважаемым человеком.

— Папа, конечно, вмешался. Эту историю не предали огласке. Но она, подозреваю, стоила ему звания Героя Социалистического Труда… К тому моменту отец успел получить кучу государственных наград. Но «Золотой Звезды» так и не дождался, его дважды вычеркивали из списков. Причин могло быть много. Наверное, в душе отец испытывал обиду, но никогда об этом не говорил вслух.

Он был очень успешным и инициативным руководителем. К примеру, под его началом придумали новый сорт яблочного вина и наладили выпуск «Золотой осени», добившись высочайшего качества, — в дополнение ко всяким консервам и джемам. Достаточно сказать, что продукцию колхоза поставляли к столу членов ЦК Компартии Украины.

Когда объемы стали расти, отец построил стеклозавод для производства тары. Он всю жизнь трудился, постоянно затевал новые проекты, жить не мог без дела — теплицы для овощей, цветов и грибов, также свой мясокомбинат…

В 80 лет занялся строительством костела. Папа был католиком по вероисповеданию. Потратил на стройку много сил и времени. Очень хотел, чтобы получился общественный проект. Поначалу отец возражал, чтобы я жертвовал больше остальных. Поэтому я помогал наравне со всеми и подключился на финальном этапе, когда в 2014-м у общины закончились деньги…

Рад, что мы успели все завершить, папа доделал последний проект и полгода посещал действующий костел.

Отца не стало в начале 2017-го, ему было уже 89 лет…

С отцом Владимиром и сыном Александром, 2005 год

© Личный архив Александра Галицкого

— Предпринимательская жилка от него?

— Наверное, что-то унаследовал…

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

— Почему вы решили ехать учиться в Москву, а не в Киев, который находится гораздо ближе?

— Вообще-то я собирался стать журналистом, мечтал увидеть мир, побывать за пределами Советского Союза. На мой взгляд, писал неплохие тексты, выигрывал школьные олимпиады по литературе. Например, сочинил романтическую историю на украинском языке о том, что роса — слезы солнца. Рассказ так и назывался — «Сльози сонця». Его опубликовали в областной газете.

Словом, на журналистику я нацеливался всерьез. А потом как-то прихожу домой и вижу разложенные на столе передовицы — от «Правды» и «Известий» до районки. Папа говорит: «Читай». Я удивился: «Зачем?» Тогда все открывали газеты с последней страницы — с новостей спорта, дальнего зарубежья, телепрограммы и погоды.

А папа продолжил: «Вот об этом — выступлениях Брежнева, показателях сбора урожая, решениях Пленума ЦК КПСС, сынок, ты будешь писать ближайшие лет 10–15. После этого тебе, возможно, разрешат про спорт и дальнее зарубежье…»

Сказанное подействовало на меня отрезвляюще. Отец шаг за шагом подвел к тому, что я родился в городе, где и Сергей Павлович Королев. Мол, увлекаешься техникой, имеешь склонность к точным наукам, соберешь еще что-нибудь поинтереснее гитар.

Поэтому после школы я поехал в Москву и подал документы в Физтех. Правда, в анкете написал, что из семьи служащих, хотя мог указать, что из колхозников. В итоге мне чуть-чуть не хватило до проходного балла. Социальное происхождение не зачли. Расстроился, помню, сильно. Решил: вот отслужу в армии и опять приеду поступать туда же.

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

Кроме того, я не указал в документах, что серьезно занимался плаванием, выполнил норматив мастера спорта на дистанции 200 метров вольным стилем. Поскромничал, а это был дополнительный козырь…

В общем, пролетел мимо Физтеха. Не попав туда, уже хотел возвращаться в Житомир, но решил навестить одноклассницу, поступавшую в Московский институт электронной техники в Зеленограде. Приехал, и так мне там понравилось! Город будущего. Мама одноклассницы преподавала математику в Житомирском политехническом институте, знала уровень моей подготовки и стала убеждать не терять годы на службу в армии, а нести документы в МИЭТ, куда набранных в Физтехе баллов хватало. Я послушался совета и в дальнейшем не пожалел об этом.

Первое время продолжал думать по-украински и даже конспекты вел на мове. Но потом адаптировался, хотя на Украину, конечно, тянуло.

— И сейчас?

— А как иначе? Родина!

— Давно были?

— В Житомире более года назад. Там живет моя сестра и близкая родня. В Киев по делам наведываюсь чаще.

— Пускают без проблем? На границе не интересуются, чей Крым?

— Ни разу никто об этом не спрашивал.

— А если зададут вопрос?

— Отвечу. Мне скрывать нечего. В царское время Крым принадлежал Российскому государству. Но в состав Османской империи он входил еще дольше. Какой смысл вспоминать прошлое? Надо ориентироваться на подписанные и действующие сейчас международные обязательства. Их необходимо выполнять.

— Разобрались. Возвращаемся к теме превращения советского человека в бизнесмена.

— После окончания учебы в МИЭТе я пришел работать в НИИ микроприборов, который входил в научно-производственное объединение ЭЛАС. За этим ничего не выражающим названием стояла суровая оборонка. По сути, я попал на передний край гонки вооружений. Мы занимались космическими системами и комплексами, строили их на основе последних достижений микроэлектроники.

НПО «ЭЛАС» руководил легендарный генеральный конструктор Геннадий Яковлевич Гуськов, еще в 1951 году получивший Сталинскую премию за создание первого радара наземного базирования, а после полета Гагарина ставший Героем Соцтруда за систему космической связи. Вся телеметрия была на нем. Гуськов сделал и первый компьютер, который в 1972 году улетел на спутнике на околоземную орбиту. Опередил американцев.

Он придумал и подвижную ранцевую связь с использованием его же космических ретрансляторов на основе ААФР (активных антенно-фазированных решеток), с помощью которой можно было из любой точки планеты поговорить с кем угодно. Когда в 1972 году Никсон прилетал в Москву, он похвастался перед Брежневым такой опцией, а через пару лет уже Брежнев демонстрировал Никсону аналогичную связь советского производства.

У станции космической связи на основе плоской антенно-фарерованной решетки, по которой передавалась информация через IP-протокол, 1990 год

© Личный архив Александра Галицкого

Потом Геннадий Яковлевич создал первый спутник оптико-электронной разведки.

На этом этапе моя карьера в ЭЛАСе и началась. На работу меня взял Владимир Брюнин, разглядев еще на четвертом курсе института. Так я занялся софтом для спутника дистанционного зондирования Земли.

Геннадий Гуськов мне доверял и в 1987-м назначил ответственным в ЭЛАСе за компьютерные системы и программное обеспечение спутников. Думаю, моложе меня в советской оборонной промышленности главных конструкторов в тот момент не было. В 32-то года от роду!

— А спутники — военные?

— Конечно. Космическая система для наблюдения за стратегическим противником. Благодаря этому еще в начале 1980-х годов я в подробностях изучил карту Сан-Диего.

— Почему именно его?

Там база Тихоокеанского флота США. Подводные лодки стоят. Мы часто их снимали. Во всех деталях. Когда 12–13 лет спустя я впервые попал в этот город, свободно обходился в нем без навигатора. Ни разу не заблудился!

​​​​— Это был ваш первый визит в Штаты?

— Нет, прилетал туда несколькими годами ранее. В марте 1991 года академик Сагдеев, который, как известно, был женат на внучке президента Эйзенхауэра, организовал советско-американскую научно-техническую выставку космических достижений. СССР с распростертой душой отправил в США лучшие разработки. Так, мы потащили ранцевую станцию, другие показали макет ядерного движка, «Луноход»…

В Штаты-то экспонаты ввезли, а потом не могли забрать. По американским законам вывозить что-либо из страны можно лишь по официальному разрешению властей.

— Всех «пущать», никого не «выпущать»?

— Примерно так. В отличие от России, где политика строится на запрете и ввоза, и вывоза. В США в этом смысле более разумная система.

После долгих переговоров нам вернули экспонаты, они потом хранились где-то в советском посольстве в Вашингтоне. История закончилась благополучно, но определенный опыт мы получили, поняли, что надо вести себя аккуратнее…

Вскоре, в апреле 1991-го, по настоянию Гуськова меня включили в очередную поездку в США. Мы в ЭЛАСе занимались «ответом» на американскую инициативу «звездных войн». Американцы предложили организовать семинар в Вашингтоне по борьбе с космическим мусором и прочесть лекции в университетах. Звали шефа, но он лететь отказался, сказал: «Запишите Сашку, он молодой, ему интересно». К тому же руководство Sun Microsystems еще в марте пригласило меня посетить их компанию в Силиконовой долине.

С астронавтом Appolo-9 Расселом Шфайкартом, его женой Ненси и Джоном Гейджем в Sun Microsystems, Калифорния, 1993 год

© Личный архив Александра Галицкого

Я очень хотел туда попасть, это была мечта любого инженера!

Тогда прямые рейсы из Вашингтона в Сан-Франциско еще не ввели. Программа визита в столицу США завершилась, и дальше я полетел один с пересадкой в Денвере. Приземлились, и тут объявление: «Мистер Галицкий, вас ждут на трапе самолета». Помню, подумал: «Вот гады! Наверняка вашингтонские церэушники не пускают. Не увижу долину!»

Нормальная реакция советского человека, везде подозревающего подвох. Оказалось, мне хотели вручить факс от организаторов семинара с пожеланиями успешного полета.

В Сан-Франциско меня встречал астронавт Рассел Швайкарт, который на Apollo 9 летал к Луне и выходил в открытый космос. У него тогда возникла идея совместно сделать низкоорбитальную систему связи, а это моя тема, я ей занимался. Мы дружим с Расселом до сих пор.

Посещение долины и Sun Microsystems (в 90-е годы это была самая яркая компания!) произвело на меня сильное впечатление. Водили по лабораториям, все показывали, ничего не скрывали, хотя могли бы шифроваться. Было много встреч, часть собеседников я уже знал заочно, читал их работы. Некоторые стали моими друзьями — Скотт Макнили, Эрик Шмидт, Джон Гейдж и, конечно, Джефф Баер, впоследствии мой партнер в Almaz Capital Partners.

Все выглядело настоящей фантастикой по тем временам!

— Вам заплатили за лекции в Вашингтоне?

— Это не подразумевалось. Организаторы и так взяли на себя все расходы. А Sun превзошел любые ожидания. В гостинице меня поселили в супер-пупер-номере, в каких я никогда не жил. Даже с джакузи! Мексиканец, работник отеля, хотел объяснить, как пользоваться агрегатом, но я гордо отверг помощь, мол, сам разберусь. Начал нажимать на кнопки, включил какой-то режим, со всех сторон потекла вода, забила фонтанчиками, я не знал, как остановить это действо…

Как говорится, и смех и грех.

Но, конечно, не это главное, что я увидел в Силиконовой долине. Тогда и предположить не мог, что моя жизнь столь радикально изменится. Потом я стал летать в США в среднем пять-шесть раз в год. Но в 1991-м все было в новинку. Тогда и в дальнейшем я встретился и пообщался со многими интересными людьми — Биллом Гейтсом, Джоном Чемберсом, Джеймсом Гослингом, Брюсом Шнайером, Уитфилдом Диффи… Всех не перечислишь.

С Биллом Гейтсом в Москве, 1997 год

© Личный архив Александра Галицкого

Помню, в 1994 году познакомился с генералом Абрахамсоном, который прежде возглавлял в Пентагоне программу «звездных войн». Поскольку я числился в списке нашего «антиответа», американцы специально пригласили меня на разговор. Видимо, Абрахамсон захотел пообщаться с человеком с другой стороны баррикад. Показывал свои достижения…
Надо сказать, по некоторым направлениям мы опережали Штаты очень серьезно

— Как вас выпускали из СССР, Александр? Вы знали секреты родины и наверняка имели серьезные ограничения при контакте с иностранцами.

— Все верно. У меня был самый высокий допуск — так называемая «особая важность». По другой классификации — «первая». «Совершенно секретно» стоит ниже.

Но не забывайте, это закат Советского Союза, система ослабила хватку. В конце 80-х годов уже создавали совместные предприятия. Я сам подписывал документы для регистрации нескольких таких СП.

А первый мой выезд за границу состоялся в 1990 году в Финляндию. Через Министерство электронной промышленности СССР мне сделали синий, служебный паспорт. Приехал получать, а документ не отдают. В буквальном смысле! Замминистра, курировавший международные дела, исподлобья взглянул в мою сторону и хмуро заявил, что восемь раз был в Финляндии и ничего интересного там не увидел.

По молодости я не лез за словом в карман и с ходу ответил: «Знаете, а мне хватит одной поездки, чтобы разобраться, надо ездить туда или нет». Ясное дело, начальник сильно обиделся, выставил из кабинета. Я позвонил шефу, описал ситуацию. Гуськов говорит: «Никуда не уходи из приемной, жди». Действительно, через короткое время этот замминистра позвал к себе каких-то подчиненных, потом вышел ко мне и бросил паспорт. Еще и прошипел сквозь зубы: «Думаешь, с таким боссом сможешь все решить? Припомню еще тебе!» Я промолчал, взял паспорт и ушел.

— А на Лубянку для инструктажа вызывали?

— По этому поводу — нет. У нас был свой так называемый первый отдел, где работали спецслужбисты. Но повторяю, империя рушилась, прежние правила переставали действовать.

Историю с паспортом мне припомнили в 1998 году, когда подошло время менять документ на новый. Я вернулся из командировки в США и собирался переезжать в Европу, где уже стартовала моя новая компания. Прилетел в Москву за паспортом, думал, быстро оформлю и опять уеду, но не тут-то было. Мне отказались его выдать!

— Мотивация какая?

— В связи с прежними допусками по секретности. Очнулись спустя почти десять лет…

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

Часть 2

О продаже родины, путче, опросе с пристрастием, зонтике и русском менталитете

— При желании вы ведь могли продать родину с потрохами?

— За десять-то лет? Конечно. Тысячу раз!

— Вам предлагали?

— Нет. Видимо, мое поведение не предполагало подобных обращений.

Перед каждой поездкой в Штаты проводился строгий инструктаж, но и без этих наставлений я действовал правильно, поскольку не собирался ничего никому сливать. Да и в Америке не дураки сидели, смотрели, кто и как проявляет себя с первого шага. Делали выводы, стоит ли начинать разговор о «сотрудничестве»…

— После возвращения в Москву из загранкомандировок вы писали отчеты о поездках?

— Да, но не на Лубянку. Вернувшись из Силиконовой долины, даже подготовил аналитическую записку в ЦК КПСС. Мы обсуждали эту тему на Старой площади 12 августа 1991 года. Участвовали мой шеф Гуськов, секретарь ЦК Бакланов, отвечавший за оборонку, управделами ЦК Кручина…

Помню, подняли по рюмке коньяка и договорились, что в сентябре начнется серьезная работа над моим планом.

© Сергей Бобылев/ТАСС

— А через неделю грянул ГКЧП, Бакланов оказался в числе путчистов, Кручина выбросился из окна…

— Конечно, подобного никто не мог предвидеть. Все договоренности рухнули.

— В чем заключалось ваше предложение, Александр?

— Силиконовая долина потрясла меня интернациональностью. Увидел офисы Siemens Nixdorf, Toshiba, Philips, Sony, Alcatel, Nokia, Hyundai, Samsung… Компании представляли весь мир. И ни одного русского названия! В то время в СССР приезжали представители многих иностранных компаний и частные предприниматели, пытались наладить взаимовыгодное сотрудничество, но партнерские отношения почему-то не складывались. Проблема была, возможно, в менталитете людей или в переоценке наших технологий.

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

Но ГКЧП смешал все карты…

Когда произошел путч, я ехал в поезде из Новосибирска в Бийск. На Телецком озере планировалась конференция по сигнальным процессорам. Даже новости о событиях в Москве удавалось узнавать с трудом. Интернет уже был, а мобильная связь и сотовые телефоны — нет. Чтобы позвонить в столицу, приходилось идти куда-то на почту. По телевизору же крутили «Лебединое озеро»…

К счастью, эта заваруха продолжалась недолго, но идея проекта в Силиконовой долине заглохла.

Уже тогда я понимал, что замысел сам по себе ничего не стоит, важна его реализация. Красивых идей может быть множество, но кто-то должен воплотить их в жизнь, иначе они умрут, не родившись. Через какое-то время осознал еще одну истину: совместное предприятие никогда не бывает успешным

— Почему?

— У создателей неизбежно возникает конфликт интересов. Оглянитесь вокруг, посмотрите, много ли видите удачных примеров СП. Sony Ericsson хотели создать лучший мобильный телефон. Где он, где предприятие? Оно развалилось.

Автоконцерны объединялись — это правда, но все равно продолжали функционировать как отдельные структуры, конкурирующие в рамках холдинга.

Когда отдельные компании приступают к совместному производству чего-то материального, какого-нибудь софта, они начинают соперничать за доминирование. Обычно все заканчивается либо развалом, либо поглощением слабого более сильным.

‘ Максим Чурусов/ТАСС’

— Тем не менее вы создали компанию ЭЛВИС+, которая стала сотрудничать с американской Sun Microsystems. Кстати, что за название такое странное вы выбрали?

— К королю рок-н-ролла Пресли оно имело опосредованное отношение. Элвис мне, конечно, нравился, но все было прозаичнее: это аббревиатура — «Электронно-вычислительные информационные системы».

Что касается кооперации с Sun, эта компания в то время выступала законодателем мод в области информационных технологий и интернета. Именно ей мир благодарен за внедрение интернет-технологий в нашу жизнь и в бизнес: язык Java, Firewall, VPN, RISC-архитектура, интернет-сети и так далее. Они бросили вызов Microsoft и многим другим, были основателями той культуры, которую Эрик Шмидт позже удачно внедрил в Google. Ее учредителями стали четыре человека, фактически мои ровесники. Мы воспринимали мир во многом схоже, ценя не столько материальную выгоду, сколько технологические прорывы. Как человек, выросший в СССР, я ничего не понимал в бизнесе, но знал, что с точки зрения решения системных задач в Советском Союзе — при всей его неправильной плановой экономике — разработки велись грамотно и качественно.

С Джефом Баером, Геннадием Гуськовым, Джоном Гейджем и Биллом Джоем во время пикника Sun Microsystems и ЭЛВИС на Волге, 1992 год

© Личный архив Александра Галицкого

Уже говорил, что с середины 1980-х годов я готовил наш ответ «звездным войнам». Мы разрабатывали разные системы, в том числе для передачи и обмена информацией между спутниками-разведчиками.

Это была действующая модель, и еще в октябре 1990 года мы показали американцам, как IP-пакеты, иными словами, блоки данных, ходят через космос. Те выпали в осадок. Окончательно их сразила 22-слойная полиамидная плата размером с пачку сигарет, которую в какой-то момент я небрежно достал из кармана. Подобные платы не делал никто в мире!

В том далеком 1990-м команда американцев во главе с сооснователем Sun Биллом Джоем попросила разрешения приехать к нам на производство. Помню, я позвонил Геннадию Гуськову, объяснил, мол, так и так. Он ответил: «Пусть смотрят». Без согласования с компетентными органами мы приняли у себя на закрытом предприятии иностранцев…

— Как у вас было с английским языком?

— В анкетах этот уровень деликатно назывался «читаю и перевожу со словарем». Я мог поддержать элементарный разговор, но не общаться профессионально.

Конечно, это очень мешало. Тем не менее я начал работать с Sun. В октябре 1991 года мне прислали из Америки 20 высокопроизводительных станций с процессорами SPARC. Каждая стоила более 20 тысяч долларов. Я не мог зарегистрировать компьютеры в ЭЛАС, поскольку получил их как бы для личного пользования. И продать тоже не имел права. Надоумил бывший коллега, ставший к тому времени кооператором: «Не мучайся, Сашка! Стартани собственную компанию».

Так появился ЭЛВИС+, куда станции Sun вошли в качестве начального капитала. Потом мы получили заказ на разработку прототипа современного Wi-Fi в виде карточки, которую надо было вставлять в компьютер. Сделали его в 1993 году, а название Wi-Fi появилось позже.

С антеннами и радиоустройствами для работы с протоколом 802.11 (Wi-Fi), включая реализацию в корпусе PCMCIA, Москва, 1993 год

© Личный архив Александра Галицкого

— А что за история с вашим допросом на украинском языке?

— Все-таки не с допросом, а с закрытыми слушаниями…

Понятное дело, американские спецслужбы меня досконально изучали, проверяли, собирали досье. Я же работал с весьма деликатными темами. Когда началось сотрудничество с Sun Microsystems, забеспокоились даже сенаторы-«ястребы»: «Как? Финансирование русских проектов?»

Для Sun это была первая в их истории инвестиция, и сразу — в российскую компанию. Они собирались выплатить миллион долларов за десять процентов акций ЭЛВИС+.

Решение принималось в кабинетах на Капитолийском холме. Наши оппоненты проделывали всякие подлые штуки. Например, заявили, что я участвовал в создании систем доставки ядерного оружия для неназванных стран Ближнего Востока. Подразумевались Иран, Сирия…

Действительно, Академия наук СССР контактировала с зарубежными коллегами, а ЭЛАС часто нанимал ведущие академические институты для выполнения работ в наших интересах. Мы вместе решали различные задачи. Скажем, при помощи радиолокационных снимков сделали первую карту Венеры. Строили и локаторы для ведения наблюдения, и электронные системы, но к поставкам вооружений это не имело отношения.

Словом, меня вызвали на интервью в Вашингтон. Со мной приехали два представителя Sun, в том числе юрист. История по-своему стремная, поскольку на входе забрали паспорт и я остался без документов. Собралась большая комиссия с участием сенаторов и представителей спецслужб. Вопросы сыпались самые неожиданные, какие только могли придумать. Так, сразу поинтересовались, что я делал в Китае? Но я никогда там не был! Говорят: «А по нашим сведениям, были. С кем встречались, какие темы обсуждали?» Ну и так далее.

Закончилось тем, что дали на подпись бумагу, где значилось, что я и созданные мною компании ни при каких обстоятельствах не станут работать на врагов Соединенных Штатов Америки. Я сделал приписку, что, будучи гражданином Российской Федерации, оставляю за собой право трудиться на свою родину, если наши страны перейдут в стадию официальной вражды

Добавил к печатному тексту, вписал от руки.

Документ остался у американцев, очень сожалею, что по неопытности не сохранил артефакт.

— Здесь эта бумага вам не аукалась?

— Понимаете, когда нужен повод, его найдут. И касается это не только России, но и любой страны мира. Не сомневайтесь: если кто-то влиятельный захочет испортить человеку жизнь, сделает это легко. Однозначно!

Подписывая соглашение с американцами, я поинтересовался: «Как узнать, кто ваши враги?» И каждые две недели стал получать из Sun Microsystems письмо со списком компаний, включенных Госдепом в число запрещенных…

— С отечественным криминалитетом встречаться приходилось, Александр?

— Получал «деловые» предложения… Признаться, всегда избегал засветки в российских СМИ, опасаясь привлекать внимание неадекватных личностей, которые рассуждали примерно так: ага, он успешен, значит, с него можно что-то поиметь. Но мы не для того зарабатывали деньги, чтобы с легкостью ими делиться…

Однажды позвонили от человека, который в будущем вырос в известного олигарха. Без обиняков заявили: «Готовы предоставить зонтик за четверть вашей компании». Я ответил, мол, на улице отличная погода…

Потом представитель одной из спецслужб возил меня в лес. Якобы для серьезного разговора. Вдвоем мы, сжираемые комарами, выпили литр джина, после чего поехали ко мне домой, где осушили еще бутылку водки. Никогда в жизни я столько не пил! Пьяный гость нес какой-то бред о совместном бизнесе, угрожал моей дочери…

Я понимал, что нужно принимать меры, и через знакомых обратился к влиятельному человеку. Объяснил, что меня прессуют не по делу. На этом все на время замерло. Вплоть до 1997 года, когда мы сделали первый VPN для Windows, предварительно взломав NDIS-драйверы в Microsoft. Опять поднялась большая волна в американском истеблишменте, пошли публикации, мол, русские могли утащить секреты в Sun Microsystems.

В России тоже неожиданно запустили историю со стороны уже нашего ФАПСИ, начали перепечатывать истории обо мне из США, писать, мол, скоро появится новый миллиардер. А к богатым у нас во все времена относились примерно одинаково.

Дошло до открытия дела…

— Уголовного?

— Ограничились проверкой, создали серьезную комиссию, в которой участвовали высокие генералы. Не буду называть фамилии, они и сейчас на слуху… В то время мне и заблокировали получение нового паспорта. Правда, потом проверяющие обнаружили, что с момента старта ЭЛВИС+ я не взял ни одного госзаказа, не получил ни рубля из бюджета, и, видимо, рассудили, что «закрывать» меня будет не совсем правильно…
 

С автором проекта «Первые лица бизнеса» Андреем Ванденко

© Сергей Бобылев/ТАСС

— Желания свалить не возникло?

— Нет. Хотя в Америке настойчиво предлагали остаться, давали вид на жительство. Но я не стал оформлять грин-карту, поскольку почему-то считал, что должен прожить свой век с одним паспортом. Особенно после того, как меня предупредили: перед каждым выездом из США я должен буду приходить и сообщать, куда и зачем направляюсь, а мне выдадут рекомендации, можно ли туда ехать. Я ответил, что не для того много-много лет прожил в одной системе, чтобы угодить в другую, которая тоже будет ограничивать мою свободу. Нет, спасибо!

Хотя и потом, когда я вернулся с семьей в Россию, к нам в Зеленоград приезжал консул посольства США, беседовал с моей женой и сетовал, что наш сын Саша наверняка скучает по американским игровым площадкам…

Такая вот была забавная история.

‘ Максим Чурусов/ТАСС’

— Мы постепенно приближаемся к следующему этапу вашей биографии, когда из инноватора вы стали инвестором.

Знаете, пока занимаешься инновациями, тебе кажется, что все инвесторы — идиоты. По крайней мере, большинство. Смотришь на них и думаешь: какие-то неправильные люди, мыслят странно. Ты хочешь изменить мир, а они говорят лишь про приоритет денежных потоков, не видят великих идей, не способны оценить масштаб замысла

Иногда это слишком бросалось в глаза и дико раздражало. А потом случилась история, когда инвесторы, по сути, заблокировали выгодную сделку, на которой мы могли заработать гораздо больше. Помню, я сильно разочаровался из-за того, как все обернулось. Компанию TrustWorks Systems продали, мне в ней оставаться не хотелось. Стал думать, что делать дальше. У меня появилась любопытная идея, я попробовал стать «правильным» инвестором: нанял людей, дал им денег, и они начали работать над реализацией.

— О чем речь?

— Об управлении расходами от использования корпоративных телефонов. В то время в Европе была проблема с роумингом, и люди, выезжая из одной страны Евросоюза в другую, тратили на мобильную связь колоссальные деньги. Как-то ко мне пришел приятель-голландец и сказал: «Мой босс требует отчета, куда и зачем звоню с корпоративного номера. А я встречаюсь с его дочкой и не хочу, чтобы шеф узнал об этом раньше времени». Я предложил: «Надо сделать софт, чтобы ты мог отмечать личные контакты и все затраты, связанные с ними, вычитались автоматически».

Мы сидели в ресторане за бутылкой вина и рассуждали. Так родилась эта история. Говорю: «Давай компанию запустим?» Я нашел людей, которые все закрутили. Самому мне не хотелось этим заниматься, я привык к более масштабным проектам.

Помню, в 2003 году поехал в Непал. Поразмышлять о жизни. Побродил по горам, потом спустился на равнину и… начал распихивать свои деньги в разные стартапы.

— Сколько их у вас тогда было?

— Компаний?

— Нет, денег.

— Достаточно, чтобы вложить их куда-то по принципу «десять процентов потерять не жалко».

Потом меня позвали сделать TechTour для зарубежных инвесторов в России. Это было раскрученное мероприятие в Европе, но здесь оно никогда не проходило. TechTour и стал для меня поворотным моментом. Приехал, увидел «Лабораторию Касперского», «Яндекс», SWsoft, который позже переименовали в Parallels, Acronis, SJlabs… Подумал: «Какие классные компании!»

Но никто из западников не стал вкладывать в них деньги.

— Почему?

— Сложно сказать. Может, не доверяли. Это, кажется, 2005-й, уже Беслан произошел…

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

© Сергей Бобылев/ТАСС

— Тем не менее в собранном вами в 2008 году первом фонде Almaz русских денег не было?

— Ноль. Инвесторы присутствовали исключительно западные. Сначала пришел Cisco. Во втором фонде уже появились какие-то ростки из России, частные вложения от предпринимателей.

— Вы говорили, что не очень любите иметь дело с отечественным бизнесом. Это правда?

— В целом, да. Во многом это связано с неумением наших людей правильно расставлять приоритеты.

У опытного инвестора образ мышления построен так, что он в первую очередь должен ущемить себя, но выполнить взятые обязательства. У нас же иногда рассуждают по-другому: лучше нарушим данное слово, но не умерим личные потребности

— Как это выглядит? Приходит человек и говорит: «Старик, извини, мне надо купить новую яхту»?

— Типа того. «Выручка не та пошла», «Жене надо слетать на Мальдивы»… Аргументы, которые нельзя воспринимать всерьез, но люди на них ссылаются.

— И что говорите в ответ?

— А что тут скажешь? Слава богу, пока ни разу не дошло до применения санкций, прописанных в соглашениях. К примеру, в качестве наказания можно лишить части прибыли. И так далее. Подобного не случалось, но постоянно играть на грани фола весьма сложно. Ведь покрывать эти истории я вынужден, как правило, из своего кармана. А потом еще неизвестно — внесет инвестор то, что должен, или нет. Есть риски.

‘ Максим Чурусов/ТАСС’

— Значит, не каждого пускаете в компанию?

— Разумеется. Нельзя доверять первому встречному. Лучше отказаться от денег, десять раз подумать и выбрать правильного партнера. Это отношения на многие годы. Зачем втягиваться в длинную историю с теми, в ком не уверен?

Стараюсь изначально быть аккуратным в выборе компаньонов. Да, у некоторых случались финансовые разрывы, но все исполняли свои обязательства. У меня ни к кому нет претензий. Наверное, повезло. Знаю много историй, когда венчурные фонды создавались на деньги LP — крупных частных инвесторов, которые потом уходили, и все получалось не слишком красиво. Повторяю, мне очень повезло с партнерами. Они отбирались селективно. Существенно помогают рекомендации моих институционных инвесторов типа Европейского банка реконструкции и развития, у них есть списки, они смотрят, что за люди хотят вступить в проект, и дают советы: этот подходит, а тот — нет. Но решаем мы сами, конечно.

С партнерами фонда Almaz Capital на острове Нантакет, 2016 год

© Личный архив Александра Галицкого

— А сотрудничество, к примеру, с находящимся под санкциями Вексельбергом накладывает на вас дополнительные риски?

— Из-за этого у нас не возникало никакого напряга. История простая. Есть четкие правила, которые надо соблюдать. Если событие уже наступило, деньги, взятые раньше, остаются в обороте, а новые брать нельзя. Допустим, я стартанул с фондом, в котором десять человек под санкциями. Ясно, что такое чудо работать в Америке или Европе не сможет, умрет в первый же день. В случае же, если санкции против инвестора ввели после создания фонда, мы попросту не можем распределять заработанные им доходы. Нужно их сложить, и они будут лежать веки вечные, пока не разрешат забрать. Но это уже не наша история.

— Ладно, а система цифровой маркировки товаров «Честный знак», в которой вы участвуете с Алишером Усмановым и Ростехом? Это, по сути, госзаказ, хотя вы всегда декларировали, что не работаете на государство.

— В проекте нет ни рубля из бюджета. Он делается на частные деньги. Общие затраты составляют около двухсот миллиардов — сто наших и столько же привлеченных. Я обсуждал проект с Европейским банком реконструкции и развития, с Международным валютным фондом, он всем нравится, поскольку может способствовать росту инноваций в России. А социально проект важен не только для нашего государства. Если бы не санкционные проблемы и — как следствие — сложности в сотрудничестве с другими странами, опыт можно было бы раскатать по миру — по той причине, что он очень востребован.

Это выгодно и бизнесу, и государству, и людям.

К примеру, возьмем острейшую проблему, связанную с питьевой водой. Как контролировать качество и выявить недобросовестного конкурента, если один производитель качает из артезианской скважины, второй разрабатывает природные источники, а третий вливает химию в воду из-под крана? Вкусовые качества вроде бы похожи, а эффект радикально разный.

Больная тема, согласитесь.

А почему, как вы думаете, идею с маркировкой сразу поддержали табачники? В Россию поступает масса контрафакта, его везут от ближайших географических соседей. QR-коды — барьер на пути «левака». Тем более что их можно автоматически печатать на сигаретных пачках. В то время как наклеивание акцизных марок требует снижения скорости работы конвейера на 30 процентов.

Эта же проблема касается медицины, где не менее важен и социальный аспект, и вопрос качества.

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

Сопротивление идет мощное. Понятно, что проект нравится далеко не всем, он грозит разрушить многие нелегальные логистические цепочки. Прослеживаемость товаров позволит контролировать процесс от начала до конца. И посредники, которые привыкли кормиться, что называется, по дороге, оказываются не у дел.

Я уже упоминал лекарства. Критически важно быть уверенным, что в аптеке вам продают именно то средство, название которого указано на упаковке.

Или взять продукты питания. Нельзя писать «Свежее молоко», если оно изготовлено из порошкового. Это разные статусы по цене, качеству, воздействию на здоровье покупателя. Коды позволят маркировать продукцию и отслеживать любой контрафакт.

— А подделать ваши QR-коды нельзя? Голь на выдумки хитра, что угодно замастырит…

— Теоретически в этой жизни все можно скопировать, вопрос в том, что злоумышленник в любом случае будет выявлен.

— Врагов много нажили?

— Не знаю. По крайней мере, по-прежнему обхожусь без охраны. Никогда не видел в этом смысла.

Наверное, проектом маркировки товаров мы перешли кому-то дорожку, отгоняем от кормушек, но порядок ведь наводить надо.

Считаю, что производство медикаментов, детского питания, безалкогольных напитков точно нуждается в системе тотального отслеживания. Что же касается сопротивления, мне не привыкать. Нечто подобное мы проходили, когда запускали кассовую реформу, давшую громадную пользу государству. И тогда страшно давили, а сегодня на этом практически живет статистика страны. Даже в период пандемии.

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

— Но где государство, там часто коррупция.

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

Маркировка товаров — шанс для построения стартапов. Скажем, почему не создать «умную» аптечку, где будет собрана информация о том, что за лекарства у человека есть дома, как их правильно принимать, когда истекает срок годности? Все сведения — на основании сканированных кодов. Это удобнее, чем читать напечатанную маленькими буквами инструкцию

Повторяю, для инноваций нужен правильный мотиватор. Убежден, что при запуске государственно-частного партнерства, когда решается социально важная задача, обязательно появится что-то новое.

Это раньше бюджетные средства вкладывались в технологии для решения госзадач — та же оборонка служила драйвером развития. Сейчас другая история.

‘ Максим Чурусов/ТАСС’

— Правильно понимаю, что маркировка — один из ваших приоритетных проектов?

— Мой пробный шар: смогу ли что-то делать в России. Знаю, что многое мне сегодня запрещено. Хочу найти то, что разрешено.

— И чего вам здесь нельзя?

— Уже говорил: устав фонда Almaz Capital не позволяет инвестировать в Российскую Федерацию.

— Almaz Capital зарегистрирован в Штатах?

— Нет, наш третий фонд, например, прописан в Люксембурге. Европейские инвесторы попросили уйти туда с Кайманов. Типичная история для транснациональных фондов.

— Отношение к русским сильно изменилось в последние годы?

— Безусловно. После Крыма.

© Сергей Бобылев/ТАСС

И не только к деньгам или инвесторам.

Есть ограничение даже на использование специалистов из России. Новая волна! Официально нигде не записано, никто прямо не скажет, что нельзя брать, но негласно привлечение российских разработчиков не приветствуется. Поэтому многие отечественные компании, вышедшие на международные рынки, стараются скрыть происхождение

Таковы реалии. Но внешние обстоятельства — одно, а желание сделать что-то полезное для России — другое. История ЦРПТ, Центра развития перспективных технологий, занимающегося системой цифровой маркировки, — лакмусовая бумажка для меня. Когда делались онлайн-кассы, я не скрывал, что моя цель — создание объектов для инвестирования Almaz. А в проекте с маркировкой хочу увидеть, какие рождаются плоды. Да, какое-то сопротивление еще будет. Как и крики про ограбление страны, но, думаю, уже не только государство, но и бизнес, и потребители видят выгоду.

Часть 3

О мотивации, фишинге, жульничестве, бизнес-предприимчивости, многоженстве и Гюльчатай

— Но вы ведь не из благотворительности занялись маркировкой. Сколько рассчитываете зарабатывать с каждого кода?

— 50 копеек. Уверяю вас, деньги в данном случае — не самое главное. Для меня это попытка запустить инновации. Неплохо, если сможем отбить вложенное. Нас на каждом шагу пытаются остановить: мол, давайте исключим молоко, лекарства, минеральную воду… История на грани. Пока мы сидим в убытках, в сильном минусе.

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

— Почему?

— На мой взгляд, это не сохранение капитала, а банальные понты. Сначала люди стремятся купить, а потом многие обладатели дорогих игрушек думают, как бы избавиться от обузы? Уже объяснял вам: я рано познакомился с американскими миллиардерами, они рассказали мне правду про богатство. Не в нем счастье.

Посмотрите на мировую элиту айтишного бизнеса. Наша пресса любит сочинять истории об их домах на Гавайях и прочей роскоши… Но я вижу иное. В подавляющем большинстве это аскетичные люди, совершенно спокойно относящиеся к материальным ценностям. Зачем покупать яхту, если сможешь пользоваться ею раз в году?

— Как считаете, наши толстосумы наедятся когда-нибудь?

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

— А ваша личная мотивация в чем?

— Мне интересно увидеть Россию инновационной. Хочу, чтобы российский капитал начал работать в стране, а не только за ее пределами. Поэтому пытаюсь продвигать простую, на первый взгляд, идею — инвестиции в обмен на рынок или рынок в обмен на инвестиции. Как кому больше нравится.

Если гарантирован спрос и понятен объем рынка, можно рисковать и частнику, и государству. Главное — закрепить обязательства сторон в так называемом ГЧП, государственно-частном партнерстве.

А проекты могут быть разными: и «умная» дорога (перевозка груза из Китая в Европу за 12 дней по цене морской доставки), и «умный» дом (скажем, все строящееся жилье не сдавать без интеллектуальной системы ЖКХ). И так далее. Главное, что подобные проекты реальны, за ними стоят живые люди, они дадут спрос на новые инновационные решения в области интернета, программного обеспечения, радиоэлектроники.

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

И еще. Например, если мы умеем делать конкурентные солнечные батареи, давайте поставим перед собой задачу, что пять-десять процентов всех сдаваемых объектов строительства будут покрыты такими панелями

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

Деньги же — некий индикатор, показатель успешности проекта. Хотя никогда не стремился попасть в список Forbes, это точно не являлось для меня целью.

— Все так отвечают.

— Рассказал вам биографию: в советское время я круто взлетел вверх и к 90-м годам поднялся очень высоко. Вы вот про личный самолет спрашивали. У нас в ЭЛАСе было три борта, и практически в любое время я мог заказать их для своего полета или как главный конструктор предоставить министру либо иной структуре.

А потом наступила новая жизнь, все регалии и привилегии мигом исчезли. Качели: то, значит, вершина, то — подножье. Я прошел несколько таких периодов.

В нулевые, например, потерял значительное количество денег, отдав их в доверительное управление. Был слишком занят своим бизнесом. Даже в прошлом году у меня почти увели большую сумму.

— Каким образом?

— Банальным, к сожалению. Лихо раскрутили нас с моим хорошим другом и партнером, известным айти-предпринимателем.

Я перечислил ему заем, и деньги оказались на чужом счету в Гонконге.

— Такое возможно?

— Элементарно! По заявлениям гонконгской полиции, подобное происходит пять-шесть раз в неделю. Работают международные преступные организации, которые профессионально занимаются фишингом. Выбирают человека и ведут его. Вот мы с вами сегодня наговорили много всякого. Прочитает кто-то наше интервью: ага, этот парень, возможно, из Forbes, у него есть фонд, активы, проекты… Надо бы прощупать.

И начинают мониторить. Меня наверняка долго пасли. Где-то произошел взлом, залезли в историю переписки с тем самым другом-айтишником. Думаю, все случилось в Китае, когда я на три часа оставил телефон без присмотра в номере отеля. Или товарища взломали, у него в компании всякие люди работают.

В разных софтах по-прежнему остается много дыр. Мы могли дать доступ к служебным почтовым ящикам своим секретарям, чтобы те вели их, отвечая на нудные письма. Есть такая специальная функция.

Сложно сказать, но факт остается фактом: кто-то вклинился в нашу переписку, незаметно подключился…

— В итоге вы перевели деньги со счета, а они уплыли не туда?

— Фантастическая история! Когда рассказал Тимуру Бекмамбетову, он ответил: это готовый сюжет для сценария голливудского фильма. Идеально ложится! И знакомый продюсер, с которым я встречался на Тайване, подтвердил слова Тимура. Только, говорит, надо добавить женскую линию, и успех гарантирован, народ будет смотреть.

© Сергей Бобылев/ТАСС

— В двух словах перескажите.

Не знаю, где и когда меня с приятелем посадили на крючок, но с определенного момента за нами пристально следили. Зарегистрировали и открыли специальные компании, создали доменные имена… Целая операция! Можно жить год и не знать, что вас выбрали в качестве жертвы и ждут, когда появится возможность забросить наживку, которая будет проглочена

Все люди, периодически сталкиваясь с проблемами, обращаются за помощью к партнерам или друзьям. Вот и в переписке с моим товарищем возникла эта тема. Фигурировала весьма крупная сумма.

— Порядок цифр?

— Не хочу уточнять. Миллионы долларов.

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

— А вы ничего не заметили?

— Говорю же: работали профи! Они не выключили наш диалог, а влились в него. Не всю переписку им удавалось контролировать, к тому же мы созванивались по телефону, какие-то нюансы проходили мимо аферистов, но по последующим действиям они четко понимали, о чем мы общались, и продолжали вести свою игру.

Уже говорил, что порой прошу кого-то из коллег составить вместо меня деловое письмо, которое потом сам отправляю. Люди, хорошо со мной знакомые, понимают: это писал не я. У любого человека существует авторский почерк, повторить его трудно, а вот этим жуликам подделать удалось. Не знаю, использовали они искусственный интеллект или нет, но потрудились хорошо. А дальше начали режиссировать за нас. Отключать, например, в какой-то момент почту, не доставлять одно письмо, менять его на другое…

Конечно, это высокое мастерство. Я же с человеком в постоянной переписке, а тут не почувствовал, как нас трамбуют по полной программе. Обоих. В итоге они даже прислали сертификаты для проверки компании, предоставили все затребованные документы, и… деньги ушли на другой счет.

В ключевой момент я летел в Сан-Франциско из Амстердама. В самолете работал Wi-Fi, можно было пользоваться телефоном. Сперва я пропустил звонок, потом попытался вернуть, но уже у товарища оказался занят номер. Пишу сообщение, мол, как дела, деньги к тебе ушли три дня назад. Получаю ответ: ты о чем, ничего не поступало. Ну, шок на взлетной полосе. Я начал судорожно звонить, стюардессы, естественно, забегали. Дескать, во время набора высоты надо выключить телефон. Словом, обстановка накалилась. Я летел и думал, что в 2019 году взрослых мужиков развели, как пацанов…

Приземлился в Сан-Франциско, меня встретил сын, мы поехали на ужин с коллегами. Приезжаем, а они уже в курсе. Мой партнер по несчастью, пока я летел, поднял всех на ноги. Удивительное совпадение, один из членов совета директоров компании моего товарища — бывший главный юрист Агентства национальной безопасности США. В 1997 году именно АНБ пыталось разобраться с VPN для Windows-среды, который мы разработали и лицензировали, а потом продали Sun Microsystems. Очень заметная, известная личность. Когда он узнал, что дело с переводом денег на левый счет касается и меня, он вспомнил старую историю и попытался помочь. Остановить транзакцию можно было только по неофициальным каналам, без судебного заключения арестовать счет нельзя.

Операцию заблокировали, потом уже пошли формальные процедуры, суд…

— Вернули деньги?

— До копейки. За вычетом юридических услуг.

— Мораль сей басни какова?

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

Хотя, если говорить откровенно, отношение к жизни я не поменял. Нельзя поголовно не доверять окружающим. Все случаи разные. В чем точно убедился, так в том, что деньги — зло человеческое.

© Сергей Бобылев/ТАСС

— Да?                                                                                      

— В определенном смысле. По крайней мере, я так воспринимаю.

Из-за денег люди идут на предательства, совершают поступки, после которых не знают, как выпутаться. Грустные истории…

— Выход?

— Прощать. Не вижу смысла таить зло, тем более сводить счеты. Если человек понял, что совершил подлость, уже хорошо. А тому, кто не в состоянии признать собственную вину, никак не помочь.

Зачем суетиться? С точки зрения вечности наша жизнь длится лишь мгновение…

‘ Максим Чурусов/ТАСС’

— Философский взгляд на жизнь помогает?

— Может, меня кинут еще десять раз. Как это узнаешь заранее? Понимаете, все относительно. Кто-то поведение коллег назовет жульничеством, а другой будет говорить о бизнес-предприимчивости. Нечестные люди есть везде, в разных видах деятельности. Они пользуются чужой неопытностью, доверчивостью. Такое случается сплошь и рядом. Помните, в фильме «Силиконовая долина» инженер пытается понравиться потенциальному работодателю, рассказывает свои задумки, а рядом сидят 30 специалистов и все аккуратно записывают, чтобы потом попробовать реализовать идеи. Как расценивать подобное? Как обман наивного?

Еще раз повторю: многое зависит от отношения к той или иной жизненной ситуации. Я вот, к примеру, фаталист по натуре. Много раз садился в самолет, у которого в воздухе выявлялись неисправности, но из-за этого не перестал летать. Или взять коронавирус. У меня есть партнеры, разводящие в недоумении руки в стороны: что ты везде ходишь, ездишь, рискуешь? С ума сошел?

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

Поэтому я за разумную достаточность. За риск в умеренных дозах.

— Как и положено венчурным инвесторам… Вы параллельно занимаетесь разными проектами, за что вас с коллегами зовут многоженцами. Кто сейчас в роли Гюльчатай в гареме Almaz Capital?

— «Любимых жен» много. В этом-то и проблема. Когда вкладываешься в ту или иную компанию, они все становятся для тебя классными, родными и близкими.

— Нельзя любить всех одинаково.

— Да, на разных этапах кто-то может требовать больше внимания. И совсем не факт, что самые лучшие. Они способны расти без дополнительной помощи, а выручать надо середняков и слабаков. Да, есть и те, кого не вытянуть, тут уже приходится выбирать, на что направлять усилия — спасать или заняться другими, которые могут подняться.

Меняются обстоятельства, рыночная конъюнктура, технологии устаревают. Сидишь, анализируешь…

— А из прежних проектов какой вам наиболее дорог?

— Ясно, что первая любовь — самая запоминающаяся…

На старте у нас был видеомессенджер Qik, который мы продали Skype. Единственное, о чем до сих пор сожалею, — рано выскочили. Пожадничали наши соинвесторы, захотели выйти в кеш. Надо было брать акции. Хотя бы на половину суммы. Через полгода компанию Skype продали Microsoft в шесть раз дороже

— Вы за сколько отдали?

— По цене стоимости акций на тот момент.

— А в абсолютных цифрах?

— У нас покупали за миллиард долларов, были готовы заплатить акциями, но мы взяли кеш да еще со скидкой. Так всегда бывает с наличными. А потом компания ушла за шесть миллиардов…

Такая вот история. Она могла выглядеть совершенно по-другому. Это запомнилось и многому меня научило. Например, как при помощи пары правильных звонков резко поменять цену.

С командой фонда Almaz Capital в Италии, 2019 год

© Личный архив Александра Галицкого

— За счет искусственного подогрева интереса к сделке?

— Конечно. Возникает конкуренция, и цена идет вверх. Стоит зашевелиться солидным игрокам, и все начинают нервничать, боясь упустить выгоду. В инвестициях психология тоже очень важна.

Это постоянный поединок, соревнование, кто кого. Убежден, что энергетический вампиризм существует, а внутренняя мотивация зашита в генах. Уже говорил, что мой отец начинал последний проект, когда ему стукнуло 80 лет с гаком. Не понимаю, как можно сидеть без дела. С ума сойду, если не буду занят чем-то серьезным. Опять же — я постоянно общаюсь с молодыми людьми, заряжаюсь от них. Не вижу себя со стороны, смотрю в их горящие глаза, проникаюсь их азартом, увлеченностью. Они строят планы на 20 лет вперед, и я невольно забываю о возрасте, включаюсь в процесс. Полезный опыт.

— С третьим фондом Almaz Capital вы еще на десяточку подписались.

— На самом деле осталось уже восемь лет, но все равно срок значительный, согласен. Да, я взял на себя определенные обязательства. Есть понятие key person, оно подразумевает, что в случае, если решу уйти, LP, основные партнеры, тоже могут сказать, что заканчивают на этом совместную историю с фондом. Они вольны и продолжить, но получают право выйти из Almaz Capital. Этого точно не хотелось бы, поскольку фонд — мое детище, и я рассчитываю еще не раз поднять бокал после совершения удачных сделок.

— Все-таки с шампанским?

— Мы же с вами в самом начале разговора выяснили: главное, чтобы повод был достойный, а с напитком разберемся…

Разница между верхним и нижним давлением: норма

Считается нормой, когда разница между верхним и нижним давлением равна 40. Но при некоторых патологиях эта разница может существенно меняться в большую сторону. Особенно часто это бывает у пожилых людей. Если разница превышает 65мм.рт.ст. – это уже критическое состояние, опасное для жизни.

Характеристика значений верхнего и нижнего давления

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

Артериальное давление – это показатель силы, с которой сердце прогоняет кровь по артериям. Это давление не во всех сосудах одинаковое. Чем ближе сосуд к сердцу, тем давление выше, и наоборот — на удаленных сосудах оно ниже.

Официальной медициной принято измерять средние показатели АД. И для этого была выбрана плечевая артерия, ее местоположение дает возможность делать правильные замеры, ввиду достаточного удаления от сердца. И замерять его на предплечье удобнее, пациенту не нужно полностью раздеваться. Измерять давление можно в любое время и, независимо, где пациент находится.

Верхнее давление определяет силу выброса крови сердечной мышцей. Нижние показатели определяют силу, с которой сосуды этому сопротивляются. Чем удары сердца чаще, тем выше показатели верхнего систолического давления. На эти значения также влияет состояние аорты.

На нижние показатели оказывает влияние эластичность сосудов и степень их проходимости.

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

Нормативные показатели

У каждого человека своя норма артериального давления. Принято считать, что систолическое давление должно быть 120мм.рт.ст., а диастолическое – 80. Но эти показатели могут немного меняться в зависимости от многих факторов. Например, от эмоционального состояния, питания, привычек, возраста, времени суток, нагрузок на организм.

Норма АД зависит от возраста

Для молодых людей характерно небольшое снижение показателей и может быть нормой 115/75. Для пожилых нормой считаются более высокие цифры. Обычно 140/90 для стариков не считается отклонением. Давление, при котором человек не испытывает дискомфорта, является нормальным и называется рабочим.

Если в молодом возрасте показатели выше 140/90, это уже считается превышением нормы и нужно принимать меры для борьбы с гипертонией.

Разница между верхним и нижним давлением должна составлять 40 единиц. Как только начинается отклонение в какую-нибудь сторону, надо искать, в чем причина. Если разрыв увеличивается, это говорит о том, что у сердца недостаточно сил, чтобы перекачивать кровь по сосудам. Значит надо заставить биться его чаще. При возникновении гипертонических симптомов человеку придется изменить свой образ жизни.

Причины отклонения от нормы

АД может подскочить или упасть по многим причинам. Их можно разделить на внешние и внутренние.

К внешним относятся физические нагрузки на организм, время суток, прием лекарственных средств, злоупотребление курением, спиртными напитками, кофе, эмоциональные нагрузки, неправильное питание.

К внутренним относят патологические процессы в организме, которые могут вызвать скачок давления в ту или иную сторону. К ним относятся:

  1. Атеросклероз. Засорение сосудов склеротическими бляшками делает их жесткими, плохо растяжимыми.
  2. Гипотиреоз. При этом заболевании также страдают сосуды, происходит их быстрое старение, что нарушает их эластичность.
  3. Сахарный диабет. Может возникнуть спазм сосудов, из-за чего нарушится нормальный кровоток.
  4. Спазмы сосудов в результате стрессов и превышения в крови гормона кортизола, вырабатываемого при выраженных эмоциях.
  5. Нарушение работы почек, в результате чего в организме накапливается лишняя соль натрия, что также ведет к спазмам сосудов.
  6. Кровотечения, внутренние или наружные. Они приводят к резкому снижению артериальных показателей давления.
  7. Климакс, беременность. При этих состояниях происходит гормональная перестройка в организме женщины.

Сахарный диабет — одна из возможных причин отклонения от нормы

Разница верхнего и нижнего давления нарушается в том случае, когда сердце и кровеносная система теряют способность нормально выполнять свои функции.

Большая разница между показателями

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

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

Маленькая разница между показателями

Если разрыв составляет менее 30мм, это повод бить тревогу. При этом может подниматься нижнее давление, а верхнее либо стоит на месте, либо немного снижается.

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

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

Симптомы проявления отклонений

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

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

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

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

При разрыве между показателями ниже нормы наблюдаются слабость, сонливость, вспышки агрессии, истерика, нарушения памяти. Иногда могут произойти нарушения сердцебиения, но в целом человек особого дискомфорта не чувствует.

Возможные последствия

Разница верхнего и нижнего давления не должна превышать 50мм и быть ниже 30мм. Если она выше или ниже этих меток, могут быть такие последствия:

  • Возникновение инсульта с кровоизлиянием в мозг или закупоркой сосуда.
  • Инфаркт миокарда с разрывом аорты или закупоркой артерии.
  • Атеросклероз сердечнососудистой системы.
  • Сердечная недостаточность с остановкой сердца.
  • Гипертонический криз.

Когда разница между верхним и нижним давлением не в норме возможен инсульт

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

Методы терапии

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

Медикаментозные

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

Поэтому нужно лечить имеющиеся патологии. Если они уйдут, АД само нормализуется.

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

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

Народные способы

Важно с раннего возраста заботиться о своем здоровье. В старости в организме происходят необратимые изменения, поэтому нормализовать давление уже невозможно.

[wpmfc_cab_si]Народные методы можно применять только тогда, когда отклонения от нормы незначительные, и больному ничто не угрожает.[/wpmfc_cab_si]

Обязательно нужно советоваться с врачом, потому что только он может выявить причину заболевания. А народные методы в основном направлены на его устранение.

Хорошо снижает АД клюква, облепиха, свекла. Из них делают сок и пьют ежедневно. Можно в комплексе или по очереди. Полезно пить кефир, по стакану в день. Помогают семечки арбуза, высушенные и перемолотые в порошок.

Профилактические меры

Чтобы избежать резких скачков давления, нужно вести здоровый образ жизни:

  1. Не злоупотреблять курением и алкоголем. Они засоряют организм и вредят сердцу и сосудам.
  2. Отказаться от чрезмерного употребления крепкого кофе. Достаточно одной чашки в день по утрам.
  3. Уделять особое внимание питанию. Не злоупотреблять острой, жирной и жареной пищей. Отдавать предпочтение овощам, фруктам и зелени. Ограничить продукты, вызывающие ожирение.
  4. Вести подвижный образ жизни, заниматься спортом и физкультурой.
  5. Регулярно проходить профилактические осмотры у врача, замерять АД.
  6. Избегать стрессовых ситуаций.
  7. Уделять внимание сну и отдыху. Он должен быть полноценным и комфортным.
  8. Не лечиться самостоятельно при любых заболеваниях. Некоторые препараты и травы действуют на АД.

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

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

Выражения стрелочных функций — JavaScript

Выражение функции стрелки — компактная альтернатива традиционному
функция
выражение, но ограничено и не может использоваться во всех ситуациях.

Отличия и ограничения:

Сравнение традиционных функций с функциями стрелок

Давайте разложим «традиционную анонимную функцию» на простейшую «стрелочную функцию», шаг за шагом:

Примечание: Каждый шаг на этом пути является допустимой «стрелочной функцией».

 
function (a) {
  вернуть + 100;
}




(а) => {
  вернуть + 100;
}


(а) => а + 100;


а => а + 100;
  

{фигурные скобки} и (круглые скобки) и «возврат» требуются в некоторых случаях.

Например, если у вас нескольких аргументов или нет
arguments
, вам нужно снова ввести круглые скобки вокруг аргументов:

 
function (a, b) {
  вернуть a + b + 100;
}


(а, б) => а + б + 100;


пусть a = 4;
пусть b = 2;
function () {
  вернуть a + b + 100;
}


пусть a = 4;
пусть b = 2;
() => а + Ь + 100;
  

Аналогично, если для тела требуется дополнительных строк обработки, вы
необходимо повторно ввести фигурные скобки ПЛЮС «возврат» (стрелочные функции не
волшебным образом угадайте, что или когда вы хотите «вернуть»):

 
function (a, b) {
  пусть патрон = 42;
  вернуть патрон a + b +;
}


(a, b) => {
  пусть патрон = 42;
  вернуть a + b + патрон;
}
  

И, наконец, для именованных функций мы обрабатываем стрелочные выражения как
переменные:

 
function bob (a) {
  вернуть + 100;
}


пусть bob = a => a + 100;
  

Базовый синтаксис

Один параметр.При использовании простого выражения возврат не требуется:

Для нескольких параметров требуются круглые скобки. С простым
возврат выражения не требуется:

  (param1, paramN) => выражение
  

Многострочные операторы требуют фигурных скобок и возвращают:

  param => {
  пусть a = 1;
  вернуть параметр +;
}
  

Для нескольких параметров требуются круглые скобки. Многострочные операторы
требуется подтяжка тела и возврат:

  (param1, paramN) => {
   пусть a = 1;
   вернуть + param1 + paramN;
}
  

Расширенный синтаксис

Чтобы вернуть объектное буквальное выражение, требуется
круглые скобки вокруг выражения:

Отдых
поддерживаются параметры:

  (а, б,...r) => выражение
  

По умолчанию
поддерживаются параметры:

  (a = 400, b = 20, c) => выражение
  

Деструктуризация
в пределах поддерживаемых параметров:

  ([a, b] = [10, 20]) => a + b;
({a, b} = {a: 10, b: 20}) => a + b;
  

Стрелочные функции, используемые как методы

Как указывалось ранее, выражения стрелочной функции лучше всего подходят для не-методов
функции. Посмотрим, что произойдет, когда мы попытаемся использовать их как методы:

  «использовать строгое»;

var obj = {
  я: 10,
  b: () => консоль.журнал (this.i, this),
  c: function () {
    console.log (this.i, this);
  }
}

obj.b ();
obj.c ();
  

Стрелочные функции не имеют собственных , это . Другой пример с участием
Object.defineProperty () :

  «использовать строгое»;

var obj = {
  а: 10
};

Object.defineProperty (obj, 'b', {
  получить: () => {
    console.log (this.a, typeof this.a, this);
    вернуть this.a + 10;
  }
});
  

позвонить, подать заявку и связать

В
звонок ,
применить
и привязать
методы НЕ подходят для стрелочных функций — как они были
спроектирован так, чтобы методы могли выполняться в разных областях — потому что Arrow
функции устанавливают «this» на основе области, в которой определена функция стрелки.
в.

Например
звонок ,
применить
и привязать
работать должным образом с традиционными функциями, потому что мы устанавливаем объем для каждой
из методов:

 



var obj = {
    число: 100
}


window.num = 2020;


var add = function (a, b, c) {
  вернуть this.num + a + b + c;
}


var result = add.call (obj, 1, 2, 3)
console.log (результат)


const arr = [1, 2, 3]
var result = add.apply (obj, arr)
console.log (результат)


var result = add.привязать (объект)
console.log (результат (1, 2, 3))
  

С функциями стрелок, поскольку наша функция добавления по существу создается на
Окно (глобальная) область, предполагается, что , это — это окно.

 




var obj = {
    число: 100
}


window.num = 2020;


var add = (a, b, c) => this.num + a + b + c;


console.log (add.call (obj, 1, 2, 3))


const arr = [1, 2, 3]
console.log (add.apply (obj, arr))


const bound = add.bind (объект)
консоль.журнал (граница (1, 2, 3))
  

Возможно, самое большое преимущество использования стрелочных функций — это методы уровня DOM.
(setTimeout, setInterval, addEventListener), которые обычно требовали какого-то закрытия,
вызовите, примените или привяжите, чтобы гарантировать, что функция выполняется в надлежащей области.

Традиционный пример:

  var obj = {
    количество: 10,
    doSomethingLater: function () {
        setTimeout (function () {
            this.count ++;
            консоль.журнал (this.count);
        }, 300);
    }
}

obj.doSomethingLater ();
  

Стрелка Пример:

  var obj = {
    количество: 10,
    doSomethingLater: function () {
        
        setTimeout (() => {
            
            
            
            
            this.count ++;
            console.log (this.count);
        }, 300);
    }
}

obj.doSomethingLater ();
  

Нет привязки

аргументов

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

  var arguments = [1, 2, 3];
var arr = () => arguments [0];

arr ();

function foo (n) {
  var f = () => arguments [0] + n;
  return f ();
}

foo (3);
  

В большинстве случаев, используя отдых
Параметры — хорошая альтернатива использованию объекта аргументов и .

  function foo (n) {
  var f = (... args) => args [0] + n;
  вернуть f (10);
}

foo (1);
  

Использование нового оператора

Стрелочные функции нельзя использовать в качестве конструкторов, и при их использовании с
новый .

  var Foo = () => {};
var foo = новый Foo ();
  

Использование прототипа

Свойство

Стрелочные функции не имеют свойства прототипа .

  var Foo = () => {};
console.log (Foo.prototype);
  

Использование

yield ключевое слово

В
выход
ключевое слово не может использоваться в теле стрелочной функции (кроме случаев, когда это разрешено внутри
функции, вложенные в него).Как следствие, стрелочные функции нельзя использовать как
генераторы.

Тело функции

Стрелочные функции могут иметь «краткое тело» или обычное «тело блока».

В кратком тексте указывается только выражение, которое становится неявным возвратом.
ценить. В теле блока необходимо использовать явный оператор return .

  var func = x => x * x;


var func = (x, y) => {return x + y; };

  

Возвращение литералов объекта

Имейте в виду, что возвращение объектных литералов с использованием краткого синтаксиса основного текста
params => {object: literal} не будет работать должным образом.

  var func = () => {foo: 1};


var func = () => {foo: function () {}};

  

Это связано с тем, что код в фигурных скобках ({}) анализируется как последовательность операторов (т. Е.
foo рассматривается как метка, а не как ключ в литерале объекта).

Вы должны заключить литерал объекта в круглые скобки:

  var func = () => ({foo: 1});
  

Разрывы строк

Стрелочная функция не может содержать разрыв строки между ее параметрами и стрелкой.

  var func = (a, b, c)
  => 1;

  

Однако это можно исправить, поместив разрыв строки после стрелки или используя
круглые скобки / фигурные скобки, как показано ниже, чтобы код оставался красивым и пушистым. Ты
также можно ставить разрывы строк между аргументами.

  var func = (a, b, c) =>
  1;

var func = (a, b, c) => (
  1
);

var func = (a, b, c) => {
  возврат 1
};

var func = (
  а,
  б,
  c
) => 1;


  

Порядок разбора

Хотя стрелка в стрелочной функции не является оператором, стрелочные функции имеют
специальные правила синтаксического анализа, которые по-разному взаимодействуют с оператором
приоритет по сравнению с обычными функциями.

  позвольте обратный звонок;

callback = обратный вызов || function () {};

callback = обратный вызов || () => {};


callback = обратный вызов || (() => {});
  

Базовое использование

 
let empty = () => {};

(() => 'фубар') ();



var simple = a => a> 15? 15: а;
простой (16);
простой (10);

пусть max = (a, b) => a> b? а: б;



var arr = [5, 6, 13, 0, 1, 18, 23];

var sum = arr.reduce ((a, b) => a + b);


var even = arr.filter (v => v% 2 == 0);


var double = arr.карта (v => v * 2);



Promise.then (a => {
  
}). then (b => {
  
});


setTimeout (() => {
  console.log («Я бываю раньше»);
  setTimeout (() => {
    
    console.log («Я буду позже»);
  }, 1);
}, 1);
  

Таблицы BCD загружаются только в браузере

Определения методов — JavaScript | MDN

Начиная с ECMAScript 2015, более короткий синтаксис для определений методов для объектов.
вводятся инициализаторы. Это сокращение для функции, назначенной методу
имя.

  const obj = {
  получить свойство () {},
  установить свойство (значение) {},
  свойство (параметры…) {},
  * генератор (параметры…) {},
  свойство async (параметры…) {},
  генератор async * (параметры…) {},

  
  получить [свойство] () {},
  установить [свойство] (значение) {},
  [свойство] (параметры…) {},
  * [генератор] (параметры…) {},
  async [свойство] (параметры…) {},
  async * [генератор] (параметры…) {},
};
  

Сокращенный синтаксис аналогичен введенному синтаксису методов получения и установки.
в ES5.

Имеется следующий код:

  const obj = {
  foo: function () {
    
  },
  bar: function () {
    
  }
}
  

Теперь вы можете сократить это до:

  const obj = {
  foo () {
    
  },
  бар() {
    
  }
}
  

Генераторные методы

Генератор
методы также могут быть определены с использованием сокращенного синтаксиса.

При этом:

  • Звездочка ( * ) в сокращенном синтаксисе должна быть перед .
    имя свойства генератора.(То есть * g () {} будет работать,
    но г * () {} не будет.)
  • Определения методов без генератора не могут содержать ключевое слово yield .
    Это означает, что наследие
    функции генератора также не будут работать и вызовут
    Ошибка синтаксиса . Всегда используйте yield вместе с
    звездочка ( * ).
 
const obj2 = {
  g: function * () {
    пусть index = 0
    while (true) {
      индекс доходности ++
    }
  }
};


const obj2 = {
  * грамм() {
    пусть index = 0
    while (true) {
      индекс доходности ++
    }
  }
};

const it = obj2.грамм()
console.log (it.next (). значение)
console.log (it.next (). значение)
  

Асинхронные методы

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

 
const obj3 = {
  f: async function () {
    жду обещание
  }
}


const obj3 = {
  async f () {
    жду обещание
  }
}
  

Методы асинхронного генератора

Генератор
методы также могут быть асинхронными.

  const obj4 = {
  f: асинхронная функция * () {
    выход 1
    выход 2
    выход 3
  }
};


const obj4 = {
  async * f () {
   выход 1
   выход 2
   выход 3
  }
}
  

Определения методов не поддаются построению

Методы не могут быть конструкторами! Они выдадут TypeError , если вы попытаетесь
создать их.

  const objA = {
  method () {}
}
новый метод objA.

const objB = {
  * грамм() {}
}
новый objB.g
  

Простой тестовый пример

  const obj = {
  а: 'фу',
  b () {вернуть this.a}
};
console.log (obj.b ())
  

Вычисляемые имена свойств

Сокращенный синтаксис также поддерживает вычисляемые имена свойств.

  const bar = {
  foo0: function () {return 0},
  foo1 () {return 1},
  ['foo' + 2] () {return 2}
}

консоль.журнал (bar.foo0 ())
console.log (bar.foo1 ())
console.log (bar.foo2 ())


function foo () {
  возврат 1
}

пусть name = 'foo'
console.log (окно [имя] ())
  

Таблицы BCD загружаются только в браузере

getter — JavaScript | MDN

Синтаксис get связывает свойство объекта с функцией
который будет вызываться при поиске этого свойства.

  {get prop () {...}}
{получить [выражение] () {...}}
  

Параметры

prop

Имя свойства, которое нужно привязать к данной функции.

выражение

Начиная с ECMAScript 2015, вы также можете использовать выражения для вычисляемого свойства.
имя для привязки к данной функции.

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

Невозможно одновременно привязать геттер к свойству и иметь это
свойство на самом деле хранит значение, хотя можно использовать геттер и
setter вместе для создания типа псевдо-свойства.

Обратите внимание на следующее при работе с синтаксисом get :

Определение получателя для новых объектов в инициализаторах объектов

Это создаст псевдо-свойство latest для объекта obj ,
который вернет последний элемент массива в журнале .

  const obj = {
  журнал: ['пример', 'тест'],
  получить последний () {
    если (this.log.length === 0) return undefined;
    вернуть this.log [this.log.length - 1];
  }
}
console.log (obj.latest);
  

Обратите внимание, что попытка присвоить значение последнему не изменит его.

Удаление получателя с помощью оператора

delete

Если вы хотите удалить геттер, вы можете просто удалить
Это:

Определение получателя для существующих объектов с помощью

defineProperty

Чтобы добавить геттер к существующему объекту позже в любое время, используйте
Объект.Определение свойств () .

  const o = {a: 0};

Object.defineProperty (o, 'b', {get: function () {return this.a + 1;}});

console.log (o.b)
  

Использование вычисленного имени свойства

  const expr = 'foo';

const obj = {
  получить [выражение] () {вернуть 'бар'; }
};

console.log (obj.foo);
  

Определение статических геттеров

  class MyConstants {
  static get foo () {
    return 'foo';
  }
}

console.log (MyConstants.foo);
MyConstants.foo = 'бар';
console.log (MyConstants.foo);
  

Умные / самоперезаписывающиеся / ленивые геттеры

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

Дополнительная методика оптимизации, позволяющая замедлить расчет объекта недвижимости или отложить его.
значение и кэшировать его для последующего доступа — это интеллектуальных (или «запомненных») геттеров .Значение вычисляется при первом вызове метода получения, а затем кэшируется, поэтому
последующие обращения возвращают кешированное значение без его пересчета. Это полезно в
следующие ситуации:

  • Если вычисление значения свойства является дорогостоящим (требует много ОЗУ или процессорного времени,
    порождает рабочие потоки, извлекает удаленный файл и т. д.).
  • Если значение сейчас не нужно. Он будет использован позже, а в некоторых случаях это не так.
    б / у вообще.
  • Если он используется, к нему будут обращаться несколько раз, и нет необходимости
    пересчитайте, что значение никогда не будет изменено или не должно пересчитываться.

Примечание. Это означает, что вам не следует писать ленивый метод получения для свойства, значение которого вы
ожидайте изменения, потому что, если получатель ленив, он не будет пересчитывать
ценить.

Обратите внимание, что геттеры не «ленивы» и не «запоминаются» по своей природе; вы должны реализовать это
техники, если вы желаете такого поведения.

В следующем примере объект имеет геттер как собственное свойство. При получении
свойство, свойство удаляется из объекта и добавляется повторно, но неявно как данные
собственности на этот раз.Наконец, возвращается значение.

  get notifier () {
  удалить this.notifier;
  return this.notifier = document.getElementById ('закладка-уведомление-привязка');
},
  

получить по сравнению с defineProperty

При использовании получить ключевое слово и Object.defineProperty () имеют
похожие результаты, между ними есть небольшая разница при использовании на
классы .

При использовании get свойство будет определено в прототипе экземпляра,
при использовании Object.defineProperty () свойство будет определено в
экземпляр, к которому он применяется.

  class Example {
  get hello () {
    вернуть "мир";
  }
}

const obj = новый пример ();
console.log (obj.hello);


console.log (Object.getOwnPropertyDescriptor (obj, 'привет'));


console.log (
  Object.getOwnPropertyDescriptor (
    Object.getPrototypeOf (obj), 'привет'
  )
);

  

Таблицы BCD загружаются только в браузере

Объект arguments — JavaScript

arguments — это объект типа Array , доступный внутри функций, который содержит значения аргументов, переданных этой функции.

Примечание: Если вы пишете код, совместимый с ES6, предпочтительнее использовать остальные параметры.

Примечание. «Подобно массиву» означает, что аргументов имеют свойство длины и свойства, проиндексированные с нуля, но у него нет встроенных методов Array , таких как forEach () или карта () . См. Подробности в §Описание.

Объект arguments — это локальная переменная, доступная во всех функциях без стрелок.Вы можете ссылаться на аргументы функции внутри этой функции, используя ее объект arguments . В нем есть записи для каждого аргумента, с которым была вызвана функция, с индексом первой записи 0 .

Например, если функции передано 3 аргумента, вы можете получить к ним доступ следующим образом:

  аргументы [0]
аргументы [1]
аргументы [2]
  

Каждый аргумент также можно установить или переназначить:

  аргументы [1] = 'новое значение';
  

Объект arguments не является массивом .Он аналогичен, но в нем отсутствуют все свойства Array , за исключением длины . Например, у него нет метода pop () .

Однако его можно преобразовать в реальный массив :

  var args = Array.prototype.slice.call (аргументы);

var args = [] .slice.call (аргументы);
  

Как и любой объект типа Array, вы можете использовать метод Array.from () из ES2015 или синтаксис распространения для преобразования аргументов в реальный массив:

  let args = Массив.от (аргументы);

let args = [... аргументы];
  

Объект arguments полезен для функций, вызываемых с большим количеством аргументов, чем они официально объявлены для принятия. Этот метод полезен для функций, которым можно передавать переменное количество аргументов, таких как Math.min () . В этом примере функция принимает любое количество строковых аргументов и возвращает самый длинный из них:

.

  function longestString () {
  var longest = '';
  for (var i = 0; i  longest.length) {
      самый длинный = аргументы [я];
    }
  }
  самый длинный возврат;
}
  

Вы можете использовать arguments.length , чтобы подсчитать, с каким количеством аргументов была вызвана функция. Если вместо этого вы хотите подсчитать, сколько параметров функция должна принимать, проверьте свойство length этой функции.

Использование typeof с аргументами

Оператор typeof возвращает «объект» при использовании с аргументами

  консоль.журнал (тип аргументов);
  

Тип отдельных аргументов можно определить путем индексации аргументов :

  console.log (тип аргументов [0]);
  

Определение функции, которая объединяет несколько строк

В этом примере определяется функция, которая объединяет несколько строк. Единственный формальный аргумент функции — это строка, содержащая символы, разделяющие элементы для объединения.

  функция myConcat (разделитель) {
  let args = Массив.prototype.slice.call (аргументы, 1);
  вернуть args.join (разделитель);
}
  

Вы можете передать этой функции столько аргументов, сколько захотите. Он возвращает список строк, используя каждый аргумент в списке:

 
myConcat (',', 'красный', 'оранжевый', 'синий');


myConcat (';', 'слон', 'жираф', 'лев', 'гепард');


myConcat ('.', 'шалфей', 'базилик', 'орегано', 'перец', 'петрушка');
  

Определение функции, которая создает списки HTML

В этом примере определяется функция, которая создает строку, содержащую HTML для списка.Единственным формальным аргументом функции является строка « u », если список должен быть неупорядоченным (маркированным), или « o », если список должен быть упорядоченным (нумерованным). Функция определяется следующим образом:

  список функций (тип) {
  var html = '<' + type + 'l> 
  • '; var args = Array.prototype.slice.call (аргументы, 1); html + = args.join ('
  • '); html + = '
  • '; return html; }

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

      позвольте listHTML = list ('u', 'One', 'Two', 'Three');
    
    
      

    Остальные, параметры по умолчанию и деструктурированные параметры

    Объект arguments можно использовать вместе с параметрами rest, default и деструктурированными.

      function foo (... args) {
      вернуть аргументы;
    }
    foo (1, 2, 3);
      

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

    В коде в строгом режиме объект arguments ведет себя одинаково независимо от того, передаются ли функции оставшиеся параметры, параметры по умолчанию или деструктурированные параметры. То есть присвоение новых значений переменным в теле функции не повлияет на объект arguments . Также присвоение новых переменных объекту arguments не повлияет на значение переменных.

    Примечание: Вы не можете написать "use strict"; в теле определения функции, которая принимает параметры покоя, значения по умолчанию или деструктурированные параметры.Это вызовет синтаксическую ошибку.

    Нестрогие функции, которым передаются только простые параметры (т. Е. Не оставшиеся, параметры по умолчанию или реструктурированные параметры), будут синхронизировать значения переменных, новые значения в теле функции, с объектом arguments , и наоборот:

      function func (a) {
      аргументы [0] = 99;
      console.log (а);
    }
    func (10);
      

    А также:

      function func (a) {
      а = 99;
      console.log (аргументы [0]);
    }
    func (10);
      

    И наоборот, нестрогие функции, которые являются переданными остальными, параметрами по умолчанию или деструктурированными параметрами , не будут синхронизировать новые значения, присвоенные переменным аргумента в теле функции, с объектом аргументов .Вместо этого объект arguments в нестрогих функциях со сложными параметрами всегда будет отражать значения, переданные в функцию, когда функция была вызвана (это то же поведение, которое демонстрируют все функции строгого режима, независимо от типа переданных переменных):

      function func (a = 55) {
      аргументы [0] = 99;
      console.log (а);
    }
    func (10);
      

    А также:

      function func (a = 55) {
      а = 99;
      консоль.журнал (аргументы [0]);
    }
    func (10);
      

    А также:

     
    function func (a = 55) {
      console.log (аргументы [0]);
    }
    func ();
      

    Таблицы BCD загружаются только в браузере

    Три способа определения функций в JavaScript | Автор: Ашутош К. Сингх

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

    Функция генератора может быть остановлена ​​в середине выполнения.Когда он вызывается, он продолжает работу с того места, где он остановился.

    Он объявлен как обычная функция, но с той разницей, что функция генератора имеет звездочку * после ключевого слова function и любое количество пробелов может быть включено между ними.

    Еще одно замечание: в JavaScript генератор — это функция, которая возвращает объект, для которого вы можете вызвать next () . Каждый вызов next () будет возвращать объект со структурой, подобной этой:

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

    Давайте лучше поймем это на простом примере:

    Внутри тела функции мы не используем ключевое слово return — вместо этого используется yeild , если использовалось return , это изменило бы свойство done до истина , и функция завершится — все, что после нее, не будет выполнено. Yield выдает присвоенное ему значение.

    Сначала мы определяем нашу функцию, затем вызываем ее, вызов функции генератора приводит к созданию объекта генератора, который сохраняется в переменной gen.

    Затем мы вызываем объект, используя next () и value property,

    При первом использовании next () начинается выполнение функции. Сначала он запускает console.log («Выполняется первым») и записывает его в консоль, а затем встречает yield — дает значение «взять паузу» и выполнение останавливается.

    При втором вызове next () он выбирает то место, где он ушел в прошлый раз. Опять же, он сначала запускает console.log () , а затем обнаруживает yield и возвращается значение «конец функции», затем функция останавливается.

    При третьем вызове next () результат будет undefined. Это происходит потому, что объект, сгенерированный функцией генератора, может быть повторен только один раз — объект теперь бесполезен, и для повторного запуска программы необходимо сгенерировать новый объект.

    Если бы я использовал return вместо yield , значение данных изменится на true , и после этого ничего не будет выполнено.

    Генераторы в сочетании с обещаниями представляют собой очень мощный инструмент для асинхронного программирования. Они смягчают, если не полностью устраняют проблемы с обратными вызовами.

    Как функция JavaScript определяет тип и создает экземпляры объектов?

    Недавно я получил вопрос от кого-то, кто проходил мой электронный курс «Освоение JavaScript» по электронной почте, касательно третьего дня курса, где я кратко рассказываю о функциях конструктора и ключевом слове «новое».

    В этом курсе я говорю:

    Значение «this» внутри функции-конструктора — это новый экземпляр этого типа объекта, где «тип» определяется самой функцией-конструктором.

    Вопрос читателя касался определений типов и функций:

    Как функция-конструктор определяет тип? Разве это не просто функция? Что квалифицирует функцию как функцию-конструктор, кроме шаблона вызова «новый»?

    Это вопрос, который сбивает с толку многих разработчиков, в том числе и меня.Но, честно говоря, это все. Любая допустимая функция JavaScript может быть функцией-конструктором, просто добавив перед ней ключевое слово «new».

    Но это не значит, что каждая функция предназначена для работы именно таким образом.

    Построение объекта из функции

    Каждая функция, которую вы определяете в JavaScript, потенциально может быть функцией-конструктором. Вы можете убедиться в этом, посмотрев на атрибут «.prototype» любой функции, которую вы определяете (например, в Chrome DevTools.

    Атрибут .prototype функции используется в качестве прототипа экземпляра объекта, когда вы вызываете функцию с ключевым словом «new».

    Также говорят, что объект является экземпляром имени этой функции… «типа», который был определен с функцией.

    Объект «s» в этих примерах явно является экземпляром «чего-то» с прототипом, определенным этой функцией.

    Но как это происходит?

    Магия «Нового»

    За кулисами, когда вы вызываете функцию с ключевым словом «new», среда выполнения JavaScript в основном делает следующее:

    1. Создать новый экземпляр объекта
    2. Назначьте свой прототип функции.прототип
    3. Примените функцию с экземпляром объекта, установленным как «этот»

    Конечно, это очень упрощенное представление того, что происходит, но это суть процесса.

    Поскольку каждая функция, которую вы определяете, имеет .prototype, и из-за того, как ведет себя ключевое слово «new», можно использовать практически любую функцию в качестве функции-конструктора для создания новых экземпляров этого «типа».

    Но то, что вы можете, не означает, что вы должны это делать.

    Не все функции созданы равными

    Большинство функций — это просто функции, которые выполняют некоторую работу и, возможно, возвращают какое-то значение.

    Вы можете использовать ключевое слово «new» перед любой случайной функцией, если хотите, но результаты не были бы предсказуемыми, если бы она не была задумана как функция-конструктор.

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

    Если вы вызовете это как простую функцию, она вернет строку, как и следовало ожидать.

    Но что будет, если вы вызовете его как конструктор?

    В этом случае функция больше не работает должным образом — требуемая строка не будет возвращена.

    Тем не менее, в другом примере возвращаемое значение нормальной функции по-прежнему будет возвращаться, как ожидалось:

    В этом случае и вызов стандартной функции, и вызов функции конструктора возвращают одно и то же значение.

    Когда у вас есть функция-конструктор, есть неявное возвращаемое значение — новый экземпляр объекта.Однако вам разрешено переопределить это возвращаемое значение вашим собственным экземпляром объекта — как показано во втором примере.

    Что вам не разрешено, так это переопределить возвращаемое значение объекта примитивным значением, таким как строка. Среда выполнения Javascript проигнорирует примитивное возвращаемое значение и вместо этого отправит обратно экземпляр объекта.

    Но не волнуйтесь. Становится хуже! И это действительно становится лучше — особенно с переходом на ES6 и выше.

    Методы объектов как конструкторы

    В объектно-ориентированном JavaScript объект обычно имеет методы.В этих методах часто используется ключевое слово «this».

    Итак, что происходит, когда у вас есть объект с методом, подобный приведенному ниже, и вы применяете к нему ключевое слово «new»?

    Результат не очень красивый:

    Использование этой функции в качестве конструктора явно сломало ситуацию.

    Значение this, когда функция используется в качестве конструктора, не является значением this, ожидаемым функцией. Он был разработан для использования самого объекта как «этого», но это ожидание не оправдалось.Код все равно пытался запуститься, и в результате происходили очень плохие вещи.

    Но это не всегда так. Бывают случаи, когда у вас будет объект с методом, и он предназначен для использования в качестве функции-конструктора. Например:

    В этом случае «Компания» действует как пространство имен, а не как стандартный объект. В пространстве имен компании определен тип «Отдел». Этот метод отдела предназначен для использования в качестве функции-конструктора.

    Итак, в чем разница между этими двумя примерами? Как кто-то узнает, что метод является или не должен быть функцией-конструктором?

    Идиоматические функции конструктора

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

    Например:

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

    вряд ли будет функцией-конструктором.

    Соглашение об именах следует стандарту для функции, которая просто возвращает значение. Он не пишется с заглавной буквы, и в нем есть слово «получить» — слово, которое обычно означает, что функция вернет какое-то значение.

    Однако в названиях функций, написанных с заглавной буквы, нет ничего особенного, кроме общепринятого стандарта, по которому работает большинство разработчиков JavaScript. Это, по определению, идиоматический JavaScript.

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

    Классы ES6 и определения типов

    В ES6 (официально ES2015) JavaScript попытался уточнить определения типов, введя синтаксис «класс».Если вы когда-либо работали с классами на C #, Java или других языках синтаксиса C, этот синтаксис должен показаться вам довольно знакомым.

    В этом примере определяется простой класс «Bar» и добавляется метод «doStuff». Создается экземпляр объекта, и метод doStuff выполняется должным образом.

    Что вы можете не осознавать, используя этот синтаксис, так это то, что это в основном просто синтаксический сахар поверх существующих функций конструктора JavaScript.

    Да, есть некоторые реальные различия в синтаксисе класса и синтаксисе функции конструктора, но как только класс определен, он фактически является функцией конструктора (как показано в Node v4 +):

    Как видно из этих выходных данных, класс Bar действительно создает функцию конструктора.Однако это не «нормальная» функция, поскольку ее нельзя вызвать без «нового»

    .

    Это одно из многих отличий от классов ES6.

    Поведение классов ES6 может несколько отличаться, но, в конце концов, это все еще функция-конструктор с .prototype, которая определяет тип JavaScript во время выполнения.

    Функции и определения типов

    Возможность использовать практически любую функцию в качестве конструктора с помощью ключевого слова «new» означает, что вы можете попасть в неприятные ситуации, если не будете осторожны.Тот факт, что вы можете использовать любую функцию в качестве конструктора, не означает, что вы должны это делать. Должны существовать идиомы и хороший документ, чтобы помочь нам определить, какие функции следует использовать таким образом.

    Синтаксис ES6 для определений классов пытается вывести JavaScript из этой опасной зоны, но все же основывается на исходных концепциях функций конструкторов. И создание дополнительных возможностей, тем не менее, вполне возможно создавать экземпляры объектов с прототипами, не используя функции конструктора. В конце концов, это прототипное наследование — даже с классами ES6.

    Хотите узнать больше о типах и прототипах?

    Если вам интересно узнать больше о типе и прототипе JavaScript, посмотрите скринкасты WatchMeCode, охватывающие как основы JavaScript.

    Из серии «Основы JavaScript» вы узнаете все, что вам нужно знать об объектах, функциях, прототипах и многом другом. От простых определений объектов до композиции объектов, от прототипного наследования до функций-конструкторов — эпизод «Объекты и прототипы JavaScript» охватывает все, что вам нужно.Затем, с дополнительными эпизодами, охватывающими переменную область видимости, страшное ключевое слово «this» и многое другое, вы быстро начнете овладевать JavaScript!

    Изучите больше JavaScript за считанные минуты, чем за годы, с помощью скринкастов WatchMeCode.

    Декораторы в JavaScript

    В этой статье мы обсудим декораторы в JavaScript и их варианты использования. Мы также познакомимся со всеми концепциями, связанными с декораторами, на практических примерах.

    Что такое декоратор?

    Декораторы — это просто оболочка для функции . Они используются для расширения функциональных возможностей функции без изменения базовой функции . Декораторы — это не новая концепция — они уже используются разработчиками Python и C #, и даже разработчики JavaScript внедряют их с незапамятных времен. Какие? Да, вы не ослышались.

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

    Функции в JavaScript

    Функции в JavaScript — это первоклассные объекты, то есть они ведут себя так же, как объекты. Мы можем присвоить их переменным, передать их как параметры другим функциям. Их также может вернуть другая функция. Давайте рассмотрим несколько примеров, чтобы понять все эти концепции.

    Функции, назначенные переменной

     
    var helloWorldFunc = function () {
    консоль.log ("Привет, мир")
    }
    
    
    
    var anotherVar = helloWorldFunc
    
    
    helloWorldFunc ()
    anotherVar ()
      

    Здесь helloWorldFunc указывает на определение функции, которая выводит Hello, world . Когда helloWorldFunc назначается anotherVar , обе переменные начинают указывать на одно и то же определение функции. Следовательно, когда вызываются обе функции, они выводят один и тот же результат — Hello, world .

    Функции, переданные как параметр другой функции

     
    var printHello = function () {
    консоль.log ("Я - функция printHello")
    }
    
    
    
    function printHelloAndHi (func) {
    func ()
    console.log ("Я - функция printHelloAndHi")
    }
    
    
    printHelloAndHi (printHello)
    
      

    Здесь мы передали функцию printHello в качестве параметра функции printHelloAndHi , поэтому функция printHelllo назначается переменной func . printHelloAndHi функция вызывает func (то есть printHello функцию) внутри своего определения.

    Функция, возвращенная другой функцией

      function printAdditionFunc (x, y) {
    var addNumbers = function () {
    результат = х + у;
    console.log («Сложение« + x + »и« + y + »:« + результат »);
    }
        
    
    вернуть addNumbers
    }
    
    
    вар addNumbersFunc = printAdditionFunc (3, 4)
    
    console.log (addNumbersFunc)
    
    addNumbersFunc ()
      

    Здесь функция printAdditionFunc принимает два параметра: x и y . Он возвращает определение функции addNumbers , которая назначается addNumbersFunc .Когда вызывается addNumbersFunc , он возвращает сложение 3 и 4 . Каким образом 3 и 4 , которые были переданы в printAdditionFunc , доступны внутри addNumbersFunc ? Это связано с закрытием в JavaScript . Замыкания позволяют дочерним функциям обращаться к переменным родительской функции, объектам и т. Д. Другими словами, дочерние функции хранят переменные родительской функции, так что дочерние функции могут использовать их при необходимости.

    В приведенной выше функции мы можем проверить, что addNumbersFunc хранит значения 3 и 4 . Как JavaScript хранит эти переменные, можно понять из этой статьи.

    Теперь, когда основы функций понятны, давайте разберемся с функциями высшего порядка.

    Функции высшего порядка в JavaScript

    Функции высшего порядка — это функции в JavaScript, которые принимают другую функцию в качестве параметра, добавляют к ним несколько операций и возвращают функцию.Функции printAdditionFunc и printAddition , упомянутые в приведенных выше примерах, являются функциями высшего порядка. Рассмотрим несколько примеров функций высшего порядка.

      функция printMessage (сообщение) {
    return function () {
    console.log (сообщение)
    }
    }
    
    
    var printHello = printMessage ("Привет")
    printHello ()
    
    
    var printHi = printMessage ("Привет")
    printHi ()
      

    Здесь printMessage — функция высшего порядка. Это похоже на фабричную функцию, которая возвращает новую функцию.

    Еще один более полезный пример

     
    
    function handleException (funcAsParameter) {
    console.log ("Внутренняя функция handleException")
    пытаться {
    funcAsParameter ()
    } catch (err) {
    console.log (ошибка)
    }
    }
    
    function DivideByZero () {
    результат = 5/0
    if (! Number.isFinite (результат)) {
    выкинуть "Деление на ноль не лучшая идея !!"
    }
    console.log ("Результат деления 5 на ноль:" + результат)
    }
    
    
    
    handleException (divByZero)
      

    Здесь handleException функция является функцией высшего порядка.Он может использоваться любой функцией для обработки исключения. С функцией handleException нам не нужно обрабатывать исключения для каждой функции отдельно, мы можем просто передать каждую функцию в функцию handleException , и они получат функциональность для обработки исключений из функции handleException . Когда мы передаем DivideByZero в качестве параметра функции handleException , исключение, вызванное DivideByZero , обрабатывается кодом функции handleException .

    Если вы внимательно посмотрите на определение функций и декораторов высшего порядка, вы обнаружите, что они похожи. Функции высшего порядка ведут себя так же, как декораторы. Как и функции высшего порядка, декораторы также добавляют некоторые функциональные возможности к существующей функции без изменения базового кода. В нашем случае handleException — это функция-декоратор.

    Тогда почему декораторы?

    Если у нас уже есть декоратор как функция высшего порядка, тогда зачем нам декораторы? Функции высшего порядка могут служить декораторами для функции JavaScript, но изобретение классов в JavaScript познакомило нас с методами классов, то есть функциями, определенными внутри класса , где функции высшего порядка не могли действовать как декораторы.Чтобы понять, почему метод класса нельзя использовать с функциями высшего порядка, давайте сначала разберемся: что такое классы в JavaScript.

    Классы в JavaScript

    Перед ключевым словом класса

    До того, как в ES2015 было введено ключевое слово class , если мы хотели создавать классы, то есть чертежи для объектов, в JavaScript мы использовали прототипы и функцию конструктора .

    Рассмотрим пример функции конструктора :

     
    function Human (firstName, lastName) {
    это.firstName = firstName
    this.lastName = lastName
    }
    
    
    Human.prototype.getFullName = function () {
    вернуть this.firstName + "" + this.lastName
    }
    
    var person1 = new Human ("Вират", "Кохли")
    var person2 = new Human ("Рохит", "Шарма")
    
    console.log (человек1)
      

    Функция Human — это функция-конструктор со свойствами firstName и lastName . С помощью этой функции Human мы можем создавать новые объекты. Эти объекты будут иметь firstName , lastName и getFullName в качестве своих свойств.

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

      Человеческий прототип
      

    Метод getFullName определен в свойстве прототипа функции Human . Каждый объект, созданный с помощью функции конструктора Human , будет иметь свою собственную копию firstName и lastName , т.е.е. person1 будет иметь значение firstName как Virat , а person2 будет иметь значение firstName как Rohit .

    Функция getFullName будет совместно использоваться всеми объектами, созданными с помощью функции конструктора, т.е. как person1 , так и person2 будут иметь одну и ту же копию getFullname . Если person1 изменяет getFullName , person2 также будет иметь это измененное значение getFullName .Это связано с тем, что свойства прототипа функции-конструктора являются общими для всех объектов.

    Мы могли бы также определить getFullName внутри функции конструктора Human , и это было бы прекрасно. Но тогда person1 и person2 будут иметь разные копии функции getFullname , которые будут избыточными. Без необходимости это заняло бы дополнительную память. Следовательно, функция getFullName определена в прототипе Human , так что все объекты, созданные с помощью функции конструктора Human , имеют одну и ту же копию функции getFullName .

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

    .

    Ключевое слово класса

    Классы в JavaScript, представленные в ES2015, не похожи на классы в Java, C # или Python. Это просто синтаксический сахар над поведением, основанным на прототипах. Синтаксический сахар означает, что JavaScript позволяет вам определять классы с помощью ключевого слова class , но под капотом он по-прежнему использует прототипы и функции конструктора, как обсуждалось выше, для создания объектов.

    Декларация класса

      class Human {
    constructor (firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
    }
    
    getFullName () {
    вернуть this.firstName + "" + this.lastName
    }
    }
    
    typeof (человек)
      

    В приведенном выше коде объявляется класс Human с функцией конструктора . Под капотом JavaScript преобразует этот класс в функцию конструктора Human . Все функции, определенные внутри класса, будут прикреплены к свойству прототипа функции-конструктора.

    В приведенном ниже коде показано преобразование классов в конструкторы и прототипы:

      function Human (firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
    }
    
    Human.prototype.getFullName = function () {
    вернуть this.firstName + "" + this.lastName
    }
      

    Это похоже на функцию-конструктор, которую мы обсуждали выше. Вот почему классы в JavaScript называются синтаксическими сахарами.

    На изображении выше мы видим, что тип Human является функцией.Кроме того, если мы сравним Human.prototype как класса Human , так и функции конструктора Human , они будут одинаковыми, за исключением того, что свойство конструктора класса Human имеет свойство конструктора со значением class Human , в то время как в случае функции конструктора это ƒ Human (firstName, lastName) , как показано ниже:

    Мы можем создавать объекты, используя класс с новым ключевым словом , как показано ниже.

      humanObj = новый человек («Вират», «Кохли»)
    console.log (humanObj)
      

    Давайте теперь поймем, почему функции высшего порядка не работают с методами класса.

    Проблемы с использованием функций высшего порядка с методами класса

     
    журнал функций (functionAsParameter) {
    return function () {
    console.log ("Выполнение" + functionAsParameter.name + "begin")
    
    functionAsParameter ()
    console.log ("Выполнение" + functionAsParameter.name + "end")
    }
    }
    
    class Human {
    constructor (firstName, lastName) {
    это.firstName = firstName
    this.lastName = lastName
    }
    
    getFullName () {
    вернуть this.firstName + "" + this.lastName
    }
    }
    
    var humanObj = новый человек ("Вират", "Кохли")
    
    
    var newGetFullNameFunc = журнал (humanObj.getFullName)
    newGetFullNameFunc ()
      

    Приведенный выше код объявляет функцию log как функцию высшего порядка, которая принимает другую функцию в качестве параметра. журнал Функция используется для ведения журнала. Мы создали объект humanObj . Давайте попробуем использовать функцию log с функцией getFullName .Функция newGetFullNameFunc — это модифицированная функция getFullName , способная вести журнал. Определение newGetFullNameFunc :

      var newGetFullNameFunc = function () {
    console.log ("Выполнение" + functionAsParameter.name + "begin")
    functionAsParameter ()
    console.log ("Выполнение" + functionAsParameter.name + "end")
    }
      

    Когда вызывается newGetFullNameFunc , внутренне он вызывает functionAsParameter , т.е.е. функция getFullName . Когда функция getFullName вызывается из newGetFullNameFunc , значение этого внутри getFullName равно undefined . Следовательно, код ломается. Чтобы исправить это, мы можем изменить нашу функцию log , как показано ниже:

      журнал функций (classObj, functionAsParameter) {
    return function () {
    console.log ("Выполнение" + functionAsParameter.name + "begin")
    functionAsParameter.вызов (classObj)
    console.log ("Выполнение" + functionAsParameter.name + "end")
    }
    }
    
    class Human2 {
    constructor (firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
    }
    
    getFullName () {
    вернуть this.firstName + "" + this.lastName
    }
    }
    
    var humanObj = new Human2 ("Вират", "Кохли")
    var newGetFullNameFunc = журнал (humanObj, humanObj.getFullName)
    newGetFullNameFunc ()
      

    В приведенном выше коде мы также передаем объект humanObj в качестве параметра функции log .Это сделано для того, чтобы сохранить значение , это . Внутри newGetFullNameFunc мы вызываем functionAsParameter (т.е. getFullName function) с помощью функции call . Функция call вызовет getFullName в объекте humanObj , то есть теперь значение этого внутри функции getFullName будет humanObj , которое имеет свойства firstName и lastName .Следовательно, этот код работает отлично.

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

    Дескрипторы свойств

    Каждое свойство объекта в JavaScript имеет дескрипторы свойств, которые используются для описания атрибутов или метаданных свойства.Дескрипторы свойств сами по себе являются объектами. Ниже приведены дескрипторы свойств, связанные с каждым свойством объекта:

    1. значение : Текущее значение свойства объекта.
    2. с возможностью записи : истинно или ложно . Значение по умолчанию — истинное . Указывает, доступно ли свойство для записи.
    3. перечислимый : истинный или ложный . Значение по умолчанию — истинное .Указывает, является ли свойство перечислимым или нет, т.е. появится ли оно в итерации object.keys .
    4. настраиваемый : истина или ложь . Значение по умолчанию — истинное . Указывает, можно ли изменять дескрипторы свойства свойства.

    Рассмотрим объект, показанный ниже:

      var humanObj = {
    'firstName': 'Вират',
    'lastName': 'Кохли',
    'getFullName': function () {
    верни это.firstName + "" + this.lastName;
    }
    }
      

    Здесь у нас есть объект humanObj . Каждое свойство ( firstName , lastName и getFullName ) будет иметь свои собственные дескрипторы свойств. Мы можем проверить значение дескриптора свойства с помощью getOwnPropertyDescriptor , как показано ниже:

      Object.getOwnPropertyDescriptor (humanObj, 'firstName')
    
      

    getOwnPropertyDescriptor перечисляет все дескрипторы свойств firstName .Точно так же lastName и getFullName будут иметь свои собственные дескрипторы свойств.

    object.defineProperty

    object.defineProperty может использоваться для определения новых свойств или обновления существующего свойства объекта. object.defineProperty принимает следующие параметры:

    1. объект : объект, для которого необходимо создать новое свойство или обновить существующее свойство.
    2. имя : Название собственности.
    3. дескриптор : объект дескриптора свойства.

    Давайте определим новое свойство с возрастом на humanObj .

      Object.defineProperty (humanObj, 'возраст', {значение: 10});
    Object.getOwnPropertyDescriptor (humanObj, 'возраст')
    
      

    Для свойства age , поскольку мы предоставили только дескриптор свойства value в качестве параметра для defineProperty , другие дескрипторы свойств будут иметь значения по умолчанию.Если свойство уже существует для объекта, Object.defineProperty перезапишет свойство новыми дескрипторами свойств, как показано ниже.

      Object.defineProperty (humanObj, 'firstName', {значение: "Rohit"});
    console.log (humanObj)
    
      

    Чтобы запретить пользователю изменять значение любого свойства объекта, мы можем сделать его доступным только для чтения, изменив с возможностью записи на false .

      Object.defineProperty (humanObj, 'firstName', {Writable: false});
      

    Теперь, если мы попытаемся изменить свойство, оно не изменится.

      humanObj.firstName = 'Вират'
    console.log (humanObj)
    
      

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

    Теперь, с пониманием всех вышеперечисленных концепций, наконец, разберемся с декораторами.

    Примечание : поскольку декораторы в настоящее время не являются частью JavaScript, приведенные ниже фрагменты кода не могут быть выполнены в браузере.Вы можете использовать JSFiddle для выполнения и понимания приведенных ниже фрагментов кода. В JSFiddle вы должны выбрать язык как Babel + JSX , как показано ниже:

    Декоратор метода класса

    Декораторы методов класса используются для изменения методов класса путем добавления дополнительных функций поверх метода. Он ведет себя как функции высшего порядка. Декораторы добавляются над определением метода с использованием @ , за которым следует имя функции декоратора.Вот синтаксис декоратора:

     
    функция decoratorFunc (цель, свойство, дескриптор) {}
    
    class DecoEx {
        
        @decoratorFunc
        getFullName () {}
    }
      

    Функция декоратора принимает три параметра, как показано выше:

    1. цель : класс метода, для которого определен декоратор.
    2. свойство : имя метода, для которого определен декоратор.
    3. дескриптор : дескрипторы свойств метода, для которого определен декоратор.

    Декоратор возвращает объект дескриптора свойства. Мы можем использовать свойство value дескриптора свойства, чтобы перезаписать определение базовой функции. Когда движок JavaScript встречает декоратор, он вызывает функцию декоратора, передавая базовую функцию в качестве параметра. Внутри функции-декоратора мы определяем новую функцию поверх базовой функции вместе с некоторыми новыми строками кода.

    Давайте разберемся в этом на примере.Рассмотрим код ниже:

     
    function readonlyDecorator (цель, свойство, дескриптор) {
        console.log ("Цель:")
        console.log (цель)
        
        console.log ("\ nНазвание свойства")
        console.log (свойство)
        
        console.log ("\ nСвойство дескриптора")
        console.log (дескриптор)
        
        
        descriptor.writable = false
        
        дескриптор возврата
    }
    
    class Human {
    constructor (firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
    }
    
    
    @readonlyDecorator
    getFullName () {
    верни это.firstName + "" + this.lastName
    }
    }
    
    humanObj = новый человек («Вират», «Коли»)
    
    console.log ("значение свойства \ ngetFullName")
    console.log (humanObj.getFullName)
    
    
    humanObj.getFullName = "Привет"
    
    
    console.log ("\ nПосле изменения значения getFullName")
    console.log (humanObj.getFullName)
      

    Найдите здесь код JSFiddle.

    Мы хотим, чтобы метод getFullName был доступен только для чтения. Следовательно, мы определили декоратор @readonlyDecorator поверх метода getFullName . @readonlyDecorator принимает в качестве параметров Human.prototype , getFullName имя метода, т.е. getFullName и дескриптор свойства getFullName .

    Здесь механизм JavaScript сначала вызовет функцию readonlyDecorator , а затем функцию getFullName . Когда вызывается readonlyDecorator , он изменяет функцию getFullName , используя свойство value дескриптора свойства , поэтому, когда JavaScript вызывает функцию getFullName , он вызывает измененную функцию getFullName .Давайте проверим шаги, предпринятые движком JavaScript для выполнения декораторов.

      funcDescriptor = Object.getOwnPropertyDescriptor (humanObj, 'getFullName')
    
    
    дескриптор = readonlyDecorator (Human.prototype, 'getFullName', funcDescriptor)
    
    
    
    Object.defineProperty (Human.prototype, 'getFullName', дескриптор);
      

    Вы можете прокомментировать код @readonlyDecorator в верхней части метода getFullName , а затем попытаться изменить метод getFullName .

    Теперь посмотрим, как определять декораторы с параметрами. Рассмотрим пример ниже:

      журнал функций (сообщение) {
      function actualLogDecorator (цель, свойство, дескриптор) {
        console.log ("свойство значения дескриптора \ ngetFullName")
        console.log (дескриптор.значение)
    
        var actualFunction = descriptor.value;
    
        var decoratorFunc = function () {
          console.log (сообщение)
          
          вернуть actualFunction.call (это)
        }
    
        
        
        descriptor.value = decoratorFunc
    
    консоль.log ("\ nНовое свойство значения дескриптора из-за декоратора")
        console.log (дескриптор.значение)
    
        
        дескриптор возврата
      }
    
      вернуть actualLogDecorator
    }
    
    class Human {
      constructor (firstName, lastName) {
        this.firstName = firstName
        this.lastName = lastName
      }
    
      @log ("Ведение журнала декоратором")
      getFullName () {
        вернуть this.firstName + "" + this.lastName
      }
    }
    
    humanObj = новый человек («Вират», «Коли»)
    
    console.log ("свойство значения дескриптора \ ngetFullName после модификации из-за декоратора")
    
    
    descriptorObject = Объект.getOwnPropertyDescriptor (Human.prototype, 'getFullName')
    console.log (descriptorObject.value)
    
    console.log ("\ nВыход для метода getFullName")
    console.log (humanObj.getFullName ())
      

    Найдите здесь код JSFiddle.

    шагов, за которыми следует JavaScript:

      var funcDescriptor = Object.getOwnPropertyDescriptor (humanObj, 'getFullName')
    
    
    var actualDecorator = log («Это делается с помощью декораторов»)
    
    дескриптор = фактическийДекоратор (Human.prototype, 'getFullName', funcDescriptor)
    Объект.defineProperty (Human.prototype, 'getFullName', дескриптор);
      

    Здесь JavaScript сначала вызывает метод log с параметром. log метод возвращает функцию actualLogDecorator . actualLogDecorator - это модифицированный метод getFullName с функцией ведения журнала, добавленной поверх функции getFullName .

    JavaScript обрабатывает actualLogDecorator как функцию декоратора, поэтому actualLogDecorator возвращает дескриптор, который имеет измененное определение функции getFullName .

    После этого шаги, за которыми следует JavaScript для выполнения getFullName с функцией декоратора, такие же, как описано в примере декоратора без параметра.

    Декораторы классов

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

      @decFunc
    class Foo {
    }
    
    
    
    function Foo (FooClass) {
    }
    
    
    NewFoo = decFunc (Foo) || Фу
    
    
    Foo = NewFoo
      

    Приведенный выше код объясняет этапы выполнения декоратора класса. У нас есть пустой класс Foo с функцией декоратора decFunc , определенный поверх класса Foo . decorFunc принимает класс (или функцию конструктора в ES2015) в качестве параметра, изменяет его и затем возвращает измененный класс (или функцию конструктора в ES2015), который назначается переменной NewFoo .Переменная NewFoo перезаписывает Foo , так что теперь Foo имеет измененную функциональность, то есть функциональность NewFoo . Рассмотрим другой пример:

      function newConstructor (HumanClass) {
    
    var newConstructorFunc = function (firstName, lastName, age) {
    this.firstName = firstName
    this.lastName = lastName
    this.age = возраст
    }
    
    вернуть newConstructorFunc
    }
    
    @newConstructor
    class Human {
    constructor (firstName, lastName) {
    это.firstName = firstName;
    this.lastName = lastName;
    }
    }
    
    
    
    var person1 = new Human («Вират», «Кохли», 31);
    console.log (person1);
    
    
    console.log (Human.prototype.constructor);
    console.log (person1 .__ proto __. constructor);
      

    Найдите здесь код JSFiddle.

    Здесь декоратор newConstructor определен в классе Human . Декоратор newConstructor возвращает функцию-конструктор с параметрами firstName , lastName и age .Возвращенная функция конструктора перезаписывает существующую функцию конструктора Human . Благодаря этому мы можем передать параметры Virat , Kohli и 31 функции конструктора Human .

    Вместо функции-конструктора мы могли бы также вернуть сам новый класс, как показано ниже. Это определение NewClass перезапишет определение функции конструктора класса Human .

      function newConstructor (HumanClass) {
    return class NewClass {
    конструктор (firstName, lastName, age) {
    это.firstName = firstName
    this.lastName = lastName
    this.age = возраст
    }
    }
    }
      

    Заключение

    В этой статье мы узнали следующие концепции, связанные с декораторами:

    1. Реализация декораторов в JavaScript с использованием функций высшего порядка
    2. Базовые классы в JavaScript
    3. Дескрипторы свойств в javaScript
    4. Декораторы методов класса и декораторы классов в JavaScript

    .

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *