In 'n' Out

知識を取り込み、そして発信する

データの種類とオブジェクト操作

値の確認とデータの操作

JavaScriptでは値の種類を判別したり、オブジェクトや配列の中身を扱う場面が多くあります。
例えばフォームに入力された値は、数値として扱いたいのか文字列として扱うのかを判別する必要があります。
また、設定情報や取得したデータはオブジェクトとしてまとめられていることが多く、その中身を取り出して処理する場面も頻繁にあります。
自分で用意した値であれば把握できますが、ユーザー入力や外部から取得したデータは想定通りとは限りません。
そのため、値の種類を確認する処理や、オブジェクトの中身を安全に扱うための方法が必要になります。
ここでは値の種類を確認する方法と、オブジェクトや配列を扱うための基本的な方法を解説します。

型の確認

値の種類を調べるにはtypeofを使用します。

構文

typeof 値;

typeofは演算子で、値の型を文字列として返します。

コード例

//typeof1.js
alert(typeof 100);
alert(typeof '文字列');
alert(typeof true);

動作例

※このボタンは動作確認用です

数値はnumber、文字列はstring、真偽値はbooleanとして表示されます。
このようにtypeofを使うことで、値の種類を判別することができます。
それでは変数を使った例を見てみましょう。

コード例

//typeof2.js
const num = [15, 20, 28, 30];
const str = 100;
let bool = false;
let variable;

alert(typeof Number(str));
alert(typeof String(num[0]));
alert(typeof bool);
alert(typeof variable);
alert(typeof num);

動作例

※このボタンは動作確認用です

NumberやStringを使って値を変換し、それぞれnumber、string、booleanと表示されます。
値が代入されていない変数はundefinedを返します。
最後の配列numを確認するとobjectと返します。
配列はオブジェクトの一種であるため、typeofではobjectと判定されます。
このようにtypeofは大まかな型の判別には便利ですが、配列とオブジェクトの違いまでは判別できません。

オブジェクトの判定

instanceofは、値が特定のオブジェクトのインスタンスかどうかを判別するための演算子です。

構文

値 instanceof コンストラクター名;

instanceofは演算子で、値がどのコンストラクターから作られたかを判別します。
戻り値はtrueまたはfalseの真偽値になります。

コード例

//instanceOf.js
const arr = [10, 20, 30];
const str = '文字列';

alert(arr instanceof Array);
alert(str instanceof String);

動作例

※このボタンは動作確認用です

このコード例を実行すると配列であるArrayで判別するとtrueと表示されます。
一方で文字列をStringで判別するとfalseと表示されます。
どちらも変数を宣言しているのになぜでしょう。
それは配列は内部的にArray()というコンストラクター関数によって生成されるオブジェクトであるためです。
つまり、[10, 20, 30]はnew Array()で作られる配列と同じ種類のオブジェクトとして扱われます。
文字列に関してはプリミティブ型のため、コンストラクター関数から生成されたオブジェクトではなく、falseを返します。
そのため、new String('文字列')としないとtrueを返すことはありません。
instanceofはコンストラクターから生成されたオブジェクトかどうかを判定するため、このような違いが発生します。

オブジェクトのキーと値の取得

JavaScriptでは、オブジェクトの中に複数のデータ(プロパティ)を持たせることができます。
これまでのように、特定のプロパティを個別に取り出すこともできますが、データが増えてくると一つずつ扱うのは手間がかかります。
そのため、オブジェクトに含まれる複数のデータをまとめて扱う方法を理解しておくことが重要です。
これにより、データの確認や処理を効率よく行えるようになります。

構文

Object.keys(対象);
Object.values(対象);
Object.entries(対象);

Object.keys、Object.values、Object.entriesはいずれもメソッドです。
これらは、指定したオブジェクトの中身を配列として取得するために使用します。
Object.keysは対象のプロパティ名(キー)を、Object.valuesは対象の値(バリュー)を、Object.entriesは対象のキーと値の組み合わせを、配列として取得します。

コード例

//objectKeys1.js
function item(name, price, stock) {
    this.itemName = name;
    this.itemPrice = price;
    this.itemStock = stock;
}

const data = new item('りんご', 150, 10);

alert(Object.keys(data));
alert(Object.values(data));
alert(Object.entries(data));

動作例

※このボタンは動作確認用です

このコード例ではkeys、values、entriesで取得した結果をそれぞれalertで表示しています。
keysではプロパティ名、valuesでは値、entriesでは変数名と値が配列に格納されていることがわかります。
取得するだけでも確認には使えますが、実際の処理では取得したデータをもとに操作することが重要です。
そこで便利に扱えるようになるのがオブジェクトリテラルです。

オブジェクトリテラル

