const setPropChain = (obj, path, value) => {
path.split('.').reduce((acc, c, i, arr) => {
if (!acc.hasOwnProperty(c)) acc[c] = {};
if (typeof acc[c] !== "object") throw "Not an object prop " + c;
if (i === arr.length - 1) acc[c] = value;
return acc[c];
}, obj);
return obj;
}
// использование:
setPropChain({"test": 0}, "make.some.noise", "habr")
{
"test": 0,
"make": {
"some": {
"noise": "habr"
}
}
}
for (...) {
// что-то делается
if (condition) {
break; // досрочный выход из цикла
}
// ещё может что-то делается
}
for
, while
можно оборвать, выйти из них с помощью break
Array.forEach()
досрочно оборвать не удастся. каким образом допустим в этой функции мы используем массив(объект) не объявив егоОбъявляют переменные. Здесь обошлись без переменной.
5
? return 5;
— тут всё нормально.[1, 2, 3] // массив
{a: 1, b: 2} // объект
return [1, 2, 3]; // вернули массив
return {a: 1, b: 2}; // вернули объект
return [1, 2, 1 + 2]; // вернули массив, где что-то посчитали налету
return {a: 1, b: 1 + 1}; // вернули объект, что сложили в последний момент
+
является особенным оператором, исключением, отличающимся от других математических операторов.Почти все математические операторы выполняют численное преобразование. Исключение составляет +.Подробнее: https://learn.javascript.ru/type-conversions
Если одно из слагаемых является строкой, тогда и все остальные приводятся к строкам.
Тогда они конкатенируются (присоединяются) друг к другу:
alert( 1 + '2' ); // '12' (строка справа) alert( '1' + 2 ); // '12' (строка слева)
'42' / 2 // 21
'42' - 2 // 40
'42' * 2 // 84
'42' + 2 // "422" ¯\_(ツ)_/¯
1 + 2 + 3 + 4 + 5 // 15
1 + 2 + 3 + '4' + 5 // "645"
+
работает слева-направо. Поэтому 1+2+3
всё ещё число, а дальше '4'
заставляет переключиться на строки. arr[0] // первый элемент, объект:
{
variation: {
attributes: {
"attribute_pa_obem": "500-gr",
"attribute_pa_czvet-produkta": "c-110-goluboj"
}
}
}
variation
: arr[0].variation // там объект с единственным свойством "attributes"
attributes
: arr[0].variation.attributes // там объект с искомыми двумя свойствами
arr[0].variation.attributes["attribute_pa_obem"] // "500-gr"
arr[0].variation.attributes["attribute_pa_czvet-produkta"] // "c-110-goluboj"
const ref = arr[0].variation.attributes;
ref["attribute_pa_obem"] // "500-gr"
ref["attribute_pa_czvet-produkta"] // "c-110-goluboj"
arr[0].variation.attributes.attribute_pa_obem // "500-gr"
// или
ref.attribute_pa_obem // "500-gr"
const arr = [0, 0, 0];
Object.freeze(arr); // ма-агия!
arr.unshift(100); // выбросит ошибку: нельзя менять свойство длины, оно non-writeable
arr[1] = 'z'; // ошибки не будет, но
console.log(arr) // [0,0,0]
(s => `${s.substr(0,2)}.${s.substr(2,2)}.${s.substr(4)}`)('30032020')
const format = (_, v) => {
const s = v.toString();
return `${s.substr(0,2)}.${s.substr(2,2)}.${s.substr(4)}`;
}
format`${30032020}`
const num = 30032020; // число
const str = num.toString().padStart(8, '0'); // строка длиной 8 символов
const result = `${str.substr(0,2)}.${str.substr(2,2)}.${str.substr(4)}`; // "30.03.2020"
requestAnimationFrame()
, реже срабатывают таймеры. for(let i = 0; i < 18; i++){
let block = document.createElement('div');
field.appendChild(block);
block.classList.add('blocks');
block.addEventListener('click', event => onClick(event, i));
}
||
const year = prompt('В каком году появилась спецификация ECMAScript-2015?');
alert( year == '2015' || year == '2016' ? 'правильно' : 'неправильно' );
x > y
, значит, x = y + ненулевое_число
. Можно так перезаписать слагаемые:m = k0
z = m + k1 = k0 + k1
y = z + k2 = k0 + k1 + k2
x = y + k3 = k0 + k1 + k2 + k3
-----------------------------
m+z+y+x = 4k0 + 3k1 + 2k2 + k3 = SUM
ki — это натуральные числа от 1. k
— вычислили x, y, z, m.k0
k1..k3
уходит минимум 6, когда все по 1,k0
остаётся диапазон [1, (SUM - 6) / 4]
k0
должен быть целым.k0
в этом диапазоне, SUM1 = SUM - 4 * k0
,3k1 + 2k2 + k3 = SUM1
k3
это весь остаток.const addUpTo = (top, n) => {
const getDiffs = (sum, n, acc = []) => {
if (n === 1) {
x = sum;
} else {
const headroom = (n - 1) * n / 2;
const cap = Math.floor((sum - headroom) / n);
if (cap < 1) throw("Impossible. " + JSON.stringify(acc));
x = 1 + Math.floor(Math.random() * cap);
}
acc.push(x);
if (n <= 1) {
return acc;
} else {
return getDiffs(sum - x * n, n - 1, acc);
}
}
return getDiffs(top, n).map((_, i, a) => a.reduce((acc, c, j) => j <= i ? acc + c : acc)).reverse();
}
addUpTo(100, 4) /*
[ 34, 30, 21, 15 ]
[ 31, 24, 23, 22 ]
[ 66, 17, 13, 4 ]
[ 47, 22, 21, 10 ]
...
*/
addUpTo(10, 4) // [ 4, 3, 2, 1 ]
addUpTo(9, 4) // ошибка, невозможно разложить
$timestamp = date('2020-03-29T23:59:00+03:00'); // +03:00 потому что по МСК
echo "<script>const theMoment = ${timestamp};</script>";
const checkTime = (ts) => {
if (Date.now() < ts) return setTimeout(() => checkTime(ts), 1000);
// время пришло
document.getElementById('price').innerText = '39 990';
}
checkTime(theMoment * 1000); // в JS timestamp считается в миллисекундах
// а из PHP приходит в целых секундах
<p>
Специальная цена на наш утюг: <span id="price">29 990</span>
<br>
действует до 30 марта!
</p>
indexOf()
this.children
, а хочется.[]
и его метод indexOf
call()
(подробнее)indexOf
в качестве this
(где искать) — this.children
,event.target
event.target
среди this.children
-1
, если не нашлось. test()
можно обернуть исходные функции с их аргументами в функции:function test(fn1, fn2){
if(fn1()){
console.log('blabla');
} else {
fn2();
}
}
// в вызове оборачивайте в функции:
test(() => real_function1(arg0, arg1), () => real_function2(arg3));
test(real_func1.bind(null, arg1, arg2), real_func2.bind(null, arg3));