JavaScriptガイドパート3:変数、データ型、式、オブジェクト

今日、JavaScriptマニュアルの翻訳の第3部では、変数を宣言するさまざまな方法、データ型、式、およびオブジェクトを操作する機能について説明します。



パート1:最初のプログラム、言語機能、標準

パート2:コードスタイルとプログラム構造

パート3:変数、データ型、式、オブジェクト

パート4:機能

パート5:配列とループ

パート6:例外、セミコロン、ワイルドカードリテラル

パート7:厳格モード、このキーワード、イベント、モジュール、数学計算

パート8:ES6機能の概要

パート9:ES7、ES8、およびES9標準の概要







変数



変数は、値が割り当てられる識別子です。 変数はプログラムでアクセスでき、割り当てられた値を使用してこの方法で動作します。



JavaScript自体の変数には、格納される値のタイプに関する情報は含まれません。 これは、文字列などの変数に書き込むことで、後で数値を書き込むことができることを意味します。 このような操作は、プログラムでエラーを引き起こしません。 そのため、JavaScriptは「型なし」言語と呼ばれることもあります。



変数を使用する前に、 var



またはlet



キーワードを使用して変数を宣言する必要があります。 定数になると、 const



キーワードが使用されます。 これらのキーワードを使用せずに変数を宣言して特定の値を割り当てることは可能ですが、そうすることはお勧めしません。



▍キーワードvar



ES2015標準の前は、 var



キーワードを使用することが変数を宣言する唯一の方法でした。



 var a = 0
      
      





この構成でvar



省略された場合、値は宣言されていない変数に割り当てられます。 この操作の結果は、プログラムが実行されているモードによって異なります。