JavaScriptでは、複数のデータをひとまとまりとして扱う方法のひとつにオブジェクトがあります。
これまで扱ってきたように、コンストラクター関数を使ってオブジェクトを作成することもできますが、より簡単にオブジェクトを作る方法も用意されています。
それがオブジェクトリテラルです。
オブジェクトリテラルは、波かっこを使って、その場で直接オブジェクトを作成する書き方です。
コンストラクター関数のように定義を用意する必要がないため、少量のデータを扱う場合や、一時的なデータを作成する場合によく使われます。
ここでは、オブジェクトリテラルの基本的な書き方と、データの扱い方について確認していきます。

構文

{
    キー: 値,
    キー: 値
}

オブジェクトリテラルはキーと値の組み合わせでデータを管理します。
{}で囲んだキーと値は:で区切ることで1対1で対応します。
なお、キーと値は1つでも複数でもかまいません。
キーに設定する名前は日本語でも英語でもよく、値も数値・文字列・関数などなんでも設定できます。

コード例

//objectKeys2.js
function student(name, scores) {
    this.studentName = name;
    this.studentScores = scores;
}

const student1 = new student('山田', {
    国語: 75,
    算数: 80,
    理科: 90,
    社会: 62
});

alert(Object.keys(student1));
alert(Object.values(student1));
alert(Object.entries(student1));

動作例

※このボタンは動作確認用です

このコード例はkeys、values、entriesで取得した結果をそれぞれalertで表示しています。
ただし、この状態ではオブジェクトリテラルの値を取得することができません。
このコードをオブジェクトリテラルの値を扱えるよう書き換えてみます。

コード例

//objectKeys3.js
function student(name, scores) {
    this.studentName = name;
    this.studentScores = scores;
}

const student1 = new student('山田', {
    国語: 75,
    算数: 80,
    理科: 90,
    社会: 62
});

const values = Object.values(student1.studentScores);

let total = 0;

values.forEach(function (score) {
    total += score;
});

alert(student1.studentName + 'の合計点は' + total + '点です');

動作例

※このボタンは動作確認用です

途中までは先ほどのコードと同じです。
インスタンスしたstudent1のstudentScoresを、Object.valuesを使って配列に格納します。
forEachを使って各教科の点数を順番に加算し、alertに名前と合計点を表示させました。
このようにオブジェクトリテラルとObject.valuesを使って格納した値を取得するだけでなく、計算にも利用することができます。
当然ですが値が文字列の場合は計算はできません。
ここで重要なのはオブジェクトリテラルとObject.valuesを理解することで、値の取り扱い方が幅広くなるということです。

数値の判定

JavaScriptでは、値が数値かどうかを確認したり、計算に使える状態かどうかを判定する場面があります。
一見すると数値に見える値でも、実際には計算できない特殊な値や、数値として扱えないデータが含まれていることがあります。
そのため、処理を行う前に値の状態を確認することが重要になります。
ここでは、数値に関する判定方法について見ていきます。

構文

isNaN(値)
isFinite(値)

isNaN、isFiniteはいずれも数値の状態を判定する関数です。
isNaNは、カッコ内に値が数値として扱えない場合にtrueを返し、数値として扱える場合はfalseを返します。
isFiniteは、カッコ内に指定した値が有限の数値であればtrueを返し、InfinityやNaNなどの無限・非数値の場合はfalseを返します。
どちらも引数に指定した値をもとに判定を行い、結果を真偽値で返す仕組みになっています。

コード例

//isNaNFinite.js
const value = ['100', '100円', 'abc', Infinity];

alert(isNaN(value[0]));
alert(isNaN(value[1]));
alert(isNaN(value[2]));

alert(isFinite(value[0]));
alert(isFinite(value[3]));

動作例

※このボタンは動作確認用です

このコードでは、数値として扱えるかどうかを判定しています。
一見するとどれも似たような値に見えますが、実際の判定結果は異なります。
まず、'100'のような数値の文字列は、自動的に数値へ変換できるため、数値として扱われます。
そのため、isNaNではfalseとなり、isFiniteでもtrueとなります。
一方で、'100円'や'abc'のように数値へ変換できない文字列は、数値ではないと判断されます。
そのため、isNaNではtrueが返されます。
また、Infinityは無限大を表す特別な数値です。
InfinityはJavaScriptでは特別な数値として扱われますが、、終わりのある値ではないため、isFiniteではfalseとなります。
このように、見た目が数値に近くても、実際に数値として扱えるかどうかで判定結果が変わる点に注意が必要です。

ここまで型の確認、オブジェクトの判定、数値の判定などを見てきましたが、どれも入力チェックなどを行うために必要です。
しっかり理解して取り扱えるようにしましょう。