ホームページ >ウェブフロントエンド >jsチュートリアル >Javascript_javascriptスキルにおける型判定について簡単に説明します

Javascript_javascriptスキルにおける型判定について簡単に説明します

WBOY
WBOYオリジナル
2016-05-16 15:36:051154ブラウズ

データ型を決定するにはいくつかの方法があります

1. 単項演算子 typeOf

2. 関係演算子のインスタンス

3. コンストラクター属性

4. プロトタイプ属性

1.

の種類

typeofの戻り値は以下の通りです

タイプ 構造
未定義 "undefined"
ヌル "object" (下記参照)
ブール値 "boolean"
"number"
文字列 "string"
シンボル (ECMAScript 6 の新機能) "symbol"
ホストオブジェクト(ブラウザなどのJS環境で提供) 実装に依存
関数オブジェクト (ECMA-262 用語で [[Call]] を実装) "function"
その他のオブジェクト "object"

単純かつ大雑把な方法です。コードを見てください

// 以下代码在版本 Google Chrome 45.0.2454.101 m 中测试通过
// Numbers
console.log(typeof 37 === 'number');
console.log(typeof 3.14 === 'number');
console.log(typeof Math.LN2 === 'number');
console.log(typeof Infinity === 'number');
console.log(typeof NaN === 'number'); // 尽管NaN是"Not-A-Number"的缩写,意思是"不是一个数字"
console.log(typeof Number(1) === 'number'); // 不要这样使用!
 
// Strings
console.log(typeof "" === 'string');
console.log(typeof "bla" === 'string');
console.log(typeof (typeof 1) === 'string'); // console.log(typeof返回的肯定是一个字符串
console.log(typeof String("abc") === 'string'); // 不要这样使用!
 
// Booleans
console.log(typeof true === 'boolean');
console.log(typeof false === 'boolean');
console.log(typeof Boolean(true) === 'boolean'); // 不要这样使用!
 
// Symbols
console.log(typeof Symbol() === 'symbol');
console.log(typeof Symbol('foo') === 'symbol');
console.log(typeof Symbol.iterator === 'symbol');
 
// Undefined
console.log(typeof undefined === 'undefined');
console.log(typeof blabla === 'undefined'); // 一个未定义的变量,或者一个定义了却未赋初值的变量
 
// Objects 使用Array.isArray或者Object.prototype.toString.call方法可以从基本的对象中区分出数组类型
console.log(typeof {a:1} === 'object');
console.log(typeof [1, 2, 4] === 'object');
console.log(typeof /^[a-zA-Z]{5,20}$/ === 'object');
console.log(typeof {name:'wenzi', age:25} === 'object');
console.log(typeof null === 'object');//true
 
// 下面的容易令人迷惑,不要这样使用!
console.log(typeof new Boolean(true) === 'object');
console.log(typeof new Number(1) === 'object');
console.log(typeof new Date() === 'object');
console.log(typeof new String("abc") === 'object');
console.log(typeof new Error() === 'object');
 
// 函数
console.log(typeof function(){} === 'function');
console.log(typeof Math.sin === 'function');

typeof は上記の 7 種類のみをチェックできます

2.

のインスタンス

instanceof 演算子は、処理されるオブジェクトのタイプを識別するために使用され、開発者はオブジェクトが特定のタイプであることを明示的に確認する必要があります

1.instanceof はコンストラクターとは関係ありません

var A = function() {};
A.prototype = {};
 
var B = {};
console.log(A.constructor);//function Function() { [native code] }
console.log(B.constructor);//function Object() { [native code] }
 
var a = new A();
A.prototype = {};
 
var b = new A();
b.constructor = A.constructor;
 
console.log(a.constructor === A);//false
console.log(a.constructor);//function Object() { [native code] }
console.log(typeof A);//function Object() { [native code] }
 
console.log(a.constructor === b.constructor);//false
console.log(b.constructor);//function Function() { [native code] }
 
console.log(a instanceof A);//false
console.log(b instanceof A);//true

2. Instanceof は関係演算子とも呼ばれ、特定のコンストラクターのプロトタイプ属性が検出対象の別のオブジェクトのプロトタイプ チェーンに存在するかどうかを判断するために使用できます。

var str = new String("hello world");
console.log(str instanceof String);//true
console.log(String instanceof Function);//true
console.log(str instanceof Function);//false
3 番目の出力が false を返すのはなぜですか?元のアドレス: Javascript の instanceof についての質問

//表达式一的指向
console.log(str.__proto__ === String.prototype);//true
console.log(str instanceof String); //true
 
//表达式二的指向
console.log(String .__proto__ === Function.prototype);//true
console.log(String instanceof Function);//true
 
