document.getElementById()
– это метод getElementById()
у объекта document
. Вызов возвращает Element. Или null
, если нет элемента с таким ID.getElementById()
уже у объекта Element. А у него такого метода нет.document.getElementById()
не ищет, а просто берёт, если есть такой. bind()
создаёт каждый раз новую копию функции.const listener = this.onclickWindowHandler.bind(this);
window.addEventListener('click', listener);
// ...
window.removeEventListener('click', listener);
alert(value)
возвращает undefined
myalert(value)
возвращает value
A || B && C
разбирается как A || (B && C)
A
. Если оно приводится к false
, требуется проверить второй аргумент ||
, т.е. (B && C)
B
. Если оно приводится к false
, то проверять C
уже не нужно. function resort(selector) {
const nodeList = document.querySelectorAll(selector);
const dict = {};
const parent = nodeList[0].parentNode;
nodeList.forEach(node => {
const key = node.querySelector('p').innerText;
dict[key] = node;
node.parentNode.removeChild(node);
});
const keys = Object.keys(dict);
keys.sort().forEach(k => parent.appendChild(dict[k]));
}
resort('.slide');
function fn(words, target) {
const length = words.length, targetLength = target.length;
const aWord = []; // индексы слов в aWords
const aWant = []; // какой длины не хватает до целого
const bWord = [];
const bWant = [];
for (let i = 0; i < length; i++) {
const word = words[i];
const x = target.indexOf(word);
if (-1 === x) continue;
const wordLength = word.length;
const want = targetLength - wordLength;
if (x === 0) { // в начале составного, первое подслово
aWord.push(i);
aWant.push(want);
const bIndex = bWant.indexOf(wordLength);
if (-1 === bIndex) continue;
const bWordIndex = bWord[bIndex];
return [words[bWordIndex], word, [i, bWordIndex]];
} else { // не в начале слова встретилось - второе слово, в конце цели
if (x + wordLength !== targetLength) continue; // не попадает в конец
bWord.push(i);
bWant.push(want);
const aIndex = aWant.indexOf(wordLength);
if (-1 === aIndex) continue;
const aWordIndex = aWord[aIndex];
return [words[aWordIndex], word, [aWordIndex, i]];
}
}
return null;
}
var isCollided = false; // изначально нет столкновения
На каждой итерации – будь то по setInterval()
или requestAnimationFrame()
– проверяйте, есть ли столкновение сейчас. И сравнивайте с предыдущим.const isNowCollided = checkIfCollided(); // как-то проверяем, есть ли сейчас наложение
if (isNowCollided && !isCollided) { // впервые столкнулись!
// alert! alert!
} else if (!isNowCollided && isCollided) { // выехали из зоны
// всем неинтересно
} else {
// вообще без новостей
}
isCollided = isNowCollided;
0..n
, в случайном порядке выдёргивая из этой «колоды» очередную карту. Когда колода пустеет, открываем новую.// Итератор случайных уникальных - Random Unique
function getRUIterator(max) {
let buffer = [];
const ruIterator = {
next: function() {
if (buffer.length === 0) { // если колода пуста
for (let i = 0; i < max; i++) buffer.push(i); // открываем новую 0..max
}
const index = Math.floor(Math.random() * buffer.length);
return buffer.splice(index, 1)[0]; // вынимаем из колоды случайную карту
}
}
return ruIterator;
}
/**
* генерим в каждый див по случайной картинке
* как можно дольше без повторов
* @param int iTotal число доступных картинок
* @param Array массив строк - айдишки div'ов, куда вставлять
*/
function placeRandomImages(iTotal, aDivs) {
function placeImage(n, id) {
const img = new Image();
img.src = `img/${n}.png`;
img.border = '0';
document.getElementById(id).appendChild(img);
}
// будет генерить случайные неповторяющиеся
const RUI = getRUIterator(iTotal);
for (let i = 0; i < aDivs.length) {
placeImage( RUI(), aDivs[i]);
}
}
placeRandomImages(2, ["imaaaga", "imaaaga2"]);
push()
, принимающий пачку новых параметров. Но мы готовы к обоим вариантам: пушим или в крутой объект, или в пустой массив.(function(w, n) {
w[n] = w[n] || [];
w[n].push({a: "A", b: "B"});
})(window, 'tosterQuery');
// в скрипте подгружаемом позже
(function(w, n) {
// не перезаписать объкт. Только если пустой или массив.
if (w[n] && !Array.isArray(w[n])) return;
function f() {
const data = w[n] || [];
// определяем свой push с блекджеком
this.push = function(x) {return data.push(x);}
this.getData = function() {return data;}
}
w[n] = new f(); // занимаем глобальное свойство
})(window, 'tosterQuery');
tosterQuery.getData(); // [{"a":"A","b":"B"}]
tosterQuery.push({z:"Z"});
tosterQuery.getData(); // [{"a":"A","b":"B"}, {"z":"Z"}]
if (!roofpt) Price2 = 5500; // null, 0, undefined, false, пустая строка
else if (roofmat == 1) Price2 = 7900; // и так известно, что не пустое
else if (roofmat == 2) Price2 = 8900; // и так известно, что не пустое
else Price2 = 0; // по умолчанию
&&
выше, чем ||
. Эти два условия выглядят похоже, имелась в виду, наверное, лишняя перепроверка на null/ноль:(roofpt == null || roofpt == 0)
(roofpt !== null || roofpt !== 0 && roofmat == 1)
&&
, потом ||
:A || B && C === A || (B && C)
// и второе условие на деле считается так:
(roofpt !== null || (roofpt !== 0 && roofmat == 1))
rootpt
, неравном null
.==
и строгое неравенство !==
. Разжёвывать не буду, чтобы вы провалили собеседование.120
и 120.001
, условия не определены и код даст ошибку, т.к. не определится одна из переменных.else if
. Поскольку они перемножаются и по умолчанию единицы, можно сразу определять конечное значение:if (floors.value == 1) {
aF = 1; // по умолчанию, для больше 300
if (area.value <= 120) aF = 1.26;
else if (area.value <= 140) aF = 1.24;
else if (area.value <= 160) aF = 1.23;
else if (area.value <= 200) aF = 1.22;
else if (area.value <= 260) aF = 1.2;
else if (area.value <= 300) aF = 1.19;
console.log(aF);
} else if (floors.value == 2 || floors.value == 3) {
bF = 1; // ? для меньше 100 .. и больше 300
if (area.value >= 100 && area.value <= 130) bF = 1.3;
else if (area.value <= 160) bF = 1.27;
else if (area.value <= 200) bF = 1.24;
else if (area.value <= 300) bF = 1.22;
console.log(bF);
}
const monthNames = 'января февраля марта апреля мая июня июля августа сентября октября ноября декабря'
.split(' '); // получится массив
const D = new Date(); // объект Даты на сейчас
// завтрашний день
D.setDate( D.getDate() + 1); // так месяц "переключится" автомагически
console.log( 'Завтра ' + D.getDate() + ' ' + monthNames[ D.getMonth() ] );
complete
и после него naturalWidth
(или naturalHeight
) через какое-то время после назначения src
– достаточное для загрузки картинки. Проверка того, есть ли картинка, в любом случае немгновенна, асихнонна.const srcs = [
'https://sun6-5.userapi.com/c850632/v850632804/12d149/KnY01pJH16w.jpg'
,'https://sun6-6.userapi.com/c855020/v855020551/59a81/phM3k4nXcrg.jpg'
];
function makeCheck(image) {
return function() {
if (image.complete && image.naturalWidth) {
console.log("картинка загрузилась ОК!");
} else {
console.error("Нет такой картинки: " + image.src);
}
}
}
for(let i = 0;i < srcs.length; i++) {
const src = srcs[i];
const image = new Image();
window.setTimeout( makeCheck(image), 300);
//image.src = "../img/designers/" + index + '.' + id + ".jpg";
image.src = src;
}
indexOf()
в лоб. Костыль только для двух повторов, но, по идее, быстрее регулярок:function haz2ones(str) {
const s = str.toString();
const search = '1';
let i = s.indexOf(search);
if (!~i) return false;
i = s.indexOf(search, i + 1);
if (!i) return false;
if (!!~s.indexOf(search, i + 1)) return false;
return true;
}
const tests = [
[1, false],
[11, true],
[111, false],
['1', false],
['11', true],
['111', false],
['100001', true],
['000011', true],
[12345678901234567890, true],
];
return tests.map(e => haz2ones(e[0]) === e[1] ? '+' : '- ' + e[0]);
// +,+,+,+,+,+,+,+,+
$('.parent div:last-child').addClass('div2');
Замыкание — это комбинация функции и лексического окружения, в котором эта функция была определена.
A closure is the combination of a function and the lexical environment within which that function was declared.
function makeCounter() {
// далее ваш код:
let count = 0;
function counter() {
return count += 1;
}
// конец вашего кода.
return counter; // вернули Функцию (с её окружением)
}
var myCounter = makeCounter();
// вот теперь к значению count не добраться - приватность!
// зато
console.log(myCounter()); // 1
console.log(myCounter()); // 2
console.log(myCounter()); // 3