Почему js залезает в if если он этого не должен делать?
Читать про let и temporal dead zone. 
Если совсем по простому, то нельзя использовать переменную раньше чем она определена с помощью let/const.
Вам надо либо определить timerId раньше, либо использовать var
timer(v){
    let func = v,
        timerId = null;
    if (timerId) {
      clearInterval(timerId);
    }   
    timerId = setInterval(function tick() {
        func();
    }, 500);
}
Потому что temporal dead zone