//表达式三的指向
console.log(str .__proto__ === String.prototype);//true
console.log(str .__proto__.__proto__ === String.prototype.__proto__);//true
console.log(str .__proto__.__proto__ === Object.prototype);//true
console.log(str .__proto__.__proto__.__proto__ === null);//true
console.log(str instanceof Object);//true
console.log(str instanceof Function);//false
別の複雑な使用法を見てみましょう

console.log(Object instanceof Object);//true
console.log(Function instanceof Function);//true
console.log(Number instanceof Number);//false
console.log(String instanceof String);//false
 
console.log(Function instanceof Object);//true
 
console.log(Foo instanceof Function);//true
console.log(Foo instanceof Foo);//false
なぜ、これは次の意味を理解する必要があります

1. この演算子は言語仕様でどのように定義されていますか?

2. JavaScript プロトタイプの継承メカニズム

オブジェクトのオブジェクト インスタンス

// 为了方便表述,首先区分左侧表达式和右侧表达式
ObjectL = Object, ObjectR = Object;
console.log(ObjectL instanceof ObjectR);//true


// 下面根据规范逐步推演
console.log(ObjectL.__proto__ === Function.prototype); //true
console.log(ObjectL.__proto__.__proto__ === Object.prototype);//true
関数のインスタンス


FunctionL = Function, FunctionR = Function;
console.log(FunctionL instanceof FunctionR);//true
console.log(FunctionL.__proto__ === Function.prototype); //true

<strong>Foo instanceof Foo
</strong>
function Foo(){}
var foo = new Foo();
FooL = Foo, FooR = Foo;
console.log(FooL instanceof FooR);//false
console.log(FooL.__proto__ === Function.prototype );//true
console.log(FooL.__proto__.__proto__ === Object.prototype );//true
console.log(FooL.__proto__.__proto__.__proto__ === null );//true

Dojo 継承メカニズムにおける instanceof のアプリケーション

JavaScript には、Java と同様に多重継承の概念がありません。ただし、declare を使用して Dojo でクラスを宣言する場合、複数のクラスから継承することが許可されます

dojo.declare("Aoo",null,{});
dojo.declare("Boo",null,{});
dojo.declare("Foo",[Aoo,Boo],{});
 
var foo = new Foo();
console.log(foo instanceof Aoo);//true
console.log(foo instanceof Boo);//false
 
console.log(foo.isInstanceOf(Aoo));//true
console.log(foo.isInstanceOf(Boo));//true
インスタンスと複数のグローバル オブジェクト (複数のフレームまたは複数のウィンドウ間の相互作用)

ブラウザでは、スクリプトは複数のウィンドウ間で対話する必要がある場合があります。複数のウィンドウは複数のグローバル環境を意味し、異なるグローバル環境には異なるグローバル オブジェクトが存在するため、異なる組み込み型コンストラクターが存在します。これにより、いくつかの問題が発生する可能性があります。たとえば、式 []instanceof window.frames[0].Array は、Array.prototype !== window.frames[0].Array.prototype であるため false を返すため、Array.isArray(myObj) または Object を使用する必要があります。 prototype.toString.call(myObj) === "[object Array]" で、myObj が配列かどうかを判断します。

// 以下代码在版本 Google Chrome 45.0.2454.101 m 中测试通过
// Numbers
console.log(37 instanceof Number);//false
console.log( 3.14 instanceof Number);.//false
console.log( Math.LN2 instanceof Number);//false
console.log( Infinity instanceof Number);//false
console.log( NaN instanceof Number); // false尽管NaN是"Not-A-Number"的缩写,意思是"不是一个数字"
console.log( Number(1) instanceof Number); // false不要这样使用!
 
// Strings
console.log( "" instanceof String);// false
console.log( "bla" instanceof String);// false
console.log( ( 1) instanceof String); // falseconsole.log(返回的肯定是一个字符串
console.log( String("abc") instanceof String); // false 不要这样使用!
 
// Booleans
console.log( true instanceof Boolean);// false
console.log( false instanceof Boolean);// false
console.log( Boolean(true) instanceof Boolean); //false 不要这样使用!
 
// Symbols
console.log( Symbol() instanceof Symbol);// false
console.log( Symbol("foo") instanceof Symbol);// false
console.log( Symbol.iterator instanceof Symbol);// false
 
// Undefined
var blabla;
//console.log( undefined instanceof Undefined);// Uncaught ReferenceError: Undefined is not defined
//console.log( blabla instanceof Undefined); // Uncaught ReferenceError: Undefined is not defined
console.log( undefined instanceof Object);// false
console.log( blabla instanceof Object);// false
 
// Objects 使用Array.isArray或者Object.prototype.toString.call方法可以从基本的对象中区分出数组类型
console.log( {a:1} instanceof Object);//true
console.log( [1, 2, 4] instanceof Object);//true
console.log( /^[a-zA-Z]{5,20}$/ instanceof Object);//true
console.log( {name:'wenzi', age:25} instanceof Object);//true
console.log( null === Object);//false
 