そのため、いわゆるストリクトモードが有効になっていると、エラーが発生します。 厳格モードが有効になっていない場合は、暗黙的な変数宣言が発生し、グローバルオブジェクトに割り当てられます。 特に、これは、特定の関数でこのように暗黙的に宣言された変数が、その関数が作業を完了した後でも利用できることを意味します。 通常、関数で宣言された変数は制限を超えないことが期待されます。 次のようになります。



 function notVar() { bNotVar = 1 //    } notVar() console.log(bNotVar)
      
      





コンソールに1



取得します。通常、プログラムからこの動作を期待する人はいません。式bNotVar = 1



は、変数を宣言および初期化しようとするようには見えませんが、関数のbNotVar = 1



外部のbNotVar = 1



ある変数にアクセスしようとするように見えます(これは非常に正常です)。 その結果、変数の暗黙的な宣言は、コードを読み取る人を混乱させ、予期しないプログラムの動作を引き起こす可能性があります。 後で関数とスコープについて説明します。今のところ、式の意味が変数を宣言することである場合は、常に特殊なキーワードを使用するようにしてください。 この例で関数本体がvar bNotVar = 1



として書き換えられた場合、上記のコードフラグメントを開始しようとするとエラーメッセージが表示されます(ブラウザコンソールで確認できます)。



たとえば、次のようになりUncaught ReferenceError: bNotVar is not defined



。 その意味は、プログラムが存在しない変数で動作できないという事実に要約されます。 このようなエラーメッセージを表示するのは、プログラムを最初に起動するときに、予期しない動作をする可能性のある理解できないコードを記述するよりもはるかに優れています。



変数を宣言するときに初期化されず、値が割り当てられていない場合、値undefined



が自動的に割り当てられます。



 var a //typeof a === 'undefined'
      
      





var



キーワードを使用して宣言された変数は、新しい値を割り当てることで繰り返し宣言できます(ただし、コードを読む人を混乱させる可能性があります)。



 var a = 1 var a = 2
      
      





1つの式で複数の変数を宣言できます。



 var a = 1, b = 2
      
      





変数のスコープ(スコープ)は、この変数がアクセス可能な(表示される)プログラムの部分です。



関数の外部でvar



キーワードで初期化された変数は、グローバルオブジェクトに割り当てられます。 グローバルスコープを持ち、プログラムのどこからでもアクセスできます。 関数内でvar



キーワードを使用して変数が宣言されている場合、その変数はローカル変数であるこの関数内でのみ表示されます。



グローバルスコープの特定の変数の名前と名前が一致するvar



を使用して関数内で変数が宣言されている場合、グローバル変数を「オーバーライド」します。 つまり、関数内のそのような変数にアクセスする場合、そのローカルバージョンが使用されます。



ブロック(ブレースで囲まれたコードの領域)は新しい可視領域を作成しないことを理解することが重要です。 関数が呼び出されると、新しいスコープが作成されます。 var



キーワードには、ブロックスコープではなく、いわゆる機能スコープがあります。



関数コードで変数が宣言されている場合、その変数は関数コード全体に表示されます。 変数が関数コードの末尾でvar



で宣言されている場合でも、変数を上げる(巻き上げる)メカニズムはJavaScriptで機能するため、コードの先頭で参照できます。 このメカニズムは変数宣言を「レイズ」しますが、初期化の操作は「レイズ」しません。 これは混乱の原因になる可能性があるため、関数の先頭で変数を宣言するルールにしてください。



▍キーワードlet



letキーワードはES2015に登場しましたが、簡単に言うとvar



「ブロック」バージョンと呼ぶことができます。 let



キーワードを使用して宣言された変数の範囲は、ネストされたブロックと同様に、宣言されたブロック、演算子、または式に制限されます。



「let」という単語自体があまり明確でないようであれば、代わりに「let」という単語が使用されていると想像できます。 次に、 let color = 'red'



という表現はlet color = 'red'



英語に「色を赤に」、ロシア語に「色を赤に」のように翻訳できます。



let



キーワードを使用すると、 var



キーワードに関連付けられたあいまいさを取り除くことができます(たとえば、 let



を使用して同じ変数を二重宣言することはできません)。 関数の外部でlet



を使用すると、たとえばループを初期化するときに、グローバル変数は作成されません。



たとえば、このようなコードはエラーの原因になります。



 for (let i = 0; i < 5; i++) {   console.log(i) } console.log(i)
      
      





ループの初期化中に、 var



キーワードを使用してカウンターi



が宣言されている場合、 i



はループの完了後にループ外で使用可能になります。



最近では、現代の標準に基づいてJSプログラムを開発する場合、 var



を完全に破棄して、 let



キーワードとconst



キーワードのみを使用できます。



constキーワードconst



var



またはlet



キーワードを使用して宣言された変数は上書きできます。 これらのキーワードの代わりにconst



使用すると、そのヘルプで宣言および初期化されたconst



新しい値を割り当てることはできません。



 const a = 'test'
      
      





この例では、定数aに新しい値を割り当てることはできません。 ただし、 a



が数値のようなプリミティブ値ではなくオブジェクトの場合、 const



キーワードを使用しても、このオブジェクトが変更から保護されないことに注意してください。



オブジェクトが変数に書き込まれていると言うとき、実際には変数がオブジェクトを参照していることを意味します。 このリンクを変更することはできません。また、リンク先のオブジェクトを変更できます。



const



キーワードは、オブジェクトを不変にしません。 対応する定数に書き込まれた参照への変更から保護するだけです。 これは次のようなものです。



 const obj = {} console.log(obj.a) obj.a = 1 // console.log(obj.a) //obj = 5 // 
      
      





obj



定数では、初期化時に新しい空のオブジェクトが書き込まれます。 存在しないプロパティa



にアクセスしようとしても、エラーは発生しません。 コンソールはundefined



ます。 その後、新しいプロパティをオブジェクトに追加し、再度アクセスを試みます。 今回は、このプロパティの値1



がコンソールに到達します。 例の最後の行のコメントを外した場合、このコードを実行しようとするとエラーが発生します。



const



キーワードはlet



に非常に似ており、特にブロックスコープを持っています。



現代の状況では、 const



キーワードを使用して、特別な場合にのみlet



、値が変更される予定のないすべてのエンティティを宣言することは完全に受け入れられます。 なんで? 問題は、プログラムを複雑にせず、エラーを回避するために、利用可能な最も単純な構成を使用するよう努めることが最善であるということです。



データ型



JavaScriptは「型なし」言語と呼ばれることもありますが、そうではありません。 さまざまな型の値を変数に書き込むことができるのは事実ですが、それでもJavaScriptにはデータ型があります。 特に、プリミティブデータ型とオブジェクトデータ型について説明しています。



特定の値のデータ型を決定するには、 typeof



演算子を使用できます。 オペランドのタイプを示す文字列を返します。



▍プリミティブデータ型



プリミティブJavaScriptデータ型のリストは次のとおりです。





ここで、データ型の名前は、 typeof



演算子がそれらを返す形式で与えられます。



このリストから最も一般的に使用されるデータ型について話しましょう。



型番



JavaScriptのnumber



値は、64ビットの倍精度浮動小数点数として表されます。



コードでは、数値リテラルは10進数システムで整数と小数として表されます。 他の方法を使用して番号を記録できます。 たとえば、数値リテラルの先頭にプレフィックス0x



がある場合0x



進表記で書かれた数字として認識されます。 数字は指数表記で書くこともできます(そのような数字では文字e



見つけることができます)。



整数エントリの例を次に示します。



 10 5354576767321 0xCC //  
      
      





ここに小数があります。



 3.14 .1234 5.2e4 //5.2 * 10^4
      
      





数値リテラル(この動作は他のいくつかのプリミティブ型の特徴でもあります)。操作中にオブジェクトとして自動的にアクセスしようとすると、対応するオブジェクト(オブジェクトラッパー)に変換されます。 この場合、オブジェクトラッパーNumber



について説明しています。



ここでは、たとえば、変数a



にアクセスする試みのように見えます。変数a



には、Google Chromeコンソールで数値リテラルがオブジェクトとして書き込まれます。









数値オブジェクトラップツールチップ



たとえば、 Number



型のオブジェクトのtoString()



メソッドを使用すると、数値の文字列表現が返されます。 次のように、ブラウザコンソール(および通常のコード)で実行できる対応するコマンドのように見えます。



 a.toString()
      
      





メソッド名の後の二重括弧に注意してください。 これらを入力しない場合、システムはエラーを出力しませんが、予想される出力の代わりに、コンソールは数字5の文字列表現とはまったく異なるものになることがわかります。



グローバルNumber



オブジェクトは、コンストラクターの形式で使用でき、その助けを借りて新しい番号を作成します(この形式ではほとんど使用されませんが)。また、インスタンスを作成せずに独立したエンティティとして使用することもできますヘルプ)。 たとえば、そのNumber.MAX_VALUE



