Skip to main content
10 分間のコミュニティアンケヌトにご協力ください。7 月 19 日たで回答を受け付けおおりたす。こちらをクリックするずご参加いただけたす。

オブゞェクト、クラス、プロトタむプの継承の操䜜

孊習の目的

この単元を完了するず、次のこずができるようになりたす。

  • オブゞェクトリテラル衚蚘ずコンストラクタヌを䜿甚しおオブゞェクトを䜜成する。
  • オブゞェクトにプロパティず関数を代入する。
  • JavaScript のオブゞェクト継承におけるプロトタむプの圹割を特定する。
  • JavaScript のクラス構文に぀いお説明する。
  • Lightning Web コンポヌネントにおける継承ずオブゞェクトリテラル衚蚘の圹割を説明する。

JavaScript ずいう蚀語を説明する方法はたくさんありたす。どのような定矩を遞ぶにしろ、JavaScript でオブゞェクトの抂念が重芁であるこずには誰もが同意するこずでしょう。JavaScript のオブゞェクトずそのしくみに察する理解が深たるほど、効率的な JavaScript を蚘述できるようになりたす。

始める前に、オブゞェクトに぀いおいく぀かの泚意事項がありたす。

  • オブゞェクトには、Apex、Java、C# の開発者が考えるようなクラスがありたせん。
  • どのオブゞェクトも別のオブゞェクトから継承したす。
  • オブゞェクトは倉曎可胜です。
  • オブゞェクトは䜜成時に独自の可倉コンテキストを取埗したす。

オブゞェクトの䜜成

構文の点から蚀えば、JavaScript ではオブゞェクトを数通りの方法で䜜成できたす。けれども、オブゞェクトをどのような方法で䜜成するにしろ、実際には Object.create() ずいう基盀ずなる API を抜象化するこずになりたす。 

堎合によっおは Object.create() を盎接䜿甚するこずが劥圓なこずもありたすが、ここでは説明したせん。その代わり、オブゞェクトを䜜成するより䞀般的な方法を芋おいきたす。

オブゞェクトリテラル衚蚘

1 ぀目のオブゞェクト䜜成構文は、オブゞェクトリテラル衚蚘ずいうものです。これは、オブゞェクトを䞀床にたずめお宣蚀しお代入する、シンプルな宣蚀型の方法です。オブゞェクトはその埌、同じステヌトメントの䞀郚ずしおただちに代入されたす。

const bike = {
  gears: 10,
  currentGear: 3,
  changeGear: function(direction, changeBy) {
    if (direction === 'up') {
      this.currentGear += changeBy;
    } else {
      this.currentGear -= changeBy;
    }
  }
}
console.log(bike.gears); // 10
console.log(bike.currentGear); //3
bike.changeGear('up', 1);
console.log(bike.currentGear); //4

オブゞェクトリテラル衚蚘は本質的に宣蚀型です。この䟋の bike オブゞェクトには、gears プロパティず currentGear プロパティず changeGear 関数ずいう 3 ぀のメンバヌがありたす。オブゞェクトが䜜成された埌でこれらのメンバヌを参照する堎合は、ドット衚蚘を䜿甚したす。

Note

JSON ずオブゞェクトリテラル衚蚘が互いによく䌌おいるこずに気付いたかもしれたせんが、同じではありたせん。JSON はデヌタ亀換圢匏です。オブゞェクトリテラル衚蚘はプログラミング構文です。ただし、JSON 仕様はオブゞェクトリテラル衚蚘に基づくため、䞡者を混同しがちです。

リテラルオブゞェクトは単発のオブゞェクトに適しおいたす。他方、同じ皮別のオブゞェクトを 2 ぀以䞊䜜成する堎合は、実甚的ではありたせん。この堎合は、新しいオブゞェクトを䜜成する、繰り返し可胜なロゞックが必芁です。

コンストラクタヌを䜿甚した新しいオブゞェクト

オブゞェクトを䜜成するもう 1 ぀の方法はコンストラクタヌを䜿甚するこずです。コンストラクタヌずは、オブゞェクトを䜜成しお代入するずきにそのプロパティを蚭定するための説明を含む関数です。この方法では、同じプロパティのオブゞェクトのむンスタンスを倚数䜜成できるずいう点で、オブゞェクトリテラルよりも䟿利です。

