テキストフィールドのテキストが編集されたら(保存が必要であると示すため)文字色を変更するコードを次のように書きました。

let textinput = document.getElementById("textinput");
textinput.oldValue = textinput.value;
textinput.isChanged = false;
Object.defineProperty(textinput, "changed", {
  set: function(changed) {
    this.isChanged = changed;
    this.style.color = (changed ? "#c88" : null);
  }
});

textinput.addEventListener("input", function(anEvent) {
  let textinput = anEvent.target;
  let changed = (textinput.value != textinput.oldValue);
  textinput.changed = changed;
});
#textinput {
  color: #000;
}
<html>
  <body>
    <input id="textinput" type="text" value="Initial Text" />
  </body>
</html>

これは期待通り動作します。入力中のテキストが初期テキストと異なれば文字色は薄い赤色になります。

ただ、コードの記述は次のように改善したいです。


追加のプロパティは役割をネーミングしたプロパティの子にしたい

現在、

let textinput = document.getElementById("textinput");
textinput.oldValue = textinput.value;
textinput.isChanged = false;
...

とあるように、元のオブジェクトに直接新しいプロパティを追加しています。これらは編集状態のために加えたので、次のようにeditingというプロパティの子にまとめたいです。

let textinput = document.getElementById("textinput");
textinput.editing = {
  oldValue: textinput.value,
  isChanged: false
};
...

ここで、セッタchangedの処理に問題が出ます。

Object.defineProperty(textinput.editing, "changed", {
  set: function(changed) {
    this.isChanged = changed;
    // this.style.color = (changed ? "#c88" : null);
  }
});

セッタ関数の内部でthistextinput.editingを指すようになったため、textinput.styleにアクセスできなくなりました。 このセッタ関数内からtextinput.styleにアクセスする方法はありませんか?