最終更新日: 2026-07-24
TOP(About this memo)) > 一覧(JavaScript) > this・プロトタイプ・class
thisはJavaやC++のthisとは全く挙動が異なる。thisは、ある関数が呼び出された際に、その関数を格納していたオブジェクトを指す。var sayHelloShared = function() {
console.log("Hello, I'm " + this.name);
};
var alice = {
sayHello: sayHelloShared,
name: 'Alice'
};
var bob = {
sayHello: sayHelloShared,
name: 'Bob',
child: alice
};
alice.sayHello(); // Hello, I'm Alice
bob.sayHello(); // Hello, I'm Bob
// 以下の方法も可能
sayHelloShared.call(alice); // Hello, I'm Alice
sayHelloShared.call(bob); // Hello, I'm Bob
thisの挙動については、以下の記事の後半も参考になる。
newもJavaやC++でクラスのインスタンス化を行うnewとは動きが異なる。newと一緒に関数を呼び出すと、まず新しい空のオブジェクト({})が生成される。次に関数が呼び出されるが、その際に関数内のthisが生成されたオブジェクトを指すようになる。関数が実行された後、生成されたオブジェクトがnewの実行結果として返される。var Person = function(name, age) {
this.name = name;
this.age = age;
};
var alice = new Person('Alice', 7);
console.log(alice.name); // Alice
console.log(alice.age); // 7
var Person = function(name, age) {
// var this = {}; を実行
this.name = name;
this.age = age;
// return this; を実行
};
Personに以下のようにreturnをつけても意図通り動作する(returnも上書きされる)。var Person = function(name, age) {
this.name = name;
this.age = age;
return name;
};
new演算子を使うことで、JavaScriptでは関数を「コンストラクタ」として利用できる。実際、newで生成されたオブジェクトはconstructorというプロパティで生成時に利用された関数への参照を保持している。console.log(alice.constructor == Person); // true
aliceオブジェクトの構造は概念的には以下のようなイメージになる。
[[Prototype]]: { constructor: Person }という形になっている。var alice = {
constructor: Person,
name: 'Alice',
age: 7
}
prototype
constructorプロパティのみを持つ。このプロパティは関数自身を参照する。[[Prototype]]
Object.getPrototypeOf()を使う。constructorプロパティを持ち、そのプロパティはnewした際にひな形になった関数オブジェクトへの参照になっている。[[Prototype]]を「オブジェクト.[[Prototype]]」と表記する。newする。function Animal() {
this.cry = "meow";
}
Animal.prototype.shout = function() { // 関数が持つプロトタイプは直接参照できる
alert(this.cry);
}
var animal = new Animal();
animal.shout(); // -> "meow"
function Bird() {
this.cry = "sing";
}
Bird.prototype = Object.create(Animal.prototype); // 継承
var niwatori = new Bird();
niwatori.shout(); // -> "sing"
niwatoriオブジェクトは概念的には以下のようなイメージになる。var niwatori = {
[[Prototype]]: {
constructor: Birdへの参照
},
cry: "sing"
}
niwatori.shout() → niwatoriのメンバにはshoutが存在しないniwatoriを生成したBirdを見に行く(niwatori.[[Prototype]]のBirdへの参照から見に行く)Bird.prototypeを生成したAnimal.prototypeを見に行く(Bird.prototype.constructorを見に行く)Animal.prototypeを見るとshoutを持っているfunction Animal() {
this.cry = "meow";
this.shout = function() {
alert(this.cry);
};
}
var animal = new Animal();
animal.shout(); // -> "meow"
* この書き方の場合、暗黙的に以下の実行になっているため、`new`のたびに新しい関数オブジェクトが生成されてしまう(プロトタイプの場合は実行時にプロトタイプチェーンで探しにいくため再利用できる)。
function Animal() {
// var this = {}; を実行
this.cry = "meow";
this.shout = function() {
alert(this.cry);
};
// return this; を実行
}
var Person = function(name) {
this.name = name;
};
Person.prototype.sayHello = function() {
console.log("Hello, I'm " + this.getName());
};
Person.prototype.getName = function() {
return this.name;
};
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
console.log("Hello, I'm " + this.getName());
}
getName() {
return this.name;
}
}
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
console.log("Hello, I'm " + this.getName());
}
getName() {
return this.name;
}
}
// Personを継承
// 同じメソッド名であるsayHelloは継承先のもので上書きされる
class Teacher extends Person {
sayHello() {
console.log("Hi, I'm " + this.getName());
}
}
const teacher = new Teacher('soarflat');
teacher.sayHello(); // => Hi, I'm soarflat
thisを参照したい場合、以下のようにlet re_this = thisのような形で退避しないと参照できないことがある。this.xxxx = tokenのように直接書くとundefinedになる。data() {
return {
token: ""
}
},
mounted() {
let re_this = this
grecaptcha.ready(function() {
grecaptcha.execute('サイトキー').then(function(token) {
re_this.token = token
});
});
}
thisはオブジェクト型(プリミティブではない)であるためre_thisには参照が渡される。その結果、re_this.token = tokenによって参照先を更新できる。thisはwindowオブジェクトになってしまうことがある。
functionの短縮記法であれば参照できる。さらにコールバック関数側をアロー関数にすると参照できる、という分かりづらい仕様になっている。$は単なる変数名として使える記号。$を関数として使っている。jQueryの$はユーティリティ的ないくつかのプロパティやメソッドを持つ。$を関数として呼び出す($("セレクタ")など)とjQueryオブジェクトを返す。prototypeプロパティは$.fnである。つまりjQueryオブジェクトは$.fnを継承しているため、$.fn.Hogeメソッドを作れば、すべてのjQueryオブジェクトにHogeメソッドができる。
$.fnを拡張することでjQueryオブジェクトを拡張できる。// bullyを作ってしまえば、全てのjQueryオブジェクトについてbullyが使える
$.fn.bully = function() { /* ... */ }
$('#' + id).bully();
let sc_sel_val = $('label.sc_radio_label > input:radio:checked').val();