プログラミングの理解が遅すぎる初心者がJavaScript、Node.jsで投票型掲示板を作ろうとしてます

トップページでは記事の順番がごちゃごちゃなので、記事もくじをご覧いただければと思います。

JavaScriptの常識③this

今回は③thisです。

なんかわかりそうでわかってなさそうでわかってるような気がするけど、という微妙な理解だったので、ここで確実に理解しておきたいと思います。

thisの基本

thisとは、もうそのまんま「こいつ」って感じです。

オブジェクトを指定してる中で使った場合、そのオブジェクトを指して「こいつです」というイメージ。

例えば

const character = {
  name: "フリーザ",
  power: 530000,
  speak: function () {
    console.log(this.name + "の戦闘力は" + this.power + "です");
  }
};

という場合。

thisを使わなかったらこんな感じになります。

const character = {
  name: "フリーザ",
  power: 530000,
  speak: function () {
    console.log(character .name + "の戦闘力は" + character .power + "です");
  }
};

けどこれ、いちいちcharacterって書くのは面倒だし、「上ですでにcharacterって言ってるんだから、それを指してるってわかればいいだろ」ってことで、thisを使ってラクをしてるってことです。

フリーザが三回目の変身を完了した」という文があったとき、ふつうは「その直後、フリーザはデンデを撃った」というように名前を繰り返すのではなく「彼はデンデを撃った」と代名詞を使いますよね。 こんなイメージです。

しかしこの場合は「彼=フリーザ」であることが明らかだから代名詞に置き換えられています。

これが誰なのかがわからなかったら成り立ちません。

それはコードの中でも同じでthisがどれを指しているのかがわからなければ意味を成しません。

結論からいうと、thisの対象が明らかにされるという範囲は{から}までの中です。

これをオブジェクトリテラルといいます。

このオブジェクトリテラルから出た場合、thisの内容は変わってしまいます。

上の例でいうとオブジェクトリテラルの範囲は以下の通り。

const character = { //ここから
  
};//ここまで

この中this.nameなどのメソッドがあったら、それはcharacterを指すことになります。

オブジェクトリテラルの外にあるthis

じゃあオブジェクトリテラルを出たときにthisと書いてしまったらどうなるのかというと、この場合のthiswindowを指すことになります。

一応説明しておくと、windowというのは、普段省略されているオブジェクトです。

console.log(this);

とか

alert();

というメソッドは、windowが省略されたものです。 本来の書き方は

window.console.log(this);

window.alert();

ということになります。

なのでthisも、どのオブジェクトリテラルにも属していないときはwindowになります。

※これはあくまでフロントエンド、つまりHTMLを操作するときの話です。

Node.jsではHTMLではなくAPIを操作することになるので、windowではなくglobalになります。

windowglobalは操作する対象は違いますが、ここでは立ち位置は同じものと考えて問題ないです。

アロー関数のthis

アロー関数ではthisの範囲は少し特殊になります。 例えば以下のようなコード。

const saiyan = {
  name: "悟空",

  // アロー関数
  arrowFunction: () => {
    console.log("おっすオラ", this.name);
  }
};

さきほど言ったようにthisが示す範囲ががオブジェクトリテラルの範囲であるならば、アロー関数のものでは

 {
    console.log("おっすオラ", this.name);
  }

とならなくてはなりません。

しかしアロー関数の中にはthisの対象となるオブジェクトは存在しません。

なのでアロー関数の場合のみ、例外として一つ外のオブジェクトリテラルthisが使える範囲になります。

もし

  arrowFunction: () => {
    console.log("おっす、オラ", this.name); //定義されていない

のように、どのアロー関数内のスコープの一つ外のオブジェクトがどこにも属さない場合、先ほどと同じようにobjectwindowということになります。

以上をまとめます。

  • オブジェクトの定義内でのthisは、定義しているオブジェクトを指す

  • thisの範囲はスコープ内に限られる

  • スコープに属しないthiswindow(node.jsではglobal)になる

  • アロー関数内ではthis、は一つ外のオブジェクト(今回ではwindow)を指す

本当は「どこでどう呼ばれたか」とかも定義に含まれるのですが、今のところはthisに関してはこれくらい理解しておけばよいかと思います。

「どこで」はともかく「どう呼ばれたか」とか、今考えるとややこしくなりそうなので。

Image