const consoleArray = Object.keys(console).filter(
k => typeof console[k] === 'function'
).reduce(
([cnsl, acc], key) => [Object.assign(cnsl, {
[key]: (original => (...args) => (
acc.push(...args),
original.call(cnsl, acc)
))(cnsl[key])
}), acc],
[console, []]
)[1];
Math.floor(1.1) // 1
parseInt(1.1) // 1
1.1 | 0 // 1
1.1 ^ 0 // 1 - как уже писал выше, эффект будет 1 в 1, как и с |
// пока все было ок, но как насчет отрицательных чисел?
Math.floor(-1.1) // -2 - округляем в сторону -Infinity
parseInt(-1.1) // -1 - отбрасываем экспоненту
-1.1 | 0 // -1 - отбрасываем экспоненту и не только (но тут не имеет значения пока)
// попробуем с чем-нибудь побольше
2 ** 31 // 2147483648
2147483648 | 0 // -2147483648
/*
не зная как преобразовывается число выше, это было бы не очевидно
но смотрим выше "он просто берет младшие 32 бита значимой части и кладет их в int32 контейнер"
2 ** 31 в двоичном виде - это единичка и 31 нолик
и эта единичка попала в бит знака при переноси в int32
тем самым мы получили самое маленькое число в int32
*/
// давайте еще пример, набью как я большое число от балды:
34646456436346346212424 // 3.464645643634635e+22
34646456436346346212424 | 0 // 1178599424
/*
ну в первом примере мы видим интересную особенность чисел с плавающей запятой
мы можем хранить не только дробные числа, но и очень большие целые, правда с потерей точности
e+22 - это и есть экспонента, это значит число до e нужно умножить на основание системы счисления (10) в степени +22
а при бинарной операции эта экспонента отбрасывается, как и старшие биты значимой части
в 32 младших битах осталось 1178599424
забавно, что я случайно вбил такое число, у которого 32 бит содержал 0 (шансы были 50/50)
если бы там оказалась 1, то я бы вновь получил отрицательное число
*/
const div = document.body.appendChild(document.createElement('div'));
export function remove() {
document.body.removeChild(div);
}
Даже если мы просто импортируем его, но не вызываем функцию remove, он все равно произведет свой побочный эффект - добавит новый div в body. И это произойдет при первом встретившемся импорте.Правильным ли решением будет использовать redux для обычного веб-ресурсаПочему бы и нет. Redux не имеет никакого отношения к React от слова совсем.
Или есть альтернативы ?Ну можете взять обычный compose из lodash/ramda (в ramda кстати есть линзы, которые хорошо помогают работать с иммутабельными объектами) и соединить им Ваши "редьюсеры". Положить объект в переменную state в замыкании, и все - свой redux готов.
скрыть ссылку от индексации посредством скриптаОт поисковых роботов? Им вполне может быть пофик, как там скрипты DOM меняют, они вполне могут проиндексировать страницу как до выполнения скриптов, так и после.
let rawNews = []; // Массив объектов (Свеженькие новости прямо из БД)
let rawCats = []; // Массив объектов с обработанными новостями
// Промис с массивом результатов
let modifyNews = Promise.all(rawNews.map(async (item, i, arr) => {
item.autor = await getUserByID(item.autor); // Асинхронная функция которая выставляет имя автора вместо id
return item;
}));
// export или module.export =
function formatText(text, formatters) {
return formatters.reduceRight(applyFormatter, text);
}
function applyFormatter(text, formatter) {
const {offset, length, type} = formatter;
const endOffset = offset + length;
const wrapper = getWrapper(type);
return `${text.slice(0, offset)}${wrapper(
text.slice(offset, endOffset),
formatter
)}${text.slice(endOffset)}`;
}
function getWrapper(type) {
switch(type) {
case 'bold':
return boldWrapper;
case 'text_link':
return linkWrapper;
default:
return identityWraper;
}
}
function boldWrapper(text) {
return `<b>${text}</b>`;
}
function linkWrapper(text, {url}) {
return `<a href="${url}">${text}</a>`
}
function identityWraper(text) {
return text;
}
console.log(formatText('qwerty Ссылка', [
{ offset: 0, length: 7, type: 'bold' },
{ offset: 7, length: 6, type: 'text_link', url: 'https://vk.com/' }
])); // <b>qwerty </b><a href="https://vk.com/">Ссылка</a>
function add(left, right) {
const typeLeft = typeof left;
const typeRight = typeof right;
if(typeLeft === 'string') {
return left.concat(right);
}
if(typeRight === 'string') {
return right.concat(left);
}
if(canConvertToNumber(left, typeLeft) && canConvertToNumber(right, typeRight)) {
return Number(left) + Number(right); // тут уже не перегруженный вариант + иначе будет бесконечная рекурсия
}
if(typeLeft === 'bigint' && typeRight === 'bigint') {
return left + right; // опять не перегруженный вариант
}
if(
(typeLeft === 'bigint' && canConvertToNumber(right, typeRight))
|| (typeRight === 'bigint' && canConvertToNumber(left, typeLeft))
) {
// если предыдущий if не прошел, а проходит этот
// то мы складываем bigint с не bigint, а так нельзя
throw new TypeError('Cannot mix BigInt and other types, use explicit conversions');
}
// во всех остальных случаях приводим к строке:
return String(left).concat(right);
}
function canConvertToNumber(item, type) {
return item === null || type === 'number' || type === 'boolean' || type === 'undefined';
}
делаю проект на laravelЗначит у Вас уже есть laravel-mix, который под капотом использует webpack, а значит можно нормально работать с import
А потом эти классы импортировать и объекты уже этих классов делать глобальными:window.text= new Text(); window.cart = new Cart(); window.Form = new Form();
Что бы потом это не получилось в неуправляемую кашу.Как раз такой подход приведет к неуправляемой каше.
А потом уже в разметке в событиях вызывать методы соответствующих объектовДа Вы батенька мазахист...
let x = 10;
console.log(x++); // 10
console.log(x--); // 11
значение сначала будет передано в console.log, а потом посчитано новоеlet x = 10;
console.log(++x); // 11
console.log(--x); // 10
сначала посчитает, а потом передаст в console.log