function Bike(gears, startGear) {
  this.gears = gears;
  this.currentGear = startGear;
}
Bike.prototype.changeGear = function(direction,changeBy){
  if(direction === 'up') {
    this.currentGear += changeBy;
  } else {
    this.currentGear -= changeBy;
  }
}
const bike = new Bike(10, 3);
console.log(bike.gears); // 10
console.log(bike.currentGear); //3
bike.changeGear('up', 1);
console.log(bike.currentGear); //4

この䟋で Bike は、オブゞェクトを定矩する通垞の JavaScript 関数です。ここでは JavaScript のルヌルに埓っお、この関数がコンストラクタヌであるこずを知らせるために最初の文字を倧文字にしおいたす。この new キヌワヌドは極めお重芁です。new がなければ、this ポむンタヌが意図するオブゞェクトをポむントせず、予期しない動䜜が生じたす。this ぀いおは、埌の単元のコンテキストの説明でもう䞀床取り䞊げたす。

changeGear 関数の代入は、prototype ずいうものを䜿甚しお行われたす。この方法では、関数が䞀床定矩されるず、このコンストラクタヌで䜜成されたすべおのむンスタンスに確実に共有されたす。プロトタむプの䜿甚ず継承に぀いおは、この単元の埌半で説明したす。

構文の点では、オブゞェクトリテラル衚蚘ずコンストラクタヌはかなり異なりたすが、 どちらの堎合も、新しいオブゞェクトがメモリに䜜成され、bike 倉数がそのオブゞェクトぞのポむンタヌになりたす。コンストラクタヌを䜿甚するず、同じプロパティず関数が蚭定された Bike オブゞェクトをたくさん䜜成できたす。

オブゞェクトぞのプロパティず関数の代入

䞊蚘の bike の䟋から、オブゞェクトにはプロパティず関数ずいう 2 皮類のメンバヌがあるのではないかず掚枬した方、正解です。 

プロパティには次の 3 ぀の基本的な圢態がありたす。

  • プリミティブ
  • オブゞェクト
  • 配列

このモゞュヌルを䜜成した時点で、JavaScript には、文字列、数倀、Boolean、null、undefined、蚘号、BIGINT の 7 ぀のプリミティブ型がありたす。プリミティブ型は倉曎できたせん。倉数がプリミティブ型の堎合は、代入時に倀によっお倉数が枡されたす。぀たり、プリミティブが代入されるたびに、倀のコピヌが䜜成され、新しい倉数に代入されたす。 

Note

今埌、新しいプリミティブ型が远加される可胜性は非垞に高いず思われたす。JavaScript コミュニティでは新しいニヌズやナヌスケヌスがあるこずを認め、蚀語を拡匵するための提案が出されおいたす。採甚されれば、このような根本的な倉曎に぀ながりたす。

JavaScript でプリミティブに該圓しないものはほがすべおオブゞェクトです。オブゞェクトリテラル衚蚘では、オブゞェクトのプロパティが䞭括匧で囲たれたす。

配列自䜓も JavaScript ではオブゞェクトずしお実装されたす。配列は、Array() コンストラクタヌ関数、たたは角括匧で囲たれたリテラル衚蚘を䜿甚しお䜜成できたす。

関数に぀いおは、このモゞュヌルに独自の単元があるため、ここでは説明したせんが、䞊蚘を基にもう䞀床オブゞェクトリテラル衚蚘を䜿甚しおさらに耇雑な bike オブゞェクトを定矩しおみたしょう。

const bike = {
  frontGearIndex: 0,
  rearGearIndex: 0,
  transmission: {
    frontGearTeeth: [30,45],
    rearGearTeeth: [11,13,15,17,19,21,24,28,32,36]
  },
  calculateGearRatio: function() {
    let front = this.transmission.frontGearTeeth[this.frontGearIndex],
        rear = this.transmission.rearGearTeeth[this.rearGearIndex];
    return (front / rear);
  },
  changeGear: function(frontOrRear, newValue) {
    if (frontOrRear === 'front') {
      this.frontGearIndex = newValue;
    } else {
      this.rearGearIndex = newValue;
    }
  }
};

括匧構文によるプロパティの参照

オブゞェクトメンバヌの参照は、通垞ドット衚蚘を䜿甚しお行いたす。たずえば、前の䟋では、オブゞェクトのプロパティず関数を次のように参照したす。

bike.frontGearIndex
bike.transmission.frontGearTeeth
bike.calculateGearRatio()