プロパティには、JavaScriptで表現できる最大数値が含まれています。



タイプ文字列



string



型の値はstring



シーケンスです。 このような値は、一重引用符または二重引用符で囲まれた文字列リテラルとして指定されます。



 'A string' "Another string"
      
      





文字列値は、バックスラッシュ文字を使用して複数の部分に分割できます。



 "A \ string"
      
      





文字列には、文字列がコンソールに出力されるときに解釈される、いわゆるエスケープシーケンスが含まれる場合があります。 たとえば、シーケンス\n



は改行文字を意味します。 バックスラッシュ文字を使用して、同じ引用符で囲まれた文字列に引用符を追加することもできます。 引用文字を\



エスケープすると、システムはそれを特殊文字として認識しません。



 'I\'ma developer'
      
      





文字列は、 +



演算子を使用して連結できます。



 "A " + "string"
      
      





テンプレートリテラル



ES2015では、いわゆるパターンリテラル、またはパターン文字列が導入されました。 それらはバッククォート( `



)で囲まれた文字列であり、いくつかの興味深い特性があります。



 `a string`
      
      





たとえば、テンプレートリテラルでは、JavaScript式を評価した結果である特定の値に置き換えることができます。



 `a string with ${something}` `a string with ${something+somethingElse}` `a string with ${obj.something()}`
      
      





逆引用符を使用すると、複数行の文字列リテラルを簡単に記述できます。



 `a string with ${something}`
      
      





ブール型



JavaScriptには、ブール値を操作するときに使用されるいくつかの予約語があります-これらはtrue



(true)およびfalse



(false)です。 ==



===



<



>



などの比較演算は、 true



またはfalse



返しtrue







論理式はif



while



などの構造で使用され、プログラムの進行を制御するのに役立ちます。



true



またはfalse



が予想される場合、言語によって自動的に真(真)または偽(偽)と見なされる他の値を使用できることに注意してください。



特に、以下は偽の値です。



 0 -0 NaN undefined null '' // 
      
      





残りの値はtrueです。



nullを入力



JavaScriptには、値がないことを示す特別なnull



値があります。 他の言語でも同様の意味が使用されます。



タイプ未定義



特定の変数に書き込まれたundefined



値は、この変数が初期化されておらず、値がないことを示します。



この値は、 return



キーワードを使用して結果が明示的に返されない関数から自動的に返されます。 関数が、呼び出されたときに指定されていないパラメーターを受け入れる場合、 undefined



設定されます。



undefined



の値を確認するには、次の構成を使用できます。



 typeof variable === 'undefined'
      
      





▍オブジェクト



プリミティブではないすべての値にはオブジェクト型があります。 関数、配列、「オブジェクト」と呼ばれるもの、および他の多くのエンティティについて話します。 これらのデータ型はすべてobject



型に基づいており、多くの点で互いに異なりますが、多くの共通点があります。



表現



式は、特定の値に対して実行された計算に基づいて処理および取得できるコードのフラグメントです。 JavaScriptにはいくつかの式のカテゴリがあります。



算術式



計算結果が数値である式は、このカテゴリに分類されます。



 1 / 2 i++ i -= 2 i * 2
      
      





文字列式



そのような式を評価した結果は文字列です。



 'A ' + 'string' 'A ' += 'string'
      
      





一次表現



リテラル、定数、および識別子への参照は、このカテゴリに分類されます。



 2 0.02 'something' true false this // ,     undefined i // i    
      
      





これには、JavaScriptのキーワードと構成の一部も含まれます。



 function class function* // yield // /   yield* //     async function* //   await //     /pattern/i //  () //
      
      





配列とオブジェクトの初期化式



 [] //  {} //  [1,2,3] {a: 1, b: 2} {a: {b: 1}}
      
      





論理式



論理式では、論理演算子が使用され、計算の結果は論理値になります。



 a && b a || b !a
      
      





プロパティアクセス式



これらの式により、オブジェクトのプロパティとメソッドにアクセスできます。



 object.property //   ( )  object[property] object['property']
      
      





オブジェクト作成式



 new object() new a(1) new MyRectangle('name', 2, {a: 4})
      
      





関数宣言式



 function() {} function(a, b) { return a * b } (a, b) => a * b a => a * 2 () => { return 2 }
      
      





呼び出し式



このような式は、オブジェクトの関数またはメソッドを呼び出すために使用されます。



 ax(2) window.resize()
      
      





オブジェクトを操作する



上記で、オブジェクトリテラルについて、メソッドの呼び出しについて、プロパティへのアクセスについて、既にオブジェクトに遭遇しています。 ここでは、オブジェクトについて詳しく説明します。特に、プロトタイプの継承メカニズムとclass



キーワードの使用について検討します。



▍プロトタイプ継承



JavaScriptは、プロトタイプ継承をサポートするという点で、現代のプログラミング言語の中でも際立っています。 ほとんどのオブジェクト指向言語は、クラスベースの継承モデルを使用します。



各JavaScriptオブジェクトには、そのプロトタイプである別のオブジェクトを指す特別なプロパティ( __proto__



)があります。 オブジェクトは、プロトタイプのプロパティとメソッドを継承します。



オブジェクトリテラルを使用して作成されたオブジェクトがあるとします。



 const car = {}
      
      





または、 Object



コンストラクタを使用してObject



を作成しました。



 const car = new Object()
      
      





これらのいずれの場合でも、 car



オブジェクトのプロトタイプはObject.prototype



ます。



オブジェクトでもある配列を作成する場合、そのプロトタイプはArray.prototype



オブジェクトです。



 const list = [] //  const list = new Array()
      
      





これは次のように確認できます。



 car.__proto__ == Object.prototype //true car.__proto__ == new Object().__proto__ //true list.__proto__ == Object.prototype //false list.__proto__ == Array.prototype //true list.__proto__ == new Array().__proto__ //true
      
      





ここでは__proto__



プロパティを使用しました。開発者が利用できる必要はありませんが、通常はアクセスできます。 オブジェクトのプロトタイプを取得するより信頼性の高い方法は、グローバルObject



getPrototypeOf()



メソッドを使用することgetPrototypeOf()







 Object.getPrototypeOf(new Object())
      
      





プロトタイプのすべてのプロパティとメソッドは、このプロトタイプを持つオブジェクトからアクセス可能です。 ここでは、たとえば、配列のリストのように見えます。









配列のヒント



すべてのオブジェクトの基本プロトタイプはObject.prototype



です。



 Array.prototype.__proto__ == Object.prototype
      
      





Object.prototype



プロトタイプがありObject.prototype



ん。



上で見たのは、プロトタイプチェーンの例です。



オブジェクトのプロパティまたはメソッドにアクセスしようとするときに、オブジェクト自体にそのようなプロパティまたはメソッドがない場合、それらはプロトタイプで検索され、次にプロトタイププロトタイプなどで検索され、目的のものが見つかるまで、またはプロトタイプチェーンは終了しません。



new



演算子とオブジェクトリテラルまたは配列リテラルを使用してオブジェクトを作成することに加えて、 Object.create()



メソッドを使用してオブジェクトのインスタンスを作成できます。 このメソッドに渡される最初の引数は、それを使用して作成されたオブジェクトのプロトタイプになるオブジェクトです。



 const car = Object.create(Object.prototype)
      
      





isPrototypeOf()



メソッドを使用して、オブジェクトが別のオブジェクトのプロトタイプチェーンの一部であるかどうかを確認できます。



 const list = [] Array.prototype.isPrototypeOf(list)
      
      





コンストラクター関数



上記では、言語で既に使用可能なコンストラクター関数を使用して新しいオブジェクトを作成しました(呼び出されると、 new



キーワードが使用されます)。 このような関数は独立して作成できます。 例を考えてみましょう。



 function Person(name) { this.name = name } Person.prototype.hello = function() { console.log(this.name) } let person = new Person('Flavio') person.hello() console.log(Person.prototype.isPrototypeOf(person))
      
      





-. , this



. name



, . . - , name



, .



, name



, . , , , hello()



. , Person



hello()



( ).





ES6 JavaScript «».



JavaScript . , JS . , , , « » . , , , , , .





.



 class Person { constructor(name) {   this.name = name } hello() {   return 'Hello, I am ' + this.name + '.' } }
      
      





, new ClassIdentifier()



.



constructor



, .



. hello()



— , , . Person



.



 const flavio = new Person('Flavio') flavio.hello()
      
      





,



. , , , , .



, ( ) , , -, .



 class Programmer extends Person { hello() {   return super.hello() + ' I am a programmer.' } } const flavio = new Programmer('Flavio') flavio.hello()
      
      





hello()



Hello, I am Flavio. I am a programmer



.



(), .



super



.





, , , , , . ( static



) , .





JavaScript , (, ) . , , .





, get



set



. — , , . -, — .



 class Person {   constructor(name) {     this.userName = name   }   set name(value) {     this.userName = value   }   get name() {     return this.userName   } }
      
      





まとめ



, , JavaScript. .



親愛なる読者! JS, , class.






All Articles