javascriptで変数の種類を判断する方法
11064 ワード
JavaScriptには5種類の基本データタイプと1種類の複雑なデータタイプがあります.基本データタイプはUnidefined、Null、Boolean、Number、Stringです.複雑なデータの種類はObjectで、Objectの中でまた多くの具体的なタイプを細分しました.例えば、Aray、Function、Dateなどです.今日はどのような方法で変数のタイプを判断するかを検討します.
さまざまな方法を説明する前に、まずいくつかのテスト変数を定義して、後の方法が変数の種類をどのように解析できるかを見てみます.以下のいくつかの変数は、私たちが実際にコード化するときによく使うタイプを含んでいます.
私たちが普段使っているのは、typeofで変数タイプを検出することです.今回は、typeof検出変数のタイプも使います.
2.instanceで測定する
JavaScriptでは、変数のタイプを試してtypeof演算子を使うと判断され、typeof演算子を使う時に参照タイプの記憶値を採用すると問題が発生します.参照の種類に関係なく、オブジェクトは「object」に戻ります.ECMAScriptは他のJava演算子instance ofを導入してこの問題を解決します.instance of演算子は、処理中のオブジェクトの種類を識別するために、typeof演算子と似ています.typeofメソッドとは違って、instancentofメソッドは、開発者に特定のタイプのオブジェクトを明確に確認するよう要求します.たとえば:
3.constructorを使って検査する
instance ofを使って変数タイプを検出する場合、number、‘string’、bookのタイプは検出できません.したがって、私たちはこの問題を解決するために他の方法が必要です.constructorは元のオブジェクトの属性であり、構造関数を指しています.しかし、例示的なオブジェクトに従って属性を探す順序は、インスタンスオブジェクトに例示的な属性または方法がない場合は、プロトタイプチェーン上で探すため、インスタンスオブジェクトもconstrutor属性を使用することができる.まずnum.co nstructorの内容を出力します.すなわち、数字型の変数の構造関数はどのようなものですか?
function Number(){native code}
Numberの構造関数を指すことができますので、num.co nstructor==Numberを使ってnumがNumberタイプかどうかを判断できます.他の変数も同様です.
まずこれが何であろうと、まず彼がどのように変数のタイプを検出しているかを見てみましょう.
jqueryには$typeのインターフェースが提供されています.変数の種類を検出します.
タイプ判定
typeof
instance of
トラック
toString.call
ドル.type
num
number
false
true
[object Number]
number
str
ストリングス
false
true
[object String]
ストリングス
ブック
bollan
false
true
[object Boolean]
bollan
アール
object
true
true
[object Aray]
array
Json
object
true
true
[object Object]
object
func
機能
true
true
[object Funct]
機能
und
undefined
false
を選択します.
[object Udefined]
undefined
nul
object
false
を選択します.
[object Null]
null
ダテ
object
true
true
[object Date]
ダテ
reg
object
true
true
[object RegExp]
regexp
error
object
true
true
[object Error]
error
長所
使いやすいので、結果を直接出力できます.
複雑なタイプを検出できます.
ほぼすべてのタイプを検出できます.
すべてのタイプを検出しました.
を選択します.
欠点
検出したタイプが少なすぎます.
基本タイプは検出できません.かつ、iframeをまたぐことはできません.
iframeをまたがることができなくて、しかもconstructorは改正されやすいです.
IE 6下のundefinedは、nullは全部Objectである.
を選択します.
このように比較すると、各方法の違いがもっと見られます.そしてObject.prototype.toString.callと$typeの出力の結果は本当に似ています.jquery(2.1.2バージョン)の内部を見てみます.type方法はどうやって実現されますか?
さまざまな方法を説明する前に、まずいくつかのテスト変数を定義して、後の方法が変数の種類をどのように解析できるかを見てみます.以下のいくつかの変数は、私たちが実際にコード化するときによく使うタイプを含んでいます.
var num = 123;
var str = 'abcdef';
var bool = true;
var arr = [1, 2, 3, 4];
var json = {name:'wenzi', age:25};
var func = function(){ console.log('this is function'); }
var und = undefined;
var nul = null;
var date = new Date();
var reg = /^[a-zA-Z]{5,20}$/;
var error= new Error();
1.typeofで検出する私たちが普段使っているのは、typeofで変数タイプを検出することです.今回は、typeof検出変数のタイプも使います.
console.log(
typeof num,
typeof str,
typeof bool,
typeof arr,
typeof json,
typeof func,
typeof und,
typeof nul,
typeof date,
typeof reg,
typeof error
);
// number string boolean object object function undefined object object object object
出力の結果から、arr,json,nul,date,reg,errorはすべてObjectタイプに検出され、他の変数は正しく検出されます.変数がnumber、string、bollan、function、undefined、jsonタイプかどうかは、typeofで判断できます.他の変数は、nullを含むタイプは判断できません.また、typeofはarrayとjsonのタイプが区別できません.typeofという変数を使うと、arrayとjsonタイプがアウトプットするのはすべてobjectです.2.instanceで測定する
JavaScriptでは、変数のタイプを試してtypeof演算子を使うと判断され、typeof演算子を使う時に参照タイプの記憶値を採用すると問題が発生します.参照の種類に関係なく、オブジェクトは「object」に戻ります.ECMAScriptは他のJava演算子instance ofを導入してこの問題を解決します.instance of演算子は、処理中のオブジェクトの種類を識別するために、typeof演算子と似ています.typeofメソッドとは違って、instancentofメソッドは、開発者に特定のタイプのオブジェクトを明確に確認するよう要求します.たとえば:
function Person(){
}
var Tom = new Person();
console.log(Tom instanceof Person); // true
次の例を見てみましょう.
function Person(){
}
function Student(){
}
Student.prototype = new Person();
var John = new Student();
console.log(John instanceof Student); // true
console.log(John instancdof Person); // true
instance ofは、多層継承の関係を検出することができます.はい、私達はinstance ofを使って上記の変数を検出します.
console.log(
num instanceof Number,
str instanceof String,
bool instanceof Boolean,
arr instanceof Array,
json instanceof Object,
func instanceof Function,
und instanceof Object,
nul instanceof Object,
date instanceof Date,
reg instanceof RegExp,
error instanceof Error
)
// num : false
// str : false
// bool : false
// arr : true
// json : true
// func : true
// und : false
// nul : false
// date : true
// reg : true
// error : true
上記の運転結果から、num、str、bookは彼のタイプを検出していませんでしたが、次のようにnumを作成します.タイプを検出することができます.
var num = new Number(123);
var str = new String('abcdef');
var boolean = new Boolean(true);
同時に、undとnulはObjectタイプを検出して出力するtrueです.jsにはUnidefinedとNullという大域タイプがないので、undとnulは全部Objectタイプです.だからtrueを出力しました.3.constructorを使って検査する
instance ofを使って変数タイプを検出する場合、number、‘string’、bookのタイプは検出できません.したがって、私たちはこの問題を解決するために他の方法が必要です.constructorは元のオブジェクトの属性であり、構造関数を指しています.しかし、例示的なオブジェクトに従って属性を探す順序は、インスタンスオブジェクトに例示的な属性または方法がない場合は、プロトタイプチェーン上で探すため、インスタンスオブジェクトもconstrutor属性を使用することができる.まずnum.co nstructorの内容を出力します.すなわち、数字型の変数の構造関数はどのようなものですか?
function Number(){native code}
Numberの構造関数を指すことができますので、num.co nstructor==Numberを使ってnumがNumberタイプかどうかを判断できます.他の変数も同様です.
function Person(){
}
var Tom = new Person();
// undefined null constructor
console.log(
Tom.constructor==Person,
num.constructor==Number,
str.constructor==String,
bool.constructor==Boolean,
arr.constructor==Array,
json.constructor==Object,
func.constructor==Function,
date.constructor==Date,
reg.constructor==RegExp,
error.constructor==Error
);
// true
出力の結果から、undefinedとnullを除いて、他のタイプの変数はconstructorを使ってタイプを判断することができます.しかし、constructorを使っても保険ではありません.constructorの属性は修正されますので、検出された結果は正しくないです.例えば、
function Person(){
}
function Student(){
}
Student.prototype = new Person();
var John = new Student();
console.log(John.constructor==Student); // false
console.log(John.constructor==Person); // true
上記の例では、StudentプロトタイプのconstructorがPersonに向けられているように修正され、その結果、インスタンスオブジェクトのJohnのリアルな構造関数が検出されなくなる.また、instaceofとconstructorを使用して、arrayは現在のページで声明しなければならないと判断されました.例えば、一つのページ(親ページ)には一つのページ(サブページ)を参照して、サブページでarrayを宣言し、親ページの変数に値を付けます.このとき、変数はAray==object.com nstructorと判断されます.falseに戻ります理由:1、arrayは参照型のデータに属しており、転送中は参照先の伝達だけである.2、各ページのAray元のオブジェクトから引用された住所は違っています.サブページで声明されたarrayは、対応する構造関数であり、サブページのArayオブジェクトです.親ページで判断すると、サブページのArayとは等しくない.覚えてください.でないと、問題を追跡するのは難しいです.4.Object.prototype.toString.callを使用するまずこれが何であろうと、まず彼がどのように変数のタイプを検出しているかを見てみましょう.
console.log(
Object.prototype.toString.call(num),
Object.prototype.toString.call(str),
Object.prototype.toString.call(bool),
Object.prototype.toString.call(arr),
Object.prototype.toString.call(json),
Object.prototype.toString.call(func),
Object.prototype.toString.call(und),
Object.prototype.toString.call(nul),
Object.prototype.toString.call(date),
Object.prototype.toString.call(reg),
Object.prototype.toString.call(error)
);
// '[object Number]' '[object String]' '[object Boolean]' '[object Array]' '[object Object]'
// '[object Function]' '[object Undefined]' '[object Null]' '[object Date]' '[object RegExp]' '[object Error]'
出力の結果から、Object.prototype.toString.callは文字列を出力しています.文字列の中に配列があります.一番目のパラメータはObjectで、二つ目のパラメータはこの変数のタイプです.そして、すべての変数の種類が検出されました.私たちは第二のパラメータだけを取り出してもいいです.あるいは、Object.prototype.toString.call==object Arayを使用して変数arrが配列であるかを検出することができる.ECMAではObject.prototype.toString.callをどのように定義していますか?
Object.prototype.toString( ) When the toString method is called, the following steps are taken:
1. Get the [[Class]] property of this object.
2. Compute a string value by concatenating the three strings “[object “, Result (1), and “]”.
3. Return Result (2)
上記の仕様では、Object.prototype.toStringの挙動を定義しています.まず、対象の内部属性を取得し、この属性に基づいて、「Object Aray」と似た文字列を返します.結果として(ECMA規格を見ても分かるはずです.[]は言語内部で使用される、外部から直接アクセスできない属性を表します.「内部属性」といいます.).この方法を利用して、またコールに協力して、私達はいかなる対象の内部の属性[クラス]を得ることができて、そしてタイプの検査を文字列の比較に転化して、私達の目的を達成します.5.jqueryの中で$typeの実現jqueryには$typeのインターフェースが提供されています.変数の種類を検出します.
console.log(
$.type(num),
$.type(str),
$.type(bool),
$.type(arr),
$.type(json),
$.type(func),
$.type(und),
$.type(nul),
$.type(date),
$.type(reg),
$.type(error)
);
// number string boolean array object function undefined null date regexp error
出力結果を見たら、慣れた感じがありますか?はい、彼はObject.prototype.toString.callを使って出力した結果の第二パラメータです.まず、上記のすべての方法で検出された結果を比較します.横の列は測定方法で、縦の列は各変数です.タイプ判定
typeof
instance of
トラック
toString.call
ドル.type
num
number
false
true
[object Number]
number
str
ストリングス
false
true
[object String]
ストリングス
ブック
bollan
false
true
[object Boolean]
bollan
アール
object
true
true
[object Aray]
array
Json
object
true
true
[object Object]
object
func
機能
true
true
[object Funct]
機能
und
undefined
false
を選択します.
[object Udefined]
undefined
nul
object
false
を選択します.
[object Null]
null
ダテ
object
true
true
[object Date]
ダテ
reg
object
true
true
[object RegExp]
regexp
error
object
true
true
[object Error]
error
長所
使いやすいので、結果を直接出力できます.
複雑なタイプを検出できます.
ほぼすべてのタイプを検出できます.
すべてのタイプを検出しました.
を選択します.
欠点
検出したタイプが少なすぎます.
基本タイプは検出できません.かつ、iframeをまたぐことはできません.
iframeをまたがることができなくて、しかもconstructorは改正されやすいです.
IE 6下のundefinedは、nullは全部Objectである.
を選択します.
このように比較すると、各方法の違いがもっと見られます.そしてObject.prototype.toString.callと$typeの出力の結果は本当に似ています.jquery(2.1.2バージョン)の内部を見てみます.type方法はどうやって実現されますか?
//
var class2type = {};
var toString = class2type.toString;
// ...
type: function( obj ) {
if ( obj == null ) {
return obj + "";
}
// Support: Android<4.0, iOS<6 (functionish RegExp)
return (typeof obj === "object" || typeof obj === "function") ?
(class2type[ toString.call(obj) ] || "object") :
typeof obj;
},
// ...
// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
class2type[ "[object " + name + "]" ] = name.toLowerCase();
});
まずjQuery.eachのこの部分を見てみます.
// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
class2type[ "[object " + name + "]" ] = name.toLowerCase();
});
// ,`class2type` :
class2type = {
'[object Boolean]' : 'boolean',
'[object Number]' : 'number',
'[object String]' : 'string',
'[object Function]': 'function',
'[object Array]' : 'array',
'[object Date]' : 'date',
'[object RegExp]' : 'regExp',
'[object Object]' : 'object',
'[object Error]' : 'error'
}
typeの方法を見てみます.
// type
type: function( obj ) {
// null undefined,
// obj undefined, "undefined"
if ( obj == null ) {
return obj + "";
}
// Support: Android<4.0, iOS<6 (functionish RegExp)
// regExp function ; , object
// typeof obj object function, class2type , typeof
return (typeof obj === "object" || typeof obj === "function") ?
(class2type[ toString.call(obj) ] || "object") :
typeof obj;
}
type of obj====object"===="function"に戻ると、class 2 typeに戻ります.ここに来たら、なぜObject.prototype.toString.tostring.callと$typeのように似ているのかが分かりますよね.jquertobjectはprojectということです.'タイプを'bootlean'タイプに変えて返します.clast 2 typeに格納されているこの変数がないタイプは'object'に戻ります.'object'と'function'タイプを除いて、他のタイプはtypeofを使って検出します.つまりnumber、string、bookタイプの変数は、typeofを使ってください.