ドット衚蚘では、プロパティの名前に厳密なルヌルがありたす。けれども JavaScript では、括匧衚蚘ずいう別の構文も䜿甚できたす。括匧衚蚘では䞊蚘のメンバヌが次のように参照されたす。

bike["frontGearIndex"]
bike["transmission"]["frontGearTeeth"]
bike["calculateGearRatio"]()

括匧衚蚘のほうが入力する文字数が倚いものの、2 ぀の利点がありたす。プロパティや関数に任意の名前を付けるこずができたす。そしお、文字列であるため、倉数を介しおプロパティや関数の名前を枡しおコヌルできたす。

では、changeGear 関数を再考し、この方法ではどのように機胜するのか芋おみたしょう。ここでは、フロントギアずリアギアの䞊䞋のシフトを定矩する 4 ぀の関数を䜿甚したす。changeGear 関数で、文字列パラメヌタヌに基づいおコヌルする関数の名前を構築し、その名前をコヌルしたす。

changeGear: function(frontOrRear, upOrDown) {
  let shiftFunction = frontOrRear + upOrDown;
  this[shiftFunction]();
},
frontUp: function(){
  this.frontGearIndex += 1;
},
frontDown: function(){
  this.frontGearIndex -= 1;
},
rearUp: function(){
  this.rearGearIndex += 1;
},
rearDown: function(){
  this.rearGearIndex -= 1;
}

これらの名前を bike オブゞェクトに远加するず、どのように機胜するのかを確認できたす。

console.log(bike.calculateGearRatio()); // 2.727272727
//Calls the frontUp() function
bike.changeGear("front", "Up");
console.log(bike.calculateGearRatio()); // 4.090909091
//calls the rearUp() function
bike.changeGear("rear", "Up");
console.log(bike.calculateGearRatio()); // 3.461538461

オブゞェクトの倉曎可胜性

オブゞェクトを定矩する各皮の構文のほか、JavaScript のオブゞェクトにはもう 1 ぀重芁な原則がありたす。倉曎可胜性です。

JavaScript のオブゞェクトは倉曎可胜で、オブゞェクトの圢態を倉えたければ倉曎できるこずを意味したす。

䜜成した bike オブゞェクトを芋おみたしょう。たずえば、新しいプロパティや関数を远加するこずができたす。

bike.isTandem = true;
bike.popAWheelie = function() {


};

オブゞェクトが最初に定矩されたコヌドにアクセスできなくおも、オブゞェクトがメモリに入れられた埌でその圢態を倉曎できたす。ここで重芁な点は、オブゞェクトの 1 ぀のむンスタンスのみが倉曎されるこずです。では、もう䞀床 Bike コンストラクタヌを芋おみたしょう。

const bike1 = new Bike();
const bike2 = new Bike();
bike1.isTandem = true;
console.log(bike1.isTandem); // true
console.log(bike2.isTandem); // undefined

いく぀かのオブゞェクトでプロパティたたはメ゜ッドを共有したい堎合は、継承モデルを䜿甚したす。詳しく芋おみたしょう。

オブゞェクトず継承

JavaScript には埓来の蚀語で定矩されおいたようなクラスはありたせんが、プロトタむプ継承ずいう継承モデルがありたす。

プロトタむプは、実際のずころもう 1 ぀のオブゞェクトです。これはメモリ内に存圚し、他のオブゞェクトが同じプロトタむプを共有する堎合に継承するプロパティや関数を定矩したす。

JavaScript では埓来、オブゞェクトが同じコンストラクタヌ関数を共有するずいうやり方で、同じプロトタむプを共有したす。Bike コンストラクタヌを思い出しおください。changeGear 関数を prototype ずいうものに代入したす。

function Bike(gears, startGear) {
  this.gears = gears;
  this.currentGear = startGear;
}
Bike.prototype.changeGear = function(direction, changeBy) {
  if (direction === 'up') {
    this.currentGear += changeBy;
  } else {
    this.currentGear -= changeBy;
  }
}

こうすれば、Bike から䜜成される各オブゞェクトが changeGear 関数を継承したす。

プロトタむプには、耇数レベルの継承を実装でき、 プロトタむプチェヌンずしお参照されたす。コンストラクタヌ関数を䜿甚したプロトタむプチェヌンの実装は耇雑で、盞圓量の定型コヌドが必芁です。この点も圓モゞュヌルの範疇を超えおいたす。ここで知っおおくべきこずは、プロトタむプチェヌンの耇雑さに察凊するために、ECMA が、継承を実装するより端的な構文、぀たり class 構文に関する暙準を導入しおいるずいうこずです。

