telegram | @Momomash |
github | @Momomash |
@mari_momos |
0 - идея 💡 | Есть проблема -> предложение решения |
1 - предложение |
Концепт Обоснование и описание |
2 - черновик |
Прототип Формальная реализация спецификации, Первая имплементация (babel) |
3- кандидат |
Бета-тест Отзызы от разработчиков и браузеров Фикс багов |
4- финал |
Предрелиз Написаны юнит-тесты (test-262) Практический опыт применения -> Включение в ближайшую версию языка |
Map | WeakMap | |
Тип ключа | Any |
Object |
Препятствует сборке мусора? |
true |
false |
let primarch = {name: 'Horus'};
const map = new Map();
map.set(primarch, 'primarch');
primarch = null;
console.log(map); // Map(1) {{name: 'Horus'}: 'primarch'}
let primarch = {name: 'Horus'};
let weakMap = new WeakMap();
weakMap.set(primarch, 'traitor');
primarch = null;
console.log(primarch) // {}
Map | WeakMap | |
Тип ключа | Any |
Object, Symbol |
Препятствует сборке мусора? |
true |
false |
let games = [
...,
{year: 2015, author: 'CD Projekt RED', title: 'The Witcher 3'},
{year: 2020, author: 'CD Projekt RED', title: 'Cyberpunk 2077'},
{year: 2022, author: 'From Software', title: 'Elden Ring'},
{year: 2023, author: 'Mundfish', title: 'Atomic Heart'},
]
let game, index;
let i = games.length - 1;
while (i > 0 && !game && !index) {
if (games[i].author === 'From Software'){
game = games[i]; index = i;
};
--i;
};
const game = games.findLast(
({author}) => author === 'author1'
);
const indexOfGame = games.findLastIndex(
({author}) => author === 'author1'
);
const array = [1,2,3];
array.with(1,10); // => [1,10,3]
console.log(array); // => [1,2,3]
type Primarch = { name: string, isLoyal: string };
const primarchs: Primarch[] = [
{ name: 'Horus', isLoyal: false },
{ name: 'Leman Russ', isLoyal: true },
{ name: 'Magnus the Red', isLoyal: true },
{ name: 'Mortarion', isLoyal: false },
{ name: 'Lion El Jonson', isLoyal: false },
{ name: 'Conrad Curze', isLoyal: false },
{ name: 'Corvus Corax', isLoyal: true },
];
type GroupedPrimarchs = {
loyal: Primarch[], traitor: Primarch[]
};
const groupedPrimarchs = primarchs.reduce(
(acc, primarch) => {
primarch.isLoyal ? acc.loyal = [...acc.loyal, primarch]
: acc.traitor = [...acc.traitor, primarch];
return acc;
},
{loyal: [], traitor: []}
);
const result = {loyal: [], traitor: []};
primarchs.forEach(() => {
let target = i.isLoyal ? result.loyal : result.traitor;
target.push(i);
})
const groupedPrimarch = primarchs.group(
(item, array, index) =>
item.isLoyal ? 'loyal' : 'traitor';
)
// => { loyal: [ { name: 'Leman Russ', isLoyal: true },...],
// traitor: [ { name: 'Horus', isLoyal: false },...]
// }
const loyal = {loyal: true};
const traitor = {traitor: true};
const primarchsMap = primarchs.groupToMap(
(item, array, index) => item.isLoyal ? loyal : traitor;
) // => Map
primarchsMap.get(loyal) // => [ { name: 'Leman Russ', isLoyal: true },...];
primarchsMap.get(traitor) // => [ { name: 'Horus', isLoyal: false },...];
import config from './config.json';
console.log(config.username);
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "application/json". Strict MIME type checking is enforced for module scripts per HTML spec.
import config from './config.json' assert {type: 'json'};
const config = import('./config.json' assert {type: 'json'});
config.then( data =>
data.default.forEach(param => {
console.log(param);
})
)
new Worker('app.wasm', {
type: 'module',
assert: {type: 'webassembly'}
})
Number |
BigInit |
String |
Boolean |
Null |
Undefined |
Symbol |
Object |
Record |
Tuple |
let alliances = #['Order', 'Chaos', 'Death', 'Destruction'];
let game = #{
name: 'Age of Sigmar',
tags: #['wargame', 'Games Workshop', 'Fantasy']
};
let game = #{
name: 'Age of Sigmar',
tags: #['wargame', 'Games Workshop', 'Fantasy'],
stores: {anyKey: 'any Value'}
};
"TypeError: cannot use an object as a value in a record"
let alliances = #['Order', {anyKey: 'any Value'}];
"TypeError: cannot use an object as a value in a tuple"
let game = #{
name: 'Age of Sigmar',
tags: #['wargame', 'Games Workshop', 'Fantasy'],
};
game.name = 'Fantasy Battles';
"Cannot assign to read only property 'name' of object '[object Object]'"
let alliances = #['Order', 'Chaos', 'Death', 'Destruction'];
alliances[0] = 'Any Text';
"Cannot assign to read only property '0' of object '[object Tuple]'"
const game = { name: 'Warhammer' };
console.log(game === { name: 'Warhammer' }); // false;
console.log(
JSON.stringify(game) === JSON.stringify({ name: 'Warhammer' })
); // true;
const game1 = { name: 'Age of Sigmar', company: 'Games Workshop' };
const game2 = { company: 'Games Workshop', name: 'Age of Sigmar' };
console.log(JSON.stringify(game1) === JSON.stringify(game2));
// false;
const game1 = { name: 'Age of Sigmar', company: 'Games Workshop' };
const game2 = { company: 'Games Workshop', name: 'Age of Sigmar' };
// lodash
.isEqual(game1, game2); // true
#{name: 'Sigmar'} === #{name: 'Sigmar'} // true
#['Order', 'Chaos'] === #['Order', 'Chaos'] // true
const date = Temporal.Now.zonedDateTimeISO();
const { year, month, day, hour,minute, second, milisecond } = date;
console.log(
year, // 2023
month, // 4
day, // 19
hour, // 21
minute, // 48
second, // 50
milisecond // 256
);
const { dayOfWeek, dayOfYear,daysInMonth,inLeapYear } = date;
console.log(
dayOfWeek, // 3
dayOfYear, // 109
daysInMonth, // 30
inLeapYear // false
);
const now = Temporal.Now.plainDateISO();
const pastDate = Temporal.PlainDate.from('2021-03-12');
const futureDate = Temporal.PlainDate.from('2023-08-15');
Temporal.PlainDateTime.compare(now, pastDate) // 1
Temporal.PlainDateTime.compare(now, futureDate) // -1
Temporal.PlainDateTime.compare(now, now) // 0
const today = Temporal.PlainDate.from('2023-04-19'); // 2023-04-19
const tomorrow = today.add({days: 1}) // 2023-04-20
const monthAgo = today.substract({months: 1}) // 2023-03-19
const yearAgo = today.substract({years: 1}) // 2022-04-19
console.log(today.toJSON()) // 2023-04-19
const duration = Temporal.Duration.from({
minutes: 10,
seconds: 52
});
const durationInDays = duration.round({
smallestUnit: 'munites' // PT11M
})
const today = Temporal.PlainDate.from('2023-04-19');
console.log(today.toLocaleString()); // 19.04.2023
console.log(today.toJSON()); // 2023-04-19
Stage 3
2 полифилла
"-Most likely it'll be a part of the next edition."
console.log(
chalk.dim(
`$ ${Object.keys(envar)
.map(envar) =>
`${envar}=${envars[envar]}`)
.join(' ')
}`,
'node',
args.join(' ')));
)
)
Object.keys(envars)
.map(envar) => `${envar}=${envars[envar]}`)
.join(' ')
|> `$ #{%}`
|> chalk.dim(%, 'node', args.join(' ' ))
|> console.log(%)
Object.keys(envars)
.map(envar) => `${envar}=${envars[envar]}`)
.join(' ')
|> `$ #{%}`
|> chalk.dim(%, 'node', args.join(' ' ))
|> console.log(%)
function logDuration(fn) {
return function decorator(...args) {
let start = Date.now();
let result = fn.apply(this, args);
let duration = Date.now - start;
console.log(fn.name + '() duration: ' + duration);
return result;
};
};
4 итерации
7 лет разработки
Уже 2 legacy-имплементации
↓
Stage 3
Возможность через прототип влиять на объект декорирования | Работают только с объектом декорирования, а не с дескрипторами |
Проблемы производительности | Работают только с классами и их элементами |
Новый объект декорирования - accessor |
type Decorator = (
value: Input,
context: {
kind: string;
name: string | symbol;
access: {
get?(): unknown;
set?(value: unknown): void;
};
private?: boolean;
static?: boolean;
addInitializer?(initializer: () => void): void;
}
) => Output | void;
Демо
"The old thing is deprecated,
and the new thing is not ready yet!"
// .babelrc
"plugins": [
[
"@babel/plugin-proposal-decorators", {
"version": "2023-01"
}
]
]
Следующие Web API поддерживаются еще не всеми
браузерами 🧪.
Перед использованием убедитесь, что поддерживаются
нужные вам платформы
Демо
94
94-95
No
80
No
if ("wakeLock" in navigator) {
let wakeLock = null;
try {
wakeLock = await navigator.wakeLock.request("screen");
console.log("Wake Lock is active!");
} catch (err) {
console.error(`${err.name}, ${err.message}`);
}
} else {
console.error("Wake lock is not supported by this browser.");
}
// отключить блокировку экрана
wakeLock.release().then(() => {
wakeLock = null;
});
// среагировать на пробуждение
wakeLock.addEventListener('release', () => {
console.log('Hello, user!');
});
84
94-84
No
70
16.4
const initialString =
"any <\script>alert('За Альянс!')<" + "/script> text";
const sanitizer = new Sanitizer();
const target = document.getElementsById('target');
target.setHTML(initialString, {sanitizer})
console.log(target.innerHTML); // any text
const initialString =
"any <\script>alert('За Альянс!')<" + "/script> text";
const sanitizer = new Sanitizer();
const sanitizedString =
sanitizer.sanitizeFor('div', initialString);
console.log(sanitizedString instanceof HTMLDivElement);
// true
document.querySelector('div#target')
.replaceChildren(sanitizedString)
const sanitizer = new Sanitizer();
const iframe = document.getElementById('userFrame');
const treeFromIframe = iframe.contentWindow.document;
const sanitizedIframeTree = sanitizer.sanitize(treeFromIframe);
iframe.replaceChildren(sanitizedIframeTree);
Демо
105
105
83
79
No
Демо
105
105
No
91
No
::view-transition-old(root) {
animation: 90ms cubic-bezier(0.4, 0, 1, 1) both fade-out,
300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left;
}
::view-transition-new(root) {
animation: 210ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in,
300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right;
}
startViewTransition()
Opacity:1 -> Opacity: 0
empty
Opacity:0 -> Opacity: 1
Демо
111
111
No
97
No
BIOCAD
telegram | @Momomash |
github | @Momomash |
@mari_momos |