JavaScriptの中のタイプ検査

8530 ワード

JSのダイナミックタイプは良いのも悪いのもあります.良い面では、変数のタイプを指定する必要はありません.悪いことに、変数のタイプは永遠に確認できません.
typeof演算子は、JSの6種類を決定できます.

typeof 10;    // => 'number'
typeof 'Hello';  // => 'string'
typeof false;   // => 'boolean'
typeof { a: 1 }; // => 'object'
typeof undefined; // => 'undefined'
typeof Symbol(); // => 'symbol'

同様に、instance of演算子は、配置関数のプロトタイプ属性があるインスタンスオブジェクトのプロトタイプチェーン上に現れるかどうかを検出するために使用される.

class Cat { }
const myCat = new Cat();

myCat instanceof Cat; // => true

ただし、typeofとinstance ofのいくつかの行為は、紛らわしいかもしれません.未然に防ぐには、エッジの状況を前もって知る必要があります.
1.typeof null
typeof myObject==='object'はmyObjectが対象のタイプかどうかを教えます.例を挙げます

const person = { name: '    ' };

typeof person; // => 'object'

typeof personは'object'です.personは普通のJSオブジェクトです.
ある場面では変数値はnullとして指定する必要がありますが、以下のようなシーンがあります.
nullを使用して設定オブジェクトをスキップしてnullを使用して初期化します.後でオブジェクトを保存する変数は関数が何らかの理由でオブジェクトを作成できない場合、nullに戻ります.例えば、正規表現マッチングがない場合、str.match(regExp)方法はnullに戻ります.

const message = 'Hello';
message.match(/Hi/); // => null

ここで一つの問題を引き出します.typeofを使って値のあるオブジェクトとnull値のあるオブジェクトを区別できますか?

let myObject = null;
typeof myObject; // => 'object'

myObject = { prop: 'Value' };
typeof myObject; // => 'object'

上からは、typeofオブジェクトに値のあるオブジェクトとnull値のあるオブジェクトがあり、結果はすべて「object」となります.
変数にオブジェクトがあるかどうか、nullではないかを以下の方法で検出できます.

function isObject(value) {
 return typeof value === 'object' && value !== null;
}

isObject({});  // => true
isObject(null); // => false

valueがobjectであるかどうかをチェックする以外に、null:value!==null
2.typeof array
変数に行列が含まれているかどうかを検出しようとすると、一般的なエラーはtypeofオペレータを使用します.

const colors = ['white', 'blue', 'red'];

typeof colors; // => 'object'

配列を検出する正しい方法は、Aray.isAray()を使用することである.

const colors = ['white', 'blue', 'red'];
const hero = { name: 'Batman' };

Array.isArray(colors); // => true
Array.isArray(hero);  // => false

Aray.isAray(colors)は、colorsが行列であることを示すブール値trueを返します.
3.虚値タイプの検査
JSのundefinedは、初期化されていない変数を表す特殊な値です.
初期化されていない変数、存在しないオブジェクト属性にアクセスしようとした場合、取得した値はundefinedとなります.

let city;
let hero = { name: '    ', villain: false };

city;   // => undefined
hero.age; // => undefined

初期化されていない変数cityと存在しないプロパティhero.ageにアクセスした結果はundefinedです.
属性が存在するかどうかを確認するには、条件の中でobject[propName]を使用することができます.このような出会いの値は、虚数またはundefinedであるかは信頼できません.

function getProp(object, propName, def) {
 //     
 if (!object[propName]) {
  return def;
 }
 return object[propName];
}

const hero = { name: '    ', villain: false };

getProp(hero, 'villain', true); // => true
hero.villain;          // => false

対象にpropNameが存在しない場合、objectの値はundefinedとなります.if(!object[propName]){return def}保護が不足している属性.
hero.villain属性が存在し、falseの値があります.しかし、この関数はvillan値にアクセスしたときにエラーでtrue:get Prop(hero,'villain',true)に戻ります.
undefinedは虚数の値で、同じfalse、0と''とnullです.
虚値をタイプチェックとして使うのではなく、属性がオブジェクトに存在するかどうかを確認します.

typeof object[propName] === 'undefined'
propName in object
object.hasOwnProperty(propName)
続いて、get Prop()関数を改善します.

function getProp(object, propName, def) {
 // Better
 if (!(propName in object)) {
  return def;
 }
 return object[propName];
}

const hero = { name: '    ', villain: false };

getProp(hero, 'villain', true); // => false
hero.villain;          // => false

if(!(propName in object){…}条件は属性が存在するかどうかを正確に決定します.
論理演算子
黙秘として論理演算子を使うのは避けたほうがいいと思います.これは読みの流れを中断しやすいです.

const hero = { name: '    ', villain: false };

const name = hero.name || 'Unknown';
name;   // => '    '
hero.name; // => '    '

//     
const villain = hero.villain || true;
villain;   // => true
hero.villain; // => false

heroオブジェクトには属性villainがあります.値はfalseですが、式hero.villain_trueはtrueとなります.
論理演算子𞓜|は、アクセス属性のデフォルトとして使用され、属性が存在し、虚値がある場合、オペレータは正しく動作しない.
属性が存在しない時にデフォルトで設定するなら、より良い選択は新しい二重疑問符(??)を使って操作します.

const hero = { name: '    ', villan: false };

//     
const villain = hero.villain ?? true;
villain;   // => false
hero.villain; // => false

または構成解除値を使用します.

const hero = { name: '    ', villain: false };

// Good
const { villain = true } = hero;
villain;   // => false
hero.villain; // => false

4.typeof NaN
整数、浮動小数点、特殊数字(例えばInfinity、NaN)の種類はいずれも数字です.

typeof 10;    // => 'number'
typeof 1.5;   // => 'number'
typeof NaN;   // => 'number'
typeof Infinity; // => 'number'
NaNは、数字を作成できないときに作成される特殊な数値です.NaNはnot a numberの略語です.
次の場合は数字を作成できません.

Number('oops'); // => NaN

5 * undefined; // => NaN
Math.sqrt(-1); // => NaN

NaN + 10; // => NaN

NaNは、数字の動作に失敗することを意味するので、数値有効性の検査には追加のステップが必要である.
以下のisValidNumber()関数はNaNによるエラーを防ぐこともできます.

function isValidNumber(value) {
 // Good
 return typeof value === 'number' && !isNaN(value);
}

isValidNumber(Number('Z99')); // => false
isValidNumber(5 * undefined); // => false
isValidNumber(undefined);   // => false

isValidNumber(Number('99')); // => true
isValidNumber(5 + 10);    // => true

typeof value=='number'以外にも多くの検証があります.isNaNは万全を期しています.
5.instance ofとプロトタイプチェーン
JSの各オブジェクトは特殊な関数を参照します.
object instance of Costructは、オブジェクトを検査するためのコンストラクタの演算子です.

const object = {};
object instanceof Object; // => true

const array = [1, 2];
array instanceof Array; // => true

const promise = new Promise(resolve => resolve('OK'));
promise instanceof Promise; // => true

今、私達は父種類のPetとそのサブタイプのCatを定義します.

class Pet {
 constructor(name) {
  this.name;
 }
}

class Cat extends Pet {
 sound = 'Meow';
}

const myCat = new Cat('Scratchy');

今、myCatの実例を確認してみます.

myCat instanceof Cat;  // => true
myCat instanceof Pet;  // => true
myCat instanceof Object; // => true

instance of演算子は、myCatがCatであり、PetまたはObjectの例を表しています.
instance ofオペレータは、オブジェクトの構造関数をプロトタイプチェーン全体で検索します.作成したオブジェクトの構造関数を正確に検出するには、constructorのプロパティを検出する必要があります.

myCat.constructor === Cat;  // => true
myCat.constructor === Pet;  // => false
myCat.constructor === Object; // => false

myCat.com nstructor==Catの計算結果だけがtrueで、CatはmyCatの例の構造関数であることを示しています.
6.まとめ
演算子typeofとinstance ofは、タイプチェックに使用されます.それらは使いやすいですが、特別な事情に注意しなければなりません.
注意したいのは、typeof nullは「object」に等しいです.変数にnull以外のオブジェクトが含まれているかどうかを判定するには、指定nullを表示する必要があります.
typeof myObject==='object'&myObject!==nullは変数が配列を含むかどうかを調べるための最適な方法として、Aray.isAray(variable)を使用して関数を内蔵します.
undefinedは虚値なので、条件文に直接使っていますが、このやり方は間違いやすいです.より良い選択は、prop in objectを使用して、属性が存在するかどうかを検証することである.
ダブル疑問符を使ってオペレーティング系のシンボルobject.prop?defまたは{prop=def}=objectは失われる可能性のある属性にアクセスします.
NaNはnumberタイプの特殊値で、数字の無効操作によって作成されます.変数に正確な数字があることを確認するために、より詳細な検証を使用したほうがいいです.isNaN(number)&typeof number=='number'
最後に、instance ofがprototypeチェーンでインスタンスを検索する構造関数を覚えてください.このことが分からない場合、親認証のサブクラスのインスタンスを使用すると、エラーの結果が得られます.
コード展開後に存在する可能性のあるバグをリアルタイムで知ることができませんでしたが、後でこれらのバグを解決するために、多くの時間をかけてロゴの調整を行いました.