JS-データタイプ-typeof/instance of/Object.prototype.toString

7092 ワード

参考記事:データの種類
typeof演算子JavaScriptには3つの方法があり、1つの値がどのタイプであるかを判定することができる.
  • typeof演算子
  • instance of演算子
  • Object.prototype.toString方法
  • typeoftypeof演算子は、値のデータタイプを返します.
  • 値、文字列、ブール値はそれぞれnumberstringbooleanfunctionを返します.
  • typeof 123 // "number"
    typeof '123' // "string"
    typeof false // "boolean"
    
  • 関数はundefinedを返します.
  • function f() {}
    typeof f
    // "function"
    
  • undefinedtypeofに戻る.
  • typeof undefined
    // "undefined"
    
    この点を利用して、vは、エラーを報告することなく、宣言されていない変数をチェックするために使用されてもよい.
    v
    // ReferenceError: v is not defined
    
    typeof v
    // "undefined"
    
    上記のコードの中で、変数vartypeofコマンドで宣言していません.直接使用するとエラーが発生します.しかし、undefinedの後ろに置くと、エラーを報告せずにobjectに戻ります.
    実際のプログラミングでは、この特徴は判断文によく使われます.
    //      
    if (v) {
      // ...
    }
    // ReferenceError: v is not defined
    
    //      
    if (typeof v === "undefined") {
      // ...
    }
    
  • オブジェクトはtypeofに戻る.
  • typeof window // "object"
    typeof {} // "object"
    typeof [] // "object"
    
    objectの欠点:上のコードでは、空配列([])のタイプもJavaScriptであり、これはtypeof内部であり、配列は本質的には特殊なオブジェクトであることを示している.instanceofは、配列とオブジェクトを区別することができません.ちなみに、null演算子は、行列とオブジェクトを区別することができます.
    var o = {};
    var a = [];
    
    o instanceof Array // false
    a instanceof Array // true
    
  • nullはObjectに戻ります.instanceofは空のオブジェクトの参照と見なされるからである.
  • typeof null // "object"
    
    instance ofv演算子は、オブジェクトがあるコンストラクタの一例であるかどうかを示すブール値を返します.
  • 以下のコードにおいて、オブジェクトVehicleは構成関数trueの例であるので、instanceofに戻る.
  • var v = new Vehicle();
    v instanceof Vehicle // true
    
  • instanceof演算子の左側はインスタンスオブジェクトで、右側はコンストラクタです.
  • prototypeの役割:右のコンストラクタのプロトタイプオブジェクト(Object.prototype.isPrototypeOf)が、左のオブジェクトのプロトタイプチェーン上にあるかどうかを確認する.したがって、次の2つの書き方は等価です.
  • v instanceof Vehicle
    //    
    Vehicle.prototype.isPrototypeOf(v)
    
    上記のコードにおいて、instanceofの意味は以下の通りである.
    var p = {x:1};//        
    var o = Object.create(p);//            
    p.isPrototypeOf(o);//=>true:o  p
    Object.prototype.isPrototypeOf(p);//=> true p   Object.prototype
    
  • は、trueによってプロトタイプチェーン全体を検査するので、同一のインスタンスオブジェクトは、複数のアーキテクチャ関数をdに返すかもしれない.
  • var d = new Date();
    d instanceof Date // true
    d instanceof Object // true
    
    上記のコードでは、Dateは、Objectおよびtrueの例であり、したがって、これらの2つの構成関数はinstanceofに戻る.
  • prototypeの原理は、左のオブジェクトのプロトタイプチェーン上にあるかどうかを検査することである.左のオブジェクトのプロトタイプチェーンには、nullオブジェクトしかありません.このとき、instanceofは歪みがあると判断する.
  • var obj = Object.create(null);
    typeof obj // "object"
    Object.create(null) instanceof Object // false
    
    上記のコードでは、Object.create(null)は新しいオブジェクトobjを返します.その原型はnullです.右の構造関数Objectprototype属性は、左のプロトタイプチェーンにはないので、instanceofobjObjectの例ではないと考えられている.しかし、オブジェクトのプロトタイプがnullでない限り、instanceof演算子の判断は歪みません.
  • instanceof演算子の一用途は、判定値の種類である.
  • var x = [1, 2, 3];
    var y = {};
    x instanceof Array // true
    y instanceof Object // true
    
    上記のコードにおいて、instanceof演算子は、変数xが配列であり、変数yがオブジェクトであると判断した.
    短所:instanceof演算子は、元のタイプ(Unidefined、Null、Boolean、Number、String)の値を適用しないオブジェクト(純粋なオブジェクトと配列)にのみ使用できます.
    var s = 'hello';
    s instanceof String // false
    
    上記のコードでは、文字列はStringオブジェクトの例ではないので、falseを返します.
    さらに、undefinedおよびnullについては、instanceOf演算子は常にfalseに戻る.
    undefined instanceof Object // false
    null instanceof Object // false
    
  • instanceof演算子を利用して、構造関数を呼び出したときにnewコマンドを追加することを忘れた問題も巧みに解決できます.
  • function Fubar (foo, bar) {
      if (this instanceof Fubar) {
        this._foo = foo;
        this._bar = bar;
      } else {
        return new Fubar(foo, bar);
      }
    }
    
    上記のコードはinstanceofの演算子を使用しており、関数内部でthisのキーワードが構造関数Fubarの例であるかどうかを判断している.もしそうでないなら、newコマンドを追加するのを忘れたということです.
    Object.prototype.toString
  • オブジェクト、配列、関数を区別するためには、単にtypeofを使用してはいけません.null及びArrayの結果もobjectであり、時には必要なのは純粋なobjectオブジェクトである.
  • 私たちは、あるオブジェクト値がどの内蔵タイプに属するかをObject.prototype.toString法で正確に判断できます.Object.prototype.toString方法を紹介する前に、toString()方法とObject.prototype.toString.call()方法を比較します.
  • var arr=[1,2];
    
    //         toString()
    arr.toString();// "1,2"
    
    //  call  arr    Object.prototype      toString  
    Object.prototype.toString.call(arr); //"[object Array]"
    
    継承配列arrとしてtoString方法を書き換えたが、Object.prototypeにおけるtoString方法ではない.
  • はどうしてtoStringと違って作用しますか?実は、この中はjsプロトタイプとプロトタイプチェーンに関する知識があります.
    var arr=[1,2,3];
    Object.prototype.toString.call(arr); //"[object Array]"
    Array.prototype.toString.call(arr); // "1,2,3"
    arr.toString(); // "1,2,3"
    
    ここを見て分かるはずですが、複雑なデータタイプの判断にはObject.prototype上のtoStringしか使えません.
  • いくつかのプロトタイプチェーンの概念を簡単に説明します.
  • jsのオブジェクトは全部Objectから継承されていることを知っています.だから、あるオブジェクトに方法を呼び出すと、まずそのオブジェクトの上で調べます.もし見つからなかったら、対象の原型(つまり.prototype)に入ります.見つけられなかったら、同じようなものも対象の原型に入ります.プロトタイプチェーンのトップObject.prototypeが見つかり、または入るまで停止します.
    したがって、arr.toString()を使用すると、Array.prototype.toStringを呼び出しているので、複雑なデータタイプの判断ができない.ArrayObjectから継承されているが、jsArray.prototypetoStringに書き換えられ、Object.prototype.toString.call(arr)を介して実際にはプロトタイプチェーンでObject.prototype.toStringを呼び出した.
  • オブジェクトのタイプJavaScriptはすべて対象であり、例外ではない.すべての値タイプにObject.prototype.toString.call()を適用する方法の結果は以下の通りである.
    console.log(Object.prototype.toString.call(123)) //[object Number]
    console.log(Object.prototype.toString.call('123')) //[object String]
    console.log(Object.prototype.toString.call(undefined)) //[object Undefined]
    console.log(Object.prototype.toString.call(true)) //[object Boolean]
    console.log(Object.prototype.toString.call({})) //[object Object]
    console.log(Object.prototype.toString.call([])) //[object Array]
    console.log(Object.prototype.toString.call(function(){})) //[object Function]