// 下面的容易令人迷惑,不要这样使用!
console.log( new Boolean(true) instanceof Object);//true
console.log( new Number(1) instanceof Object);//true
console.log( new Date() instanceof Object);//true
console.log( new String("abc") instanceof Object);//true
console.log( new Error() instanceof Object);//true
 
// 函数
console.log( function(){} instanceof Function );//true
console.log( Math.sin instanceof Function);//true
注: 未定義と null はオブジェクト タイプとして検出されます。js には未定義と Null のグローバル タイプがなく、数値、文字列、およびブール値はそれらのタイプを検出できないためです。

3. コンストラクター

instanceof を使用して変数の型を検出する場合、数値、'文字列'、およびブールの型を検出できません。したがって、この問題を解決する別の方法を見つける必要があります

Object.prototype.constructor は、オブジェクトのプロトタイプを作成した関数への参照を返します。このプロパティの値は関数名を含む文字列ではなく、関数そのものであることに注意してください。プリミティブ値 (1、true、「test」など) の場合、このプロパティは読み取り専用であり、すべてのオブジェクトはそのプロトタイプ

からコンストラクター プロパティを継承します。

コンストラクターはもともとプロトタイプ オブジェクトのプロパティであり、コンストラクターを指します。ただし、インスタンス オブジェクトが属性を検索する順序に従って、インスタンス オブジェクトにインスタンス属性またはメソッドがない場合は、プロトタイプ チェーン上で検索されます。そのため、インスタンス オブジェクトはコンストラクター属性

ただし、コンストラクター属性は変更される可能性があり、検出結果が不正確になる可能性があることに注意してください
function Person(){
 
}
var Tom = new Person();
 
console.log(Tom.constructor === Person);//true

このオブジェクトのコンストラクター プロパティの値を変更します
function Person(){
 
}
function Student(){
 
}
Student.prototype = new Person();
var John = new Student();
console.log(John.constructor==Student); // false
console.log(John.constructor==Person); // true

未定義と null を除き、他の型の変数の型はコンストラクターを使用して決定できます
function Type() { };
 
var types = [
  new Array,
  [],
  new Boolean,
  true,    // remains unchanged
  new Date,
  new Error,
  new Function,
  function(){},
  Math, 
  new Number,
  1,      // remains unchanged
  new Object,
  {},
  new RegExp,
  /(&#63;:)/,
  new String,
  "test"    // remains unchanged
];
 
for(var i = 0; i < types.length; i++) {
  types[i].constructor = Type;
  types[i] = [ types[i].constructor, types[i] instanceof Type, types[i].toString() ];
};
 
console.log( types.join("\n") );

4. ユニバーサル Object.prototype.toString.call

toString() メソッドを使用してオブジェクトの種類を検出します

JavaScriptのデータ型についてどれくらい知っていますか?
function Type() { };
 
var toString = Object.prototype.toString;
console.log(toString.call(new Date) === '[object Date]');//true
console.log(toString.call(new String) ==='[object String]');//true
console.log(toString.call(new Function) ==='[object Function]');//true
console.log(toString.call(Type) ==='[object Function]');//true
console.log(toString.call('str') ==='[object String]');//true
console.log(toString.call(Math) === '[object Math]');//true
console.log(toString.call(true) ==='[object Boolean]');//true
console.log(toString.call(/^[a-zA-Z]{5,20}$/) ==='[object RegExp]');//true
console.log(toString.call({name:'wenzi', age:25}) ==='[object Object]');//true
console.log(toString.call([1, 2, 3, 4]) ==='[object Array]');//true
//Since JavaScript 1.8.5
console.log(toString.call(undefined) === '[object Undefined]');//true
console.log(toString.call(null) === '[object Null]');//true

5. jquery jquery の実装: "1.8.2"、

jquery は $.type インターフェースを提供します。コードを見てください

jquery が Object.prototype.toString.call を使用して実装されていることがわかります
var m = Object.prototype.toString //501行
 
E = {};//512行
 
isFunction: function(a) { //645行
  return p.type(a) === "function"
},
isArray: Array.isArray || function(a) {
  return p.type(a) === "array"
}
,
isWindow: function(a) {
  return a != null && a == a.window
},
isNumeric: function(a) {
  return !isNaN(parseFloat(a)) && isFinite(a)
},
type: function(a) {
  return a == null &#63; String(a) : E[m.call(a)] || "object"
},
isPlainObject: function(a) {
  if (!a || p.type(a) !== "object" || a.nodeType || p.isWindow(a))
    return !1;
  try {
    if (a.constructor && !n.call(a, "constructor") && !n.call(a.constructor.prototype, "isPrototypeOf"))
      return !1
  } catch (c) {
    return !1
  }
  var d;
  for (d in a)
    ;
  return d === b || n.call(a, d)
},
isEmptyObject: function(a) {
  var b;
  for (b in a)
    return !1;
  return !0
},
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。