Почему не работает this внутри объекта?

Рейтинг: 0Ответов: 2Опубликовано: 18.04.2023

Написал когда то функцию по работе с временем, решил добавить новый параметр с ключом f

При обращении к этому параметру выводит undefined

Подскажите как можно решить эту проблему без вызова новых now.getDate() и тд?

function dateTime(mask = 'd.m.y h:i:s', time = false) {
    let month = {
        f: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
        s: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    };
    let now = time ? new Date(parseInt(time)) : new Date();

    let data = {
        d: now.getDate().toString(),
        D: ('0'+ now.getDate()).slice(-2),
        m: ('0'+ (now.getMonth() + 1)).slice(-2),
        M: (now.getMonth() + 1).toString(),
        n: month.s[now.getMonth()],
        N: month.f[now.getMonth()],
        Y: now.getFullYear().toString(),
        h: now.getHours().toString(),
        H: ('0'+ now.getHours()).slice(-2),
        i: ('0'+ now.getMinutes()).slice(-2),
        s: ('0'+ now.getSeconds()).slice(-2),
        f: this.h === '0' ? this.d +' '+ this.n : this.h +':'+ this.i,
    };

    return [...mask].reduce((res, el) => {
        return res += data[el] || el;
    }, '');
}

console.log( dateTime('f') );

Ответы

▲ 2Принят

В вашем случае this = window, так как у window нет полей d, n, h, i, то появляются undefined и получаются такие ошибки.

Можно просто переопределить или просто определить поле f сославшись на поля объекта data. Решение костыльное, но довольно простое и рабочее. Обращаемся к полям, которые уже заданы.

function dateTime(mask = 'd.m.y h:i:s', time = false) {
  let month = {
    f: [
      'January',
      'February',
      'March',
      'April',
      'May',
      'June',
      'July',
      'August',
      'September',
      'October',
      'November',
      'December',
    ],
    s: [
      'Jan',
      'Feb',
      'Mar',
      'Apr',
      'May',
      'Jun',
      'Jul',
      'Aug',
      'Sep',
      'Oct',
      'Nov',
      'Dec',
    ],
  };
  let now = time ? new Date(parseInt(time)) : new Date();

  let data = {
    d: now.getDate().toString(),
    D: ('0' + now.getDate()).slice(-2),
    m: ('0' + (now.getMonth() + 1)).slice(-2),
    M: (now.getMonth() + 1).toString(),
    n: month.s[now.getMonth()],
    N: month.f[now.getMonth()],
    Y: now.getFullYear().toString(),
    h: now.getHours().toString(),
    H: ('0' + now.getHours()).slice(-2),
    i: ('0' + now.getMinutes()).slice(-2),
    s: ('0' + now.getSeconds()).slice(-2),
  };

  data.f = data.h === '0' ? data.d + ' ' + data.n : data.h + ':' + data.i;

  return [...mask].reduce((res, el) => {
    return (res += data[el] || el);
  }, '');
}

console.log(dateTime('f'));

▲ 1

Почему не работает this внутри объекта?

Так смотря как его использовать... Как вариант применить геттер или "вычисляемое свойство".

let month = {
    f: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
    s: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
};
let now = new Date();
let data = {
  d: now.getDate().toString(),
  D: ('0' + now.getDate()).slice(-2),
  m: ('0' + (now.getMonth() + 1)).slice(-2),
  M: (now.getMonth() + 1).toString(),
  n: month.s[now.getMonth()],
  N: month.f[now.getMonth()],
  Y: now.getFullYear().toString(),
  h: now.getHours().toString(),
  H: ('0' + now.getHours()).slice(-2),
  i: ('0' + now.getMinutes()).slice(-2),
  s: ('0' + now.getSeconds()).slice(-2),
  get f(){
    return this.h === '0' ? this.d + ' ' + this.n : this.h + ':' + this.i
  }
};
console.log(data.f)