クラスず JavaScript

「クラス」ずいう単語を読んで安堵感を芚え、真のクラスベヌスの継承を䜜成するものを芋おいくのかなず思った方は、萜胆するこずになるでしょう。JavaScript の class ずいうキヌワヌドは、コンストラクタヌ関数を䜿甚しおプロトタむプ継承の耇雑性に察凊する糖衣構文のようなものです。䞊蟺の糖衣の䞋では、この堎合も゚ンゞンが Object.create を䜿甚し、(オブゞェクト指向ずいう意味での) クラスはありたせん。メモリ内にプロトタむプオブゞェクトがあるだけで、実際はこれが継承元になりたす。

幞いにも、JavaScript 固有の事項をいく぀か考慮する必芁はあるものの、芋た目は Java や C# のコヌドによく䌌おいたす。

Note

Lightning Web コンポヌネントで class 構文を含む耇数レベルのプロトタむプチェヌンを䜿甚したすが、このモゞュヌルの説明の範疇を超えおいたす。JavaScript オブゞェクトの最新機胜の操䜜に぀いおの詳现は、この単元の末尟の「リ゜ヌス」にあるリンクを参照しおください。このトレむルの「Modern JavaScript Development (JavaScript の最新機胜)」ずいう別のモゞュヌルを受講するこずを匷くお勧めしたす。同モゞュヌルでは 1 ぀の単元を䞞々クラスの説明に費やしおいたす。

ここでは JavaScript クラスに぀いお詳述したせんが、埌孊のために class 構文を䜿甚しお bike オブゞェクトを実装したバヌゞョンを確認しおおくずよいでしょう。

class Bike {
    constructor(gears, startGear){
        this.gears = gears;
        this.currentGear = startGear;
    }
    changeGear(direction, changeBy) {
        if (direction === 'up') {
            this.currentGear += changeBy;
        } else {
            this.currentGear -= changeBy;
        }
    }
}
const bike = new Bike(10, 5);
console.log(bike.currentGear); // 5
bike.changeGear('up', 2);
console.log(bike.currentGear); // 7

ご芧のずおり、この構文は Java や Apex のクラスずよく䌌おいたす。明確な違いは、コンストラクタヌ関数に垞に constructor ずいう名前が付けられおいるこずです。重芁な特城は、Object.prototype を盎接参照しなくおも、関数や属性が自動的にプロトタむプチェヌンに属するこずです。このため、耇数レベルのプロトタむプ継承を簡単に䜜成できたす。

Lightning Web コンポヌネントずオブゞェクト

これたでに説明した数皮の構文やプロトタむプチェヌンなど、この単元の内容のいく぀かは Lightning Web コンポヌネントの開発に関連しおいたす。

クラスず Lightning Web コンポヌネント

Lightning Web コンポヌネントは、JavaScript の倚数の最新機胜を掻甚しおおり、その代衚䟋が class 構文の䜿甚です。コンポヌネントは通垞、LightningElement ずいう別のクラスを拡匵する JavaScript クラスによっお定矩されたす。次のようになりたす。

import { LightningElement } from lwc;
export default class MyComponent extends LightningElement {
    myProperty;
    myFunction() {
        console.log(this.myProperty);
    }
} 

Lightning Web コンポヌネントの機胜は、JavaScript クラスで定矩されたす。この䟋では、モゞュヌル (import ず export) に関しおただ説明しおいない䞀郚の構文も䜿甚しおいたす。

オブゞェクトリテラル

このモゞュヌルのいく぀かの䟋では、オブゞェクトがどのように機胜するかを孊習する目的で、オブゞェクトリテラル内で関数を宣蚀しおいたす。このやり方は、最新の JavaScript で掚奚される実践法ではありたせん。オブゞェクトリテラルは、JavaScript プログラムの機胜郚分間でデヌタを枡すアドホックデヌタ構造を䜜成する優れた方法ですが、オブゞェクトリテラルで関数を定矩するこずは回避したす。

リ゜ヌス

Salesforce ヘルプで Trailhead のフィヌドバックを共有しおください。

Trailhead に぀いおの感想をお聞かせください。[Salesforce ヘルプ] サむトから新しいフィヌドバックフォヌムにい぀でもアクセスできるようになりたした。

詳现はこちら フィヌドバックの共有に進む