您好,登錄后才能下訂單哦!
這篇文章主要介紹JavaScript中數據類型的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
一,數據類型
以下內容基于ES5(ES6引入了一種新的原始數據類型Symbol,表示獨一無二的值。它是JavaScript語言的第七種數據類型。)
JavaScript是一種弱類型動態語言,定義變量時無需指定類型,看似簡單,但背后有繁瑣的轉換邏輯。讓我們一起來看下js常見的數據類型和背后的隱式轉換邏輯。
ES5中有5種簡單的數據類型(也叫基本數據類型):number,string,boolean,null,undefined(null和undefined是兩種特殊的基本數據類型,下面會講到);還有一種復雜數據類型——Object(函數是一種特殊的對象,后面會講到)
Undefined類型:
Undefined類型只有一個值,即特殊的undefined。在使用var聲明變量但未對其加以初始化時,這個變量的值就是undefined,例如:
var message; alert(message == undefined);//true
這個例子只聲明了變量message,但未對其進行初始化。比較這個變量與undefined字面量,結果表明它們是相等的。這個例子與下面的例子是等價的:
var message = undefined; alert(message == undefined);//true
這個例子是用undefined值顯示初始化了變量message.但我們沒有必要這么做,因為未經初始化的值默認都會取得undefined值。
(一般而言,不存在需要顯示地把一個變量設置為undefined值的情況。字面值undefined的主要目的是用于比較,而ECMA-262第3版之前的版本中并沒有規定這個值。第3版引入這個值是為了正式區分空對象指針與未經初始化的變量。)
不過,包含undefined值的變量與尚未定義的變量還是不一樣的。請看下面的例子:
var message;//這個變量聲明之后默認取得了undefined值 //下面這個變量并沒有聲明 //var age alert(message);//'undefined' alert(age);//產生錯誤 Uncaught ReferenceError: age is not defined(…)
運行以上代碼,第一個警告框會顯示變量message的值,即'undefined'。而第二個警告框由于傳遞給alert()函數的是尚未聲明的變量age,則會導致一個錯誤。對于尚未聲明過的變量,只能執行一項操作,即使用typeof操作符檢測其數據類型。
然而,令人困惑的是:對未初始化的變量執行typeof操作符會返回undefined值,而對未聲明的變量執行typeof操作符同樣也會返回undefined值。來看下面的例子:
var message;//這個變量聲明之后默認取得了undefined值 //下面這個變量并沒有聲明 //var age alert(typeof message);//'undefined' alert(typeof age);//'undefined'
結果表明,對未初始化和未聲明的變量執行typeof操作符都返回了undefined值,這個結果有其邏輯上的合理性,因為雖然這兩種變量從技術角度看有本質區別,但實際上無論對哪種變量也不可能執行真正的操作。
(即使未初始化的變量會自動被賦予undefined值,但我們仍然建議讀者養成顯式初始化變量-即在聲明變量的同時給變量賦值的習慣。如果能夠做到這一點,那么當typeof操作符返回undefined值時,我們就知道被檢測的變量是還沒有被聲明的,而不是尚未初始化的了。)
Null類型
Null類型是第二個只有一個值的數據類型,這個特殊的值就是null。從邏輯角度來看,null值表示一個空對象指針,而這也正是typeof操作符檢測null值會返回'Object'的原因,如下面的例子所示:
var car = null; alert(typeof car);//'object'
如果定義的變量準備在將來用于保存對象,那么最好將該變量初始化為null而不是其他值。這樣一來,只要直接檢查null值就可以知道相應的變量是否已經保存了一個對象的引用了,如下面的例子所示:
if(car != null){ //對car執行某些操作 }
實際上,undefined值是派生自null值的,因此ECMA-262規定對它們的相等性測試要返回true;
alert(null == undefined);//'true'
這里,位于null和undefined之間的相等操作符(==)總是返回true,不過要注意的是,這個操作符出于比較的目的會轉換其操作數(后面會詳細介紹相關內容)。
盡管null和udefined有這樣的關系,但它們的用途完全不同。如前所述,無論在什么情況下,都沒有必要把一個變量的值顯式地設置為undefined,可是同樣的規則對null卻不適用。換句話說,只要意在保存對象的變量還沒有真正保存對象,就應該明確地讓該變量保存null值。這樣做不僅可以體現null作為空對象指針的慣例,而且也有助于進一步區分null和undefined。
二,隱式轉換
+和-
在js中,雖然我們不需要顯式地定義變量的類型,但在實際的處理中,會根據不同的類型,會有不同的處理。先看幾個例子:
var x = 'The answer is ' + 42;//"The answer is 42" 這里的'+'會理解為字符串拼接 var y = 42 + ' is the answer';//"42 is the answer" 這里的'+'會理解為字符串拼接 '37' + 7;//"377" 這里的'+'會理解為字符串拼接 '37' - 7;//30 這里的'-'會理解為減法運算
我們也可以巧用類型轉換,去做一些事情,比如想把一個變量num轉換為數字類型,非常簡單的辦法就是減去數字‘0',如果想把一個變量num變為字符串類型,那么可以加上一個空字符串''。
var num; num = num - 0; alert(typeof num);//"number" num = num + ''; alert(typeof num);//"string"
===
嚴格等于a===b,首先會判斷等號兩邊的類型,如果兩邊的類型不同,直接返回false,不再往下進行,如果類型相同,判斷值是否想等。需注意NaN和任何東西比較都不想等,包括和自己比較也不想等。另外,JavaScript中的對象的比較是用引用去比較,而不是用值去比較,所以比較兩個對象也不相等,因為不是兩個完全相同的對象。可以定義變量x(不區分類型),讓x和x比較,返回true。
'1.23' === '1.23';//true null === null;//true undefined == undefined;//true null === undefined;//false NaN === NaN;//false NaN屬于number值,和任何東西比較都不想等,包括和自己比較也不想等 NaN == NaN;//false NaN屬于number值,和任何東西比較都不想等,包括和自己比較也不想等 [1,2] == [1,2];//false 由于js中對象的比較是用引用去比較,雖然兩邊都是數組,而且長度一樣、相同的值、相同的順序,也是不等的,因為不是完全相同的對象。 new Object() == new Object();//false 引用比較,兩個空對象是不同的兩個對象,不相等。 var x; x === x;//true 定義變量x,,讓x和x比較 返回true
==
如果類型相同,比較方法同'===',如果類型不同,會嘗試類型轉換和比較:
null == undefined //相等 number == string //嘗試把string轉換成number再去比較 1.0 == '1.0';//true boolean == ? //無論右邊是什么,會先把boolean先轉換成數字,true轉換成1,false轉換成0,然后再去和右邊的比較 true == 1; //true. object == number | string //會嘗試把對象轉換為基本類型再去比較 其他的情況是false. new String('hi') == 'hi';//true new Boolean(false) == 0;//true
三,包裝對象
number,string,boolean這三種基本類型都有對應的包裝類型,先看一個例子:
從上面的例子可以看出,js中當把一個基本類型(比如string類型)嘗試以對象的方式去使用的時候,比如訪問它的length屬性,或者增加一些屬性的時候,js會很智能地把被操作的基本類型轉換成對應的包裝類型對象,(相當于new String()),這個臨時包裝對象的內容和基本類型的值是一樣的,當完成訪問或者屬性設置的時候,這個臨時包裝對象會被銷毀掉,所以再去訪問已經設置的屬性,是訪問不到的。number和boolean基本類型轉換成包裝類型對象的原理都是一樣的。
var a = 'string';//定義變量a,賦值基本類型'string' alert(a.length);//"6" 創建對應的臨時包裝對象,訪問臨時包裝對象的length屬性,得到結果6 a.t = 3;//3,設置成功后,臨時對象被銷毀,所以下面alert值是undefined alert(a.t);//"undefined"
var b = 123; b.toString();//"123" 調用對應臨時包裝對象Number()上的toString()方法,轉換成字符串
四,類型檢測
1,最常見的是用typeof操作符,會返回一個字符串,適合函數對象和基本類型的判斷,遇到null失效,會返回Object。
typeof 100 //"number" 數值 typeof NaN; //"number" 數值 typeof Infinity;//"number" 數值 typeof true //"Boolean" 布爾值 typeof(undefined); //"undefined" 表示這個值未定義 typeof new Object(); //"object" 對象 typeof [1, 2]; //"object" 數組是對象,沒有特殊處理 typeof null; //"object" null值表示一個空對象指針,所以返回Object typeof function //"function" 從技術角度講,函數在ECMAScript中是對象,不是一種數據類型,然而,函數也確實有一些特殊的屬性,因此通過typeof操作符來區分函數和其他對象是有必要的
2,如果要判斷對象類型,常用的是instanceof,適合自定義對象,也可以用來檢測原生對象,在不同iframe和window間檢測時失效,是基于原型鏈去判斷,instanceof原理: 判斷obj對象的原型鏈上是否有右邊的構造函數的prototype屬性,關于原型鏈,詳見后面篇章。
obj instanceof Object(obj:必須是對象,如果是基本類型,直接會返回false; Object:必須是函數對象,或者函數構造器,如果不是,就會拋出TypeError異常。)
看下簡單的例子
new Object() instanceof Array === false //true [1, 2] instanceof Array === true //true [] instanceof Array===true//true
我們知道,任何一個構造函數,都有一個prototype對象屬性,這個對象屬性將用作使用new構造函數這種方式構造出的對象的原型。比如Person這個函數,函數有prototype屬性. 我們用new Person()去創建Person實例的時候,這個對象實例就會有一個原型指向Person.prototype這個對象。我們用var bosn=new Student(),創建一個Student實例bosn,bosn的原型會指向它的構造器Student的prototype對象屬性。檢測bosn instanceof Person時,bosn.__proto__=Student.prototype,然后原型鏈會繼續往上查找,bosn.__proto__.__proto__=person.prototype.就會返回true。注意,不同window或iframe間的對象類型檢測不能使用instanceof!
3,Object.prototype.toString()判斷類型,適合內置對象和基本類型,遇到null和undefined失效,IE6/IE7/IE8返回'[object Object]'
Object.prototype.toString.apply([]);==='[object Array]'; Object.prototype.toString.apply(function(){});==='[object Function]'; Object.prototype.toString.apply(null);==='[object Null]';//IE6/IE7/IE8返回'[object Object]' Object.prototype.toString.apply(undefined);==='[object Undefined]';//IE6/IE7/IE8返回'[object Object]' Object.prototype.toString.apply('123');==="[object String]"; Object.prototype.toString.apply(123);==="[object Number]"; Object.prototype.toString.apply(true);==="[object Boolean]"; Object.prototype.toString.apply(String);==="[object Function]"; Object.prototype.toString.apply(Boolean);==="[object Function]"
4,constructor檢測類型
任何一個對象都有一個constructor屬性,繼承自原型,會執向構造這個對象的構造函數, constructor可以被改寫,使用時要小心。
5,duck type檢測類型
比如我們不知道一個對象是否是數組,我們可以判斷這個對象的length是否是數字,是否有join,push等數組的函數方法,通過特征判斷對象是否屬于某些類型,有時也會用到。
以上是“JavaScript中數據類型的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。