PUROGU LADESU

ポエムがメインのブログです。

Javascriptの落とし穴2

配列の初期化

配列の宣言のときArrayオブジェクトをnewしてはいけません。バグのもとです。
リテラル[]で初期化します。
わざわざnewしなくても同じことができます。

let bad = new Array(11, 22, 33);
let good = [1, 22, 33];

配列のコピー

スプレッド構文、concat、sliceなどはシャローコピーとなります。
配列内にのオブジェクトがあった場合はコピー元とコピー先の変更は互いに影響する。
変更ではなく代入して入れ替えるのは影響しない。

ディープコピーは頑張って自分で再帰的に取り出して入れ直す必要があります。

let ary6 = new Array(5, 6, [7]);
let ary4 = ary6.concat(); // 結合、引数なしでコピー
let ary5 = [...ary6]; // スプレッドして再配列化するとコピー
ary6[1] = "xxx"; // 代入は影響を受けないが
ary6[2].push(9); // オブジェクトは参照を共有
console.log(ary6, ary5);

配列のソート

配列のsortは値が数字でも文字列順に並ぶゴミ仕様。
ソートの比較処理を作ってあげる必要があります。

let arysrt = [10, 5, 25];
console.log(arysrt.sort());
arysrt.sort(function (x, y) {
  return x - y;
});

オブジェクトリテラルのソート

ソートしたい列を比較する処理を作成して配列を返します。

let classes = ["部長", "課長", "係長", "主任"];
let members = [
  { name: "toyota", class: "係長" },
  { name: "honda", class: "部長" },
  { name: "kawasaki", class: "主任" },
  { name: "suzuki", class: "課長" },
  { name: "nissan", class: "主任" },
];
let mbsorted = members.sort(function (x, y) {
  return classes.indexOf(x.class) - classes.indexOf(y.class);
});
console.log(mbsorted);

Dateを文字列から生成

文字列から作成する場合はYYYY-MM-DDTHH:mm:ss.sssZにしないと挙動が不安定となります。
ハイフン区切りの日付はUTCになりますが、スラッシュ区切りだとローカルになります。

let dt = new Date(2020, 1, 13, 23, 15, 45);
let date1 = new Date("2021-11-01"); // utc
let date2 = new Date("2021/11/01"); // local
console.log(date1.toUTCString());
console.log(date2.toUTCString());

Dateの月の指定

月は0-11を指定、日付に0で前の月の最終日

let dt2 = new Date(2000, 0, 1); // 0で1月になる

Dateのフォーマット

strftimeとかformatみたいなものは無いクソ仕様のようです。
getXXXを使って自作します。

let fmtdate = `${dt1.getMonth() + 1}/${dt1.getDay()}`;

Dateの計算

getしたものを足し算引き算してsetします。
ちゃんと月をまたいでも考慮されます。

date1.setDate(date1.getDate() - 5); // 5日戻す

Dateの間隔を計算

ミリ秒を取得して割り算します。
1000 * 60 * 60 * 24で一日になります。

let dt3 = new Date(2022, 1, 5);
let dt4 = new Date(2022, 1, 10);
console.log(dt3.getTime()); // ミリ秒を取得
let diff34 = (dt4.getTime() - dt3.getTime()) / (1000 * 60 * 60 * 24);
console.log(diff34);