首頁 web前端 js教程 簡單談談Javascript中類型的判斷_javascript技巧

簡單談談Javascript中類型的判斷_javascript技巧

May 16, 2016 pm 03:36 PM
javascript

資料型態的判斷有這麼多種方式

1、一元運算子 typeOf

2、關係運算子 instanceof

3、constructor 屬性

4、prototype屬性

一、typeof

typeof的回傳值有以下幾種

類型 結構
Undefined "undefined"
Null "object" (見下方)
布林值 "boolean"
數值 "number"
字串 "string"
Symbol (ECMAScript 6 新增) "symbol"
宿主物件(JS環境提供的,如瀏覽器) Implementation-dependent
函數物件 (implements [[Call]] in ECMA-262 terms) "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幾種類型

二、instanceof

instanceof 運算子用於識別正在處理的物件的類型,要求開發者明確地確認物件為某特定類型

1、instanceof 和 constructor 沒有關係

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又叫關係運算符,可以用來判斷某個建構子的prototype屬性是否存在另外一個要偵測物件的原型鏈上

var str = new String("hello world");
console.log(str instanceof String);//true
console.log(String instanceof Function);//true
console.log(str instanceof Function);//false
登入後複製

第三次輸出為什麼會回傳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 原型繼承機制

Object instanceof Object

// 为了方便表述,首先区分左侧表达式和右侧表达式
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
登入後複製

Function instanceof Function

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

登入後複製

 instanceof 在 Dojo 繼承機制中的應用

在 JavaScript 中,是沒有多重繼承這個概念的,就像 Java 一樣。但在 Dojo 中使用 declare 宣告類別時,是允許繼承自多個類別的

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和多全域物件(多個frame或多個window之間的交互作用)

在瀏覽器中,我們的腳本可能需要在多個視窗之間進行互動。多個視窗意味著多個全域環境,不同的全域環境擁有不同的全域對象,從而擁有不同的內建類型建構函數。這可能會引發一些問題。例如,表達式[] instanceof window.frames[0].Array 會回傳false,因為Array.prototype !== window.frames[0].Array.prototype,因此你必須使用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
登入後複製

注意:undefined和null是偵測的Object類型,因為js中沒有Undefined和Null的這種全域類型,number, string和boolean無法偵測出它的類型

三、constructor

在使用instanceof檢測變數類型時,我們是偵測不到number, 'string', bool的類型的。因此,我們需要換個方式來解決這個問題

Object.prototype.constructor傳回一個指向建立了該物件原型的函數參考。需要注意的是,該屬性的值是那個函數本身,而不是一個包含函數名稱的字串。對於原始值(如1,true 或 "test"),該屬性為唯讀,所有物件都會從它的原型上繼承一個 constructor 屬性

constructor本來是原型物件上的屬性,指向建構子。但根據實例物件尋找屬性的順序,若實例物件上沒有實例屬性或方法時,就去原型鏈上尋找,因此,實例物件也是能使用constructor屬性的

function Person(){
 
}
var Tom = new Person();
 
console.log(Tom.constructor === Person);//true
登入後複製

不過要注意,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
登入後複製

改變這個物件的constructor屬性的值

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") );
登入後複製

除了undefined和null,其他類型的變數均能使用constructor判斷類型

四、萬能的Object.prototype.toString.call

使用toString()方法偵測物件類型

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
登入後複製

附上判斷函數 Javascript中的資料型別知多少

五、jquery的實作  jquery: "1.8.2",

jquery中提供了一個$.type的接口,看看代碼

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
},
登入後複製

可以看出來,jquery中就是用Object.prototype.toString.call實作的

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

javascript如何使用insertBefore javascript如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

JavaScript與WebSocket:打造高效率的即時影像處理系統 JavaScript與WebSocket:打造高效率的即時影像處理系統 Dec 17, 2023 am 08:41 AM

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數

See all articles