JavaScriptのデータ型決定に関するまとめメモ_基礎知識

WBOY
リリース: 2016-05-16 15:47:41
オリジナル
959 人が閲覧しました

typeof を使用してデータ型を検出します
JavaScript には、基本データ型 (未定義、文字列、null、ブール、関数、オブジェクト) とオブジェクト型の 2 つの型セットが付属しています。

しかし、typeof を使用してオブジェクトのタイプを検出しようとすると、常に「object」が返され、区別できません

typeof null // "object"
typeof []  // "object"
typeof document.childNodes //"object"
typeof /\d/ //"object"
typeof new Number() //"object"
ログイン後にコピー

constructor 属性を使用して型のコンストラクターを検出します

[].constructor === Array  //true
document.childNodes === NodeList  //true
/\d/.constructor === RegExp   //true
 
function isRegExp(obj) {
  return obj && typeof obj === "object" && obj.constructor === RegExp;
} //检测正则表达式对象
 
function isNull(obj){
  return obj === null;
}
ログイン後にコピー

構造検出を使用すると、ほとんどの型検出を完了でき、null は特別に直接比較されます。ただし、iframe 内の配列型の正しい型を検出できません。これは、コンストラクトによって検出される欠陥であると同時に、古いバージョンの IE

では DOM と BOM のコンストラクトにアクセスできません。

Object.prototype.toString を使用して

を決定します
Object.prototype.toString.call([]) //"[object Array]"
Object.prototype.toString.call(/\d/) // "[object RegExp]"
Object.prototype.toString.call(1)//"[object Number]"
ログイン後にコピー

見てみましょうjQuery ソース コードで toString メソッドを使用する方法

/*
* jQuery JavaScript Library v1.11.2
*/
var class2type = {};  //用来保存js数据类型
 
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {//构造class2type存储常用类型的映射关系,遍历基本类型并赋值,键值为 [object 类型]
 class2type[ "[object " + name + "]" ] = name.toLowerCase();
});
type: function( obj ) {
  if ( obj == null ) {//首先如果是null则返回null字符串
   return obj + "";
  }
//接着判断给定参数类型是否为object或者function,是的话在映射表中寻找 toString后的键值名称并返回,不是的话利用typeof就可以得到正确类型。
  return typeof obj === "object" || typeof obj === "function" ?
   class2type[ toString.call(obj) ] || "object" :
   typeof obj;
 },
/****************************/ 
jQuery.type(/\d/)  //"regexp"
jQuery.type(new Number())  //"number"
ログイン後にコピー

さまざまなオブジェクトが独自の toString メソッドを再定義するため、ここで toString メソッドを使用して検出できます

いくつかの特殊なタイプの検出について話しましょう

上記のデバッグは、javascript のキーワードではないため、IE8 で実行されました。jQuery.type のソース コードを見ると、未定義であることがわかります。タイプが未定義であることの検出が完了しました。 jQuery.type は、古い IE では未定義を正しく検出しません。純粋な未定義を取得したい場合は、 void 0

を使用できます。

また、DOM および BOM オブジェクトの場合、古い IE では Objec.prototype.toString を使用して検出される値はすべて「[object Object]」です

しかし、Chrome での結果は完全に異なります (Chrome は実際の型を検出できます)

jQuery 検出の特殊な型について学習します

isWindow: function( obj ) {//ECMA规定window为全局对象global,且global.window === global
 return obj != null && obj == obj.window;
},
isPlainObject: function( obj ) {
 var key;
 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
  return false;
 }
 try {//判断它最近的原形对象是否含有isPrototypeOf属性
  if ( obj.constructor &&
   !hasOwn.call(obj, "constructor") &&
   !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
   return false;
  }
 } catch ( e ) {
  return false;
 }
 if ( support.ownLast ) {
  for ( key in obj ) {
   return hasOwn.call( obj, key );
  }
 }
ログイン後にコピー

jQuery と比較した Mass Framework の改善点

var class2type = {//将可能出现的类型都映射在了class2type对象中,从而减少isXXX函数
  "[object HTMLDocument]": "Document",
  "[object HTMLCollection]": "NodeList",
  "[object StaticNodeList]": "NodeList",
  "[object DOMWindow]": "Window",
  "[object global]": "Window",
  "null": "Null",
  "NaN": "NaN",
  "undefined": "Undefined"
 };
type: function(obj, str) {
   var result = class2type[(obj == null || obj !== obj) ? obj : serialize.call(obj)] || obj.nodeName || "#"; //serialize == class2type.toString
   if (result.charAt(0) === "#") { //兼容旧式浏览器与处理个别情况,如window.opera
    //利用IE678 window == document为true,document == window竟然为false的神奇特性
    if (obj == obj.document && obj.document != obj) {//对DOM,BOM对象采用nodeType(单一)和item(节点集合)进行判断
     result = "Window"; //返回构造器名字
    } else if (obj.nodeType === 9) {
     result = "Document"; //返回构造器名字
    } else if (obj.callee) {
     result = "Arguments"; //返回构造器名字
    } else if (isFinite(obj.length) && obj.item) {
     result = "NodeList"; //处理节点集合
    } else {
     result = serialize.call(obj).slice(8, -1);
    }
   }
   if (str) {
    return str === result;
   }
   return result;
  }
ログイン後にコピー

配列のような

配列のような配列は、配列に似ていますが、配列メソッドを使用できない特殊なタイプのデータです。その明らかな特徴の 1 つは、長さ属性が含まれており、キー値が順序どおりに配置されていることです。整数を使用します。このような配列は、Array が提供するメソッドを使用し、Array.slice() などのメソッドを通じて実際の配列に変換できます。

共通クラス配列: 引数、document.forms、document.getElementsByClassName (一連のノード コレクション NodeList、HTMLCollection など)、または以下に示すいくつかの特別なオブジェクト:

var arrayLike={ 
   0:"a", 
   1:"b", 
   2:"c", 
   length:3 
}
ログイン後にコピー

通常、Array.slice.call を通じてクラス配列を変換できますが、古い IE の HTMLCollection と NodeList は Object のサブクラスではないため、現時点ではこのメソッドを使用できません。次に、トラバースされたノードをプッシュします。たとえば、空の配列では、新しく生成された配列を返し、ウィンドウ オブジェクトと文字列オブジェクトを区別します。これは、そのようなオブジェクトには長さ >= 0 (長さは変更できません) も含まれますが、それらは異なります。配列っぽい。

jQuery による配列のような処理方法

makeArray: function( arr, results ) {
 var ret = results || [];
 if ( arr != null ) {
  if ( isArraylike( Object(arr) ) ) {
   jQuery.merge( ret,
    typeof arr === "string" ?
    [ arr ] : arr
   );  //jQuery.merge 合并数组 ,若是字符串则封装成数组河滨,不是则世界合并
  } else {
   push.call( ret, arr );
  }
 }
 return ret;
}
ログイン後にコピー

Ext.js が配列を処理する方法

toArray: function(iterable, start, end) {
    if (!iterable || !iterable.length) {
     return [];  //非类数组类型直接返回[]
    }
    if (typeof iterable === 'string') {
     iterable = iterable.split('');  //分解字符串
    }
    if (supportsSliceOnNodeList) {
     return slice.call(iterable, start || 0, end || iterable.length); //对于NodeList支持
    }
    var array = [],
     i;
    start = start || 0;
    end = end &#63; ((end < 0) &#63; iterable.length + end : end) : iterable.length;
    for (i = start; i < end; i++) {
     array.push(iterable[i]);
    }
    return array;
   }
ログイン後にコピー

大量の Framework.js がクラス配列を処理する方法

slice: W3C &#63; function(nodes, start, end) { //var W3C = DOC.dispatchEvent; IE9开始支持W3C的事件模型
 return factorys.slice.call(nodes, start, end);
} : function(nodes, start, end) {
 var ret = [],
   n = nodes.length;
 if (end === void 0 || typeof end === "number" && isFinite(end)) {
  start = parseInt(start, 10) || 0;
  end = end == void 0 &#63; n : parseInt(end, 10);
  if (start < 0) {
   start += n;
  }
  if (end > n) {
   end = n;
  }
  if (end < 0) {
   end += n;
  }
  for (var i = start; i < end; ++i) {
   ret[i - start] = nodes[i];
  }
 }
 return ret;
ログイン後にコピー

以上がこの記事の全内容です。皆様の学習にお役に立てれば幸いです

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート