JavaScript
895
Вклад в тег
TSLint в VSCode прям жутко тугойTSLint официально deprecated, вместо него стоит использовать плагин к eslint, заодно можете мой конфиг попробовать.
Типы? Есть JSDOCJSDoc в плане типов не умеет и 10% того, что умеет TypeScript. Кроме того, никто в здравом уме не пишет JSDoc на приватную логику, а значит проверки типов там не будет. JSDoc не гарантирует корректность рефакторинга, а вот благодаря TypeScript я, опять таки, точно не забуду обновить JSDoc.
многие библиотеки nodejs не имеют типовможет лет 5 назад так и было, но сейчас встретить библиотеку без типов - скорее исключение. Если библиотека популярная, но не предоставляет типов, скорее всего их уже написал кто-то другой, достаточно просто установить одноименный модуль из npm скоупа types и все будет работать само.
Поддержка браузерами скомпилированного кода? Да какбы почти весь JS имеет поддержку 95%+, тот же Babel уже забыл когда использовал.Вообще это не основная задача компилятора TypeScript, а опциональная возможность. И babel + preset-env с ней справляются гораздо лучше. И никто не мешает использовать их вместе. А еще думаю вопрос времени, когда кто-то напишет оптимизатор кода использующий информацию о типах из TS.
Примерно в каждой второй есть инстансы, на которые смотришь - и чешешь репу - а как называется тип этой переменной в @types/?
import {someObject} from 'some-library';
type TypeFromValue = typeof someObject;
const valueCopy: TypeFromValue = {
...someObject,
type: 'overrides',
with: 'type check',
};
и кстати, вот пример того что JSDoc типы не умеют.//@ts-checkи почти везде останется бесполезный any.
const h = 'Hello world!';
const n = 'nothing';
setTimeout(() => {
console.log(h);
}, 1000);
У нас есть строковые переменные h и n. Переменная n нигде больше не используется и ее память очистится при ближайшей работе GC. А вот переменная h оказалась в замыкании созданном стрелочной функцией. И хотя в JS мы не можем достучаться до h имея ссылку на эту функцию, сама функция все таки имеет ссылку на h, а значит h не может быть уничтожена пока не будет уничтожена сама функция. В терминах GC ссылка на h будет серой, то есть сама ссылка на h недоступна из корня напрямую, но сейчас мы проверяем объекты, которые на нее ссылаются и истина будет зависеть от них (подробнее можете погуглить "mark black white and gray memory in gc").Скажем был отправлен запрос на сервер, но потом компонент в котором был объявлен промис и колбек был удален.Если других ссылок не осталось, то инстанс компонента будет удерживаться от очистки через промис.
И после удаления приходит ответ от сервера, и он выполнит колбек. Это значит что колбек остался в памяти со всеми переменными контекста
function getSomething(){
return new Promise((resolve, reject)=>{
if(sys_condition){
resolve();
}
})
}
function testPromise(){
let config = {....}
getSomething().then(()=>{
#use config
goOn(...config)
})
}
testPromise();
У нас есть вызванная 1 раз функция testPromise, которая получает из функции getSomething промис, в который с помощью метода then сохраняет колбэк, удерживающий в замыкании переменную config. Сам промис она нигде не сохраняет, что здесь очень важно.В этом примере. если sys_condition = false и resolve не вызовется, это значит что создается утечка памятиНет, утечки памяти не будет. Колбэк созданный в testPromise будет удален вместе с замыканием, так и не вызвавшись ни разу.
1. Для чего замыкание существуют?Для инкапсуляции данных.
2. В каких условиях они создаются?Когда вложенная функция обращается к переменным внешней функции.
// makeCounter - внешняя функция
function makeCounter(initialValue) {
var value = +initialValue || 0;
// counter - внутренняя функция
// она использует переменную value из внешней функции
// что-бы это было возможным, для counter создается замыкание,
// в котором хранится переменная value
// переменная initialValue функции counter не нужна, поэтому ее можно "забыть"
return function counter() {
return value++;
};
}
// у нас 3 экземпляра функции counter
var counter1 = makeCounter();
var counter2 = makeCounter();
var counter3 = makeCounter(100);
// и для каждой есть своя переменная value
console.log(counter1()); // 0
console.log(counter1()); // 1
console.log(counter2()); // 0
console.log(counter1()); // 2
console.log(counter3()); // 100
// а вот получить как-то напрямую переменную value мы не можем
// инкапсуляция нам не дает поломать данные
var self = this;
позволяющая сохранить контекст в замыкании уже потихоньку уходит в прошлое, благодаря стрелочным функциям из es2015