Русский
Русский
English
Статистика
Реклама

Future

Пентестеры Ведьмаки мира ИТ

26.01.2021 14:17:08 | Автор: admin

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

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

Под катом я хотел бы сравнить и провести параллель ( пусть, быть может, местами, это может казаться утрированно) между ведьмаками и пентестерами ( ведьмаками из мира IT).

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

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

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

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

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

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

  2. Ищут за оставшуюся цену специалистов в иб.

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

  4. Эта цепочка движется вниз до тех пор, пока не дойдет до студентов, которые еще вчера "работали за еду" и им бы не помешала практика.

  5. В итоге цепочка движется обратно вверх, где каждый на звено выше дописывает что-то от себя.

  6. Как результат, в руки заказчику возвращается отчет низкого качества, в чем, собственно, они сами и виноваты.

Что касается добросовестных программистов-разработчиков, они на то и разработчики, чтобы именно разрабатывать продукты, а не защищать их.

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

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

Но некоторые этого до сих пор не понимают, всегда необходимы специализированные профессионалы своего дела, эксперты в области иб, "особый отряд" - пентестеры.

Теперь же поговорим о терминологии.

К пентестерам мы вернемся после описания Ведьмаков, которые тоже представляют собой "особый отряд".

Терминология

Кто такие ведьмаки?

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

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

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

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

Отслеживание монстров v.1Отслеживание монстров v.1

Главного харизматичного героя - Геральта из Ривии вы можете знать, как минимум по одной из лучших игр десятилетия - "Ведьмак 3 : Дикая Охота".

Геральт из РивииГеральт из Ривии

Пентестеры

Пентестеры - особый "отряд" людей, специально обученный и прошедший подготовку, чтобы стать профессиональными истребителями "чудовищ" - проблем (уязвимостей) в IT.

Считается, что у пентестеров ( читай "хакеров") нет эмоций, что это суровые "компьютерщики" хотя это и не совсем так. За последние годы каста безопасников тоже сократилась до горстки действующих охотников; столь мало их осталось, что мир начинает напоминать времена, когда их и вовсе не было - особенно в России.

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

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

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

Отслеживание "монстров" v.2Отслеживание "монстров" v.2"Типичный" пентестер"Типичный" пентестер

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

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

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

Скриншот из игры Ведьмак 3 : Дикая ОхотаСкриншот из игры Ведьмак 3 : Дикая Охота

Пентестер (он же хакер), может услышать - все от тех же "необразованных" - фрик, задрот.

Обоим в "бою" не обойтись без светящейся в темноте "волшебной" штуковины.

Те же, кто "образован" и "в курсе" наоборот, относятся с уважением и почётом, что в мире ведьмака к самим ведьмакам, что в нашем мире IT - к пентестерам, и уважают их ремесло.

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

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

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

Порой с этих слов состоят многие интро к рассказам на различных конференциях , таких как, например, ZeroNights.

Багбаунти

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

В Ведьмаке 3 Дикая Охота эту функцию просто выполняет доска объявлений.

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

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

К чему же это я это все?..

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

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

Там жители считали, мол чудовищ осталось не так много и оставшееся количество ведьмаков справится - но на самом деле ошибались, ведь чудовищ много и все они будут продолжать плодиться ( а с чего бы нет? ), быть может, создавая новые виды, а ведьмаки , хоть и сверхбойцы, но все же смертны, а создание новых бойцов либо идет очень медленно в подполье, либо отсутствует вовсе.

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

А ведь на кону наша с вами жизнь и наши персональные данные, если продолжить в том же духе - в будущем защищать страну будет некому.

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

Подробнее..

Будущее JavaScript классы

22.01.2021 14:05:41 | Автор: admin


Доброго времени суток, друзья!

Сегодня я хочу поговорить с вами о трех предложениях, относящихся к JavaScript-классам, которые находятся на 3 стадии рассмотрения:


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

Вспомним, что такое классы в JavaScript.

По большей части, классы представляют собой так называемый синтаксический сахар (абстракцию или, проще говоря, обертку) для функций-конструкторов. Такие функции используется для реализации паттерна проектирования Конструктор. Данный паттерн, в свою очередь, реализуется (в JavaScript) с помощью модели прототипного наследования (prototypal inheritance). Модель прототипного наследования иногда определяют в качестве самостоятельного паттерна Прототип. Подробнее о паттернах проектирования можно почитать здесь.

Что такое прототип? Это объект, который выступает в роли проекта или схемы (blueprint) для других объектов экземпляров (instances). Конструктор это функция, позволяющая создавать объекты-экземпляры на основе прототипа (класса, суперкласса, абстрактного класса etc.). Процесс передачи свойств и функций от прототипа к экземпляру называется наследованием. Свойства и функции в терминологии классов, обычно, именуются полями и методами, но, де-факто, это одно и тоже.

Как выглядит функция-конструктор?

// обратите внимание на включение строгого режима'use strict'function Counter(initialValue = 0) {  this.count = initialValue  // смотрим на то, что такое this  console.log(this)}

Мы определяем функцию Counter, принимающую параметр initialValue со значением по умолчанию, равным 0. Этот параметр присваивается свойству экземпляра count при инициализации экземпляра. Контекстом this в данном случае является создаваемый (возвращаемый) функцией объект. Для того, чтобы указать JavaScript на вызов не просто функции, но функции-конструктора, необходимо использовать ключевое слово new:

const counter = new Counter() // { count: 0, __proto__: Object }

Как мы видим, функция-конструктор возвращает объект с определенным нами свойством count и прототипом (__proto__) в виде глобального объекта Object, к которому восходят цепочки прототипов почти всех типов (данных) в JavaScript (за исключением объектов без прототипа, создаваемых с помощью Object.create(null)). Поэтому говорят, что в JavaScript все является объектом.

Если вызвать функцию-конструктор без new, то будет выброшено исключение TypeError (ошибка типа), говорящее о том, что свойство 'count' не может быть присвоено undefined:

const counter = Counter() // TypeError: Cannot set property 'count' of undefined// в нестрогом режимеconst counter = Counter() // Window

Это объясняется тем, что значением this внутри функции в строгом режиме является undefined, а в нестрогом глобальный объект Window.

Добавим в функцию-конструктор распределенные (совместно используемые, общие для всех экземпляров) методы по увеличению, уменьшению, сбросу и получению значения счетчика:

Counter.prototype.increment = function () {  this.count += 1  // возвращаем this, чтобы иметь возможность выстраивания цепочки из вызовов методов  return this}Counter.prototype.decrement = function () {  this.count -= 1  return this}Counter.prototype.reset = function () {  this.count = 0  return this}Counter.prototype.getInfo = function () {  console.log(this.count)  return this}

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

Добавление нескольких методов в прототип функции-конструктора можно оптимизировать следующим образом:

;(function () {  this.increment = function () {    this.count += 1    return this  }  this.decrement = function () {    this.count -= 1    return this  }  this.reset = function () {    this.count = 0    return this  }  this.getInfo = function () {    console.log(this.count)    return this  }// привязываем методы к прототипу функции-конструктора// https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Function/call}.call(Counter.prototype))

Или можно сделать еще проще:

// это современный синтаксис, раньше такой возможности не былоObject.assign(Counter.prototype, {  increment() {    this.count += 1    return this  },  decrement() {    this.count -= 1    return this  },  reset() {    this.count = 0    return this  },  getInfo() {    console.log(this.count)    return this  }})

Воспользуемся нашими методами:

counter  .increment()  .increment()  .getInfo() // 2  .decrement()  .getInfo() // 1  .reset()  .getInfo() // 0

Синтаксис класса является более лаконичным:

class _Counter {  constructor(initialValue = 0) {    this.count = initialValue  }  increment() {    this.count += 1    return this  }  decrement() {    this.count -= 1    return this  }  reset() {    this.count = 0    return this  }  getInfo() {    console.log(this.count)    return this  }}const _counter = new _Counter()_counter  .increment()  .increment()  .getInfo() // 2  .decrement()  .getInfo() // 1  .reset()  .getInfo() // 0

Для демонстрации работы механизма наследования в JavaScript рассмотрим более сложный пример. Создадим класс Person и его подкласс SubPerson.

В классе Person определяются свойства firstName (имя), lastName (фамилия) и age (возраст), а также методы getFullName (получение имени и фамилии), getAge (получение возраста) и saySomething (произнесение фразы).

Подкласс SubPerson наследует все свойства и методы Person, а также определяет новые поля lifestyle (образ жизни), skill (навык) и interest (интерес, хобби), а также новые методы getInfo (получение полного имени посредством вызова родительского-унаследованного метода getFullName и образа жизни), getSkill (получение навыка), getLike (получение хобби) и setLike (определение-установка хобби).

Функция-конструктор:

const log = console.logfunction Person({ firstName, lastName, age }) {  this.firstName = firstName  this.lastName = lastName  this.age = age};(function () {  this.getFullName = function () {    log(`Этого человека зовут ${this.firstName} ${this.lastName}`)    return this  }  this.getAge = function () {    log(`Этому человеку ${this.age} лет`)    return this  }  this.saySomething = function (phrase) {    log(`Этот человек говорит: "${phrase}"`)    return this  }}.call(Person.prototype))const person = new Person({  firstName: 'Иван',  lastName: 'Петров',  age: 30})person.getFullName().getAge().saySomething('Привет!')/*  Этого человека зовут Иван Петров  Этому человеку 30 лет  Этот человек говорит: "Привет!"*/function SubPerson({ lifestyle, skill, ...rest }) {  // привязываем конструктор Person к экземпляру SubPerson применительно к наследуемым свойствам  Person.call(this, rest)  this.lifestyle = lifestyle  this.skill = skill  this.interest = null}// делаем прототип Person прототипом SubPersonSubPerson.prototype = Object.create(Person.prototype)// и добавляем в него новые функцииObject.assign(SubPerson.prototype, {  getInfo() {    this.getFullName()    log(`Он ${this.lifestyle}`)    return this  },  getSkill() {    log(`Этот ${this.lifestyle} умеет ${this.skill}`)    return this  },  getLike() {    log(      `Этот ${this.lifestyle} ${        this.interest ? `любит ${this.interest}` : 'ничего не любит'      }`    )    return this  },  setLike(value) {    this.interest = value    return this  }})const developer = new SubPerson({  firstName: 'Петр',  lastName: 'Иванов',  age: 25,  lifestyle: 'разработчик',  skill: 'писать код на JavaScript'})developer  .getInfo()  .getAge()  .saySomething('Программирование - это круто!')  .getSkill()  .getLike()/*  Этого человека зовут Петр Иванов  Он разработчик  Этому человеку 25 лет  Этот человек говорит: "Программирование - это круто!"  Этот разработчик умеет писать код на JavaScript  Этот разработчик ничего не любит*/developer.setLike('делать оригами').getLike()// Этот разработчик любит делать оригами

Класс:

const log = console.logclass _Person {  constructor({ firstName, lastName, age }) {    this.firstName = firstName    this.lastName = lastName    this.age = age  }  getFullName() {    log(`Этого человека зовут ${this.firstName} ${this.lastName}`)    return this  }  getAge() {    log(`Этому человеку ${this.age} лет`)    return this  }  saySomething(phrase) {    log(`Этот человек говорит: "${phrase}"`)    return this  }}const _person = new Person({  firstName: 'Иван',  lastName: 'Петров',  age: 30})_person.getFullName().getAge().saySomething('Привет!')/*  Этого человека зовут Иван Петров  Этому человеку 30 лет  Этот человек говорит: "Привет!"*/class _SubPerson extends _Person {  constructor({ lifestyle, skill /*, ...rest*/ }) {    // вызов super() почти аналогичен вызову Person.call(this, rest)    // super(rest)    super()    this.lifestyle = lifestyle    this.skill = skill    this.interest = null  }  getInfo() {    // super.getFullName()    this.getFullName()    log(`Он ${this.lifestyle}`)    return this  }  getSkill() {    log(`Этот ${this.lifestyle} умеет ${this.skill}`)    return this  }  get like() {    log(      `Этот ${this.lifestyle} ${        this.interest ? `любит ${this.interest}` : 'ничего не любит'      }`    )  }  set like(value) {    this.interest = value  }}const _developer = new SubPerson({  firstName: 'Петр',  lastName: 'Иванов',  age: 25,  lifestyle: 'разработчик',  skill: 'писать код на JavaScript'})_developer  .getInfo()  .getAge()  .saySomething('Программирование - это круто!')  .getSkill().like/*  Этого человека зовут Петр Иванов  Он разработчик  Этому человеку 25 лет  Этот человек говорит: "Программирование - это круто!"  Этот разработчик умеет писать код на JavaScript  Этот разработчик ничего не любит*/developer.like = 'делать оригами'developer.like// Этот разработчик любит делать оригами

Думаю, тут все понятно. Двигаемся дальше.

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

// https://www.typescriptlang.org/docs/handbook/mixins.htmlfunction applyMixins(derivedCtor, constructors) {  constructors.forEach((baseCtor) => {    Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {      Object.defineProperty(        derivedCtor.prototype,        name,        Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||          Object.create(null)      )    })  })}class A {  sayHi() {    console.log(`${this.name} говорит: "Привет!"`)  }  sameName() {    console.log('Метод класса А')  }}class B {  sayBye() {    console.log(`${this.name} говорит: "Пока!"`)  }  sameName() {    console.log('Метод класса B')  }}class C {  name = 'Иван'}applyMixins(C, [A, B])const c = new C()// вызываем метод, унаследованный от класса Ac.sayHi() // Иван говорит: "Привет!"// вызываем метод, унаследованный от класса Bc.sayBye() // Иван говорит: "Пока!"// одноименный последующий метод перезаписывает предыдущийc.sameName() // Метод класса B

Однако, это не является полноценным решением и представляет собой всего лишь хак для того, чтобы втиснуть JavaScript в рамки объектно-ориентированного программирования.

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

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

const log = console.logclass C {  constructor() {    this.publicInstanceField = 'Публичное поле экземпляра'    this.#privateInstanceField = 'Приватное поле экземпляра'  }  publicInstanceMethod() {    log('Публичный метод экземпляра')  }  // получаем значение приватного поля экземпляра  getPrivateInstanceField() {    log(this.#privateInstanceField)  }  static publicClassMethod() {    log('Публичный метод класса')  }}const c = new C()console.log(c.publicInstanceField) // Публичное поле экземпляра// при попытке прямого доступа к приватной переменной выбрасывается исключение// console.log(c.#privateInstanceField) // SyntaxError: Private field '#privateInstanceField' must be declared in an enclosing classc.getPrivateInstanceField() // Приватное поле экземпляраc.publicInstanceMethod() // Публичный метод экземляраC.publicClassMethod() // Публичный метод класса

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

C.publicClassField = 'Публичное поле класса'console.log(C.publicClassField) // Публичное поле класса

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

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

publicInstanceField = 'Публичное поле экземпляра'#privateInstanceField = 'Приватное поле экземпляра'

Второе предложение позволяет определять приватные методы экземпляра:

#privateInstanceMethod() {  log('Приватный метод экземпляра')}// вызываем приватный метод экземпляраgetPrivateInstanceMethod() {  this.#privateInstanceMethod()}

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

static publicClassField = 'Публичное поле класса'static #privateClassField = 'Приватное поле класса'static #privateClassMethod() {  log('Приватный метод класса')}// получаем значение приватного поле классаstatic getPrivateClassField() {  log(C.#privateClassField)}// вызываем приватный метод классаstatic getPrivateClassMethod() {  C.#privateClassMethod()}

Вот как будет выглядеть (в действительности, уже выглядит) полный комплект:

const log = console.logclass C {  // class field declarations  // https://github.com/tc39/proposal-class-fields  publicInstanceField = 'Публичное поле экземпляра'  #privateInstanceField = 'Приватное поле экземпляра'  publicInstanceMethod() {    log('Публичный метод экземляра')  }  // private methods and getter/setters  // https://github.com/tc39/proposal-private-methods  #privateInstanceMethod() {    log('Приватный метод экземпляра')  }  // получаем значение приватного поля экземпляра  getPrivateInstanceField() {    log(this.#privateInstanceField)  }  // вызываем приватный метод экземпляра  getPrivateInstanceMethod() {    this.#privateInstanceMethod()  }  // static class features  // https://github.com/tc39/proposal-static-class-features  static publicClassField = 'Публичное поле класса'  static #privateClassField = 'Приватное поле класса'  static publicClassMethod() {    log('Публичный метод класса')  }  static #privateClassMethod() {    log('Приватный метод класса')  }  // получаем значение приватного поля класса  static getPrivateClassField() {    log(C.#privateClassField)  }  // вызываем приватный метод класса  static getPrivateClassMethod() {    C.#privateClassMethod()  }  // пытаемся получить публичное и приватное поля класса из экземпляра  getPublicAndPrivateClassFieldsFromInstance() {    log(C.publicClassField)    log(C.#privateClassField)  }  // пытаемся получить публичное и приватное поля экземпляра из класса  static getPublicAndPrivateInstanceFieldsFromClass() {    log(this.publicInstanceField)    log(this.#privateInstanceField)  }}const c = new C()console.log(c.publicInstanceField) // Публичное поле экземпляра// при попытке прямого доступа к значению приватного поля экземпляра выбрасывается исключение// console.log(c.#privateInstanceField) // SyntaxError: Private field '#privateInstanceField' must be declared in an enclosing classc.getPrivateInstanceField() // Приватное поле экземпляраc.publicInstanceMethod() // Публичный метод экземляра// попытка прямого доступа к приватному методу экземпляра также заканчивается ошибкой// c.#privateInstanceMethod() // Errorc.getPrivateInstanceMethod() // Приватный метод экземпляраconsole.log(C.publicClassField) // Публичное поле класса// console.log(C.#privateClassField) // ErrorC.getPrivateClassField() // Приватное поле классаC.publicClassMethod() // Публичный метод класса// C.#privateClassMethod() // ErrorC.getPrivateClassMethod() // Приватный метод классаc.getPublicAndPrivateClassFieldsFromInstance()// Публичное поле класса// Приватное поле класса// публичное и приватное поля экземпляра недоступны из класса,// поскольку на момент доступа к ним экземпляра не существует// C.getPublicAndPrivateInstanceFieldsFromClass()// undefined// TypeError: Cannot read private member #privateInstanceField from an object whose class did not declare it

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

Стоит отметить, что слова private, public и protected в JavaScript являются зарезервированными. При попытке их использования в строгом режиме выбрасывается исключение:

const private = '' // SyntaxError: Unexpected strict mode reserved wordconst public = '' // Errorconst protected = '' // Error

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

Обращаю ваше внимание, что техника инкапсуляции переменных, т.е. их защиты от доступа извне, стара, как сам JavaScript. До стандартизации приватных полей класса для скрытия переменных, обычно, использовались замыкания, а также паттерны проектирования Фабрика и Модуль. Рассмотрим эти паттерны на примере корзины для товаров.

Модуль:

const products = [  {    id: '1',    title: 'Хлеб',    price: 50  },  {    id: '2',    title: 'Масло',    price: 150  },  {    id: '3',    title: 'Молоко',    price: 100  }]const cartModule = (() => {  let cart = []  function getProductCount() {    return cart.length  }  function getTotalPrice() {    return cart.reduce((total, { price }) => (total += price), 0)  }  return {    addProducts(products) {      products.forEach((product) => {        cart.push(product)      })    },    removeProduct(obj) {      for (const key in obj) {        cart = cart.filter((prod) => prod[key] !== obj[key])      }    },    getInfo() {      console.log(        `В корзине ${getProductCount()} товар(а) на ${          getProductCount() > 1 ? 'общую ' : ''        }сумму ${getTotalPrice()} рублей`      )    }  }})()// модуль представляет собой обычный объект с методамиconsole.log(cartModule) // { addProducts: , removeProduct: , getInfo:  }// добавляем товары в корзинуcartModule.addProducts(products)cartModule.getInfo()// В корзине 3 товар(а) на общую сумму 300 рублей// удаляем товар с идентификатором 2cartModule.removeProduct({ id: '2' })cartModule.getInfo()// В корзине 2 товар(а) на общую сумму 150 рублей// пытаемся получить доступ к инкапсулированому полю и методуconsole.log(cartModule.cart) // undefined// cartModule.getProductCount() // TypeError: cartModule.getProductCount is not a function

Фабрика:

function cartFactory() {  let cart = []  function getProductCount() {    return cart.length  }  function getTotalPrice() {    return cart.reduce((total, { price }) => (total += price), 0)  }  return {    addProducts(products) {      products.forEach((product) => {        cart.push(product)      })    },    removeProduct(obj) {      for (const key in obj) {        cart = cart.filter((prod) => prod[key] !== obj[key])      }    },    getInfo() {      console.log(        `В корзине ${getProductCount()} товар(а) на ${          getProductCount() > 1 ? 'общую ' : ''        }сумму ${getTotalPrice()} рублей`      )    }  }}const cart = cartFactory()cart.addProducts(products)cart.getInfo()// В корзине 3 товар(а) на общую сумму 300 рублейcart.removeProduct({ title: 'Молоко' })cart.getInfo()// В корзине 2 товар(а) на сумму 200 рублейconsole.log(cart.cart) // undefined// cart.getProductCount() // TypeError: cart.getProductCount is not a function

Класс:

class Cart {  #cart = []  #getProductCount() {    return this.#cart.length  }  #getTotalPrice() {    return this.#cart.reduce((total, { price }) => (total += price), 0)  }  addProducts(products) {    this.#cart.push(...products)  }  removeProduct(obj) {    for (const key in obj) {      this.#cart = this.#cart.filter((prod) => prod[key] !== obj[key])    }  }  getInfo() {    console.log(      `В корзине ${this.#getProductCount()} товар(а) на ${        this.#getProductCount() > 1 ? 'общую ' : ''      }сумму ${this.#getTotalPrice()} рублей`    )  }}const _cart = new Cart()_cart.addProducts(products)_cart.getInfo()// В корзине 3 товар(а) на общую сумму 300 рублей_cart.removeProduct({ id: '1', price: 100 })_cart.getInfo()// В корзине 1 товар(а) на общую сумму 150 рублейconsole.log(_cart.cart) // undefined// console.log(_cart.#cart) // SyntaxError: Private field '#cart' must be declared in an enclosing class// _cart.getTotalPrice() // TypeError: cart.getTotalPrice is not a function// _cart.#getTotalPrice() // Error

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

Напоследок, рассмотрим пример создания веб-компонента кнопки с помощью синтаксиса класса (из текста одного из предложений с небольшой модификацией).

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

// https://developer.mozilla.org/ru/docs/Web/Web_Componentsclass Counter extends HTMLButtonElement {  #xValue = 0  get #x() {    return this.#xValue  }  set #x(value) {    this.#xValue = value    // привязываем к экземпляру метод рендеринга    // https://developer.mozilla.org/ru/docs/DOM/window.requestAnimationFrame    // https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Function/bind    requestAnimationFrame(this.#render.bind(this))  }  #increment() {    this.#x++  }  #decrement(e) {    // отменяем вызов контекстного меню    e.preventDefault()    this.#x--  }  constructor() {    super()    // привязываем к экземпляру обработчики событий    this.onclick = this.#increment.bind(this)    this.oncontextmenu = this.#decrement.bind(this)  }  // монтирование в терминологии React/Vue или, проще говоря, встраивание элемента в DOM  connectedCallback() {    this.#render()  }  #render() {    // для упрощения будем считать, что 0 - это положительное число    this.textContent = `${this.#x} - ${      this.#x < 0 ? 'отрицательное' : 'положительное'    } ${this.#x & 1 ? 'нечетное' : 'четное'} число`  }}// регистрация веб-компонентаcustomElements.define('btn-counter', Counter, { extends: 'button' })

Результат:



Представляется, что, с одной стороны, классы не получат повсеместного признания в сообществе разработчиков до решения, назовем ее так, проблемы this. Не случайно после продолжительного использования классов (классовых компонентов), команда React отказалась от них в пользу функций (хуков). Похожая тенденция наблюдается в Vue Composition API. С другой стороны, многие причастные к разработке ECMAScript, инженеры из Google, занимающиеся веб-компонентами, а также команда TypeScript активно работают над развитием объектно-ориентированной составляющей JavaScript, поэтому сбрасывать классы со счетов в ближайшие несколько лет точно не стоит.

Весь код, приводимый в статье, находится здесь.

Дополнительно про объектно-ориентированный JavaScript можно почитать здесь.

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

Просто космос NASA утвердило перечень первых целей для телескопа Джеймс Уэбб

07.04.2021 16:22:59 | Автор: admin
Источник
Почти двадцать лет назад появилась идея строительства нового мощнейшего космического телескопа Джеймс Уэбб, JWST или Webb, как его еще называют. И вот мы не только приближаемся к точке отсчета последних секунд перед взлетом, но и узнаем новые подробности о том, что будет делать телескоп в космосе.

NASA утвердило список первых целей для наблюдений Webb в первом цикле, ведь JWST уже через несколько месяцев (даже не верится) будет открывать секреты Вселенной. Перечень включает 286 самых разных программ: от изучения ледяного пояса Койпера, анализа климатической системы Плутона до исследования межзвездной среды.

Космические цели


NASA
Ученых из 44 стран мира отправили заявки для бронирования наблюдательных часов в рамках первого цикла. В итоге были отобраны первые 286 целей. Согласно расчетам, изучение всех обозначенных задач займет две трети времени в рамках первого цикла наблюдений или 6 000 наблюдательных часов.

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

  • 25 часов маленькие,
  • > 25 и 75 часов средние,
  • > 75 часов большие.


Цели, за которыми будет наблюдать телескоп, сгруппировали по направлениям, всего их 8:

  1. Экзопланеты и дисковые среды.
  2. Галактики.
  3. Межгалактическая и циркумгалактическая среды.
  4. Крупномасштабная структура Вселенной.
  5. Солнечная система.
  6. Астрофизика и типы звезд.
  7. Популяции планет и межзвездная среда.
  8. Сверхмассивные черные дыры.


К осуществлению целей аппарат приступит через 6 месяцев после отрыва от Земли.

Webb изучит самые разные аспекты космической жизни, включая:

  • атмосферы открытых экзопланет, далеких галактик, квазаров и протоскоплений;
  • галактики Местной вселенной, межгалактических и внутригалактических сред;
  • объекты Солнечной системы, включая кометы, астероиды, транснептуновые объекты, кентавры;
  • природа темной материи и черных дыр;
  • крупномасштабная структура Вселенной;
  • уточнение постоянной Хаббла;
  • галактики, звездные скопления и туманности Млечного пути.


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

Как проходил отбор заявок


Всего поступило порядка 1000 заявок из 44 стран мира.

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

Участники потратили бесчисленное множество часов вне официального времени для оценки предложений. Они ранжировали научную ценность каждого предложения в ходе двойного анонимного ревью.

Глобально основная исследовательская миссия JWST заключается в изучении, какой была Вселенная до Большого взрыва, поэтому цели так либо иначе связаны с этой центральной темой. Webb сможет наблюдать за галактиками на расстоянии 13 млрд световых лет от Земли.

NASA
Запуск Джеймс Уэбб запланирован на 31 октября 2021 года. Его откладывают последние 10 лет, поэтому мировое астрономическое сообщество c нетерпением ожидает этого события. В отличие от Хаббла, который исследует Вселенную в оптическом диапазоне, JWST будет изучать инфракрасную часть спектра.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru