Неверно деобфусцировал код

310
26 июня 2017, 21:23

Как-то раз, давным-давно я захотел минифицировать свой JS-код, но случайно зашёл на сайт, который помимо минификации ещё и обфусцирует его. Я это заметил не сразу, а лишь спустя, ибо торопился поскорее закончить работу. Теперь я решил этот код вручную деобфусцировать, но сломал при этом функционал. Суть в том, что при клике на инпут появлялось выпадающее меню, а если кликнуть где-то в другое место, то оно скрывалось. Я переписал этот код на читаемый, но при этом сломался тот самый функционал, отвечающий за закрытие выпадающего меню. Почему это произошло? Ведь я в точности переписал код.

Новый код:

$(() => {
    let dropdown = $('.passengers-main-dropdown');
    dropdown.on('click', function(){
        $(this).toggleClass('active');
        $(this).nextAll('.dropdown-box').toggleClass('active');
    });
    $('body').on('click', function(e){
        let drop = $('.dropdown-box');
        console.log(`${dropdown.is(e.target)} + ${dropdown.has(e.target).length !== 0} + ${drop.has(e.target).length !== 0)}`)
        if(dropdown.is(e.target) && dropdown.has(e.target).length !== 0 && drop.has(e.target).length !== 0) {
            drop.removeClass('active');
            dropdown.removeClass('active');
        }
    })
});

Старый (обфусцированный) код:

$(function() {
    var t = $(".passengers-main-dropdown");
    t.on("click", function() {
        t.nextAll(".dropdown-box").toggleClass("active"), t.toggleClass("active")
    }), $("body").on("click", function(o) {
        var i = $(".dropdown-box");
        t.is(o.target) || 0 !== t.has(o.target).length || 0 !== $(i).has(o.target).length || (i.removeClass("active"), t.removeClass("active"))
    })
})

Проблема, скорее всего, в этой строке: t.is(o.target) || 0 !== t.has(o.target).length || 0 !== $(i).has(o.target).length || (i.removeClass("active"), t.removeClass("active"))

У меня она переписана, как:

if(dropdown.is(e.target) && dropdown.has(e.target).length !== 0 && drop.has(e.target).length !== 0) { drop.removeClass('active'); dropdown.removeClass('active'); }

Несмотря на то, что в обфусцированном варианте кода используется оператор ||(или), переписанный код с этим оператором не работает вовсе. С оператором &&(и) выпадающий список работает, однако, почему-то не скрывается по клику вне. Помогите, пожалуйста, разобраться, где я допустил ошибку.

Answer 1

Данная строка кода:

t.is(o.target) || 0 !== t.has(o.target).length || 0 !== $(i).has(o.target).length || (i.removeClass("active"), t.removeClass("active"))

имеет вид:

a || b || c || d

JavaScript вычисляет несколько ИЛИ слева направо. При этом, чтобы экономить ресурсы, используется так называемый «короткий цикл вычисления».

Если выражение a вернет true, то вычислять выражения b, c, d не имеет смысла. Очевидно, выражение d вычислится только тогда, когда выражения a, b и c вернут false.

if (a == false && b == false && c == false) {
  d
}

Преобразованный код для вашей задачи:

if (!dropdown.is(e.target) && dropdown.has(e.target).length === 0 && $(drop).has(e.target).length === 0) {
  drop.removeClass("active");
  dropdown.removeClass("active")
}
READ ALSO
Не работает IndexOf

Не работает IndexOf

Здравствуйте! Есть данный участок кода:

426
Отправка формы при помощи JS?

Отправка формы при помощи JS?

Добрый день, хочу поинтересоваться, кто-то делал отправку писем через гугл таблицы? Те, проворачивал ли, кто-то вот такую схему "сайт -> гугл...

273
HTML5 + EME + VIDEO

HTML5 + EME + VIDEO

Нужно проигрывать видео зашифрованное симметричным ключомПри этом скопировать видео нельзя и ключ тоже

248
Изменить высоту грида

Изменить высоту грида

У меня проблема с канвасом html5У меня есть датасэт для заполнения графика в канвасе по данным из базы

185