溫故js系列(1)-基本數據類型和引用數據類型判斷&存儲訪問&類型轉換

前端學習:教程&開發模塊化/規範化/工程化/優化&工具/調試&值得關注的博客/Git&面試-前端資源彙總前端

歡迎提issues斧正:數據類型git

回味,無窮!程序員

數據類型定義

數據類型分類

基本數據類型:String,boolean,Number,Symbol(ES6新增),Undefined, Null
引用數據類型:Object
基本數據類型中有兩個爲特殊數據類型: null, undefined
js的常見內置對象:Date,Array,Math,Number,Boolean,String,Array,RegExp,Function...github

數據類型訪問&&複製

基本數據類型:基本數據類型值指保存在棧內存中的簡單數據段。訪問方式是按值訪問。面試

var a = 1;

圖片描述

操做的是變量實際保存的值。數組

a = 2;

圖片描述

基本類型變量的複製:從一個變量向一個變量複製時,會在棧中建立一個新值,而後把值複製到爲新變量分配的位置上。數據結構

var b = a;

圖片描述

b = 2;

圖片描述

引用數據類型:引用數據類型值指保存在堆內存中的對象。也就是,變量中保存的實際上的只是一個指針,這個指針指向內存中的另外一個位置,該位置保存着對象。訪問方式是按引用訪問。模塊化

var a = new Object();

圖片描述

當操做時,須要先從棧中讀取內存地址,而後再延指針找到保存在堆內存中的值再操做。函數

a.name = 'xz';

圖片描述

引用類型變量的複製:複製的是存儲在棧中的指針,將指針複製到棧中未新變量分配的空間中,而這個指針副本和原指針指向存儲在堆中的同一個對象;複製操做結束後,兩個變量實際上將引用同一個對象。所以,在使用時,改變其中的一個變量的值,將影響另外一個變量。工具

var b = a;

圖片描述

b.sex = 'boy';

圖片描述

漏畫了,差一條指針。b的引用指針也指向object{sex:'boy'}

b.sex;  //'boy'   a.name; //'boy'

堆&棧

二者都是存放臨時數據的地方。
棧是先進後出的,就像一個桶,後進去的先出來,它下面原本有的東西要等其餘出來以後才能出來。
堆是在程序運行時,而不是在程序編譯時,申請某個大小的內存空間。即動態分配內存,對其訪問和對通常內存的訪問沒有區別。對於堆,咱們能夠爲所欲爲的進行增長變量和刪除變量,不用遵循次序。
棧區(stack) 由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。
堆區(heap) 通常由程序員分配釋放,若程序員不釋放,程序結束時可能由OS回收。
堆(數據結構):堆能夠被當作是一棵樹,如:堆排序;
棧(數據結構):一種先進後出的數據結構。

數據類型檢測

Typeof

typeof操做符是檢測基本類型的最佳工具。

"undefined" — 未定義
"boolean"   — 布爾值
"string"    — 字符串
"number"    — 數值
"object"    — 對象或null
"function"  — 函數

Instanceof

instanceof用於檢測引用類型,能夠檢測到它是什麼類型的實例。
instanceof 檢測一個對象A是否是另外一個對象B的實例的原理是:查看對象B的prototype指向的對象是否在對象A的[[prototype]]鏈上。若是在,則返回true,若是不在則返回false。不過有一個特殊的狀況,當對象B的prototype爲null將會報錯(相似於空指針異常)。

var sXzaver = new String("Xzavier"); 
console.log(sXzaver instanceof String);   //  "true"
var aXzaver = [1,2,3]; 
console.log(aXzaver instanceof Array);   //  "true"
檢測數組在ECMA Script5中定義了一個新方法Array.isArray()

Constructor

constructor屬性返回對建立此對象的數組函數的引用。能夠用於檢測自定義類型。

'xz'.constructor == String // true
(123).constructor == Number // true
(true).constructor == Boolean // true
[1,2].constructor == Array // true
({name:'xz'}).constructor == Object // true
(function(){}).constructor == Function // true
(new Date()).constructor == Date // true
(Symbol()).constructor == Symbol // true
(/xz/).constructor == RegExp // true

constructor不適用於null和undefined。除了這些原生的,constructor還可驗證自定義類型。

function Xzavier(){}
var xz = new Xzavier();
xz.constructor == Xzavier;  // true

Object.prototype.toString.call(obj)

推薦使用:Object.prototype.toString.call(obj)

原理:調用從Object繼承來的原始的toString()方法

Object.prototype.toString.call('xz'); //"[object String]"
Object.prototype.toString.call(123);  //"[object Number]"
Object.prototype.toString.call(true); //"[object Boolean]"
Object.prototype.toString.call([1,2]); //"[object Array]"
Object.prototype.toString.call({name:'xz'}); //"[object Object]"
Object.prototype.toString.call(function(){}); //"[object Function]"
Object.prototype.toString.call(null); //"[object Null]"
Object.prototype.toString.call(undefined); //"[object Undefined]"
Object.prototype.toString.call(); //"[object Undefined]"
Object.prototype.toString.call(new Date()); //"[object Date]"
Object.prototype.toString.call(/xz/);  //"[object RegExp]"
Object.prototype.toString.call(Symbol()); //"[object Symbol]"

var obj = {name:"Xzavier", age:23};
var a = [1,2,3];

function isType(obj) {
    return Object.prototype.toString.call(obj).slice(8, -1);
}
isType(obj);  // "Object" 
isType(a)  // "Array"

數據類型轉換

隱式轉換

undefined == null;  // true   
1 == true;  // true  
2 == true;  // false  
0 == false;  // true
0 == '';  // true   
NaN == NaN;  // false  NaN不等於任何值
[] == false;  // true  
[] == ![];  // true
'6' - '3'  // 3
1234 + 'abcd' // "1234abcd"

1.undefined與null相等,但不恆等(===)
2.一個是number一個是string時,會嘗試將string轉換爲number
3.隱式轉換將boolean轉換爲number,0或1
4.隱式轉換將Object轉換成number或string,取決於另一個對比量的類型
5.對於0、空字符串的判斷,建議使用 「===」 。
6.「==」會對不一樣類型值進行類型轉換再判斷,「===」則不會。它會先判斷兩邊的值類型,類型不匹配時直接爲false。

顯示轉換

顯示轉換通常指使用Number、String和Boolean三個構造函數,手動將各類類型的值,轉換成數字、字符串或者布爾值。

Number:

Number('1234') // 1234
Number('1234abcd') // NaN
Number('') // 0
Number(true) // 1
Number(null) // 0
Number(undefined) // NaN

String:

String(1234)  // "1234"
String('abcd')  // "abcd"
String(true)  // "true"
String(undefined) // "undefined"
String(null)  // "null"

Boolean:

Boolean(0)  // false
Boolean(undefined)  // false
Boolean(null)  // false
Boolean(NaN)  // false
Boolean('')  // false

使用總,!!至關於Boolean:

!!'foo';   // true
!!'';      // false
!!'0';     // true
!!'1';     // true
!!'-1'     // true
!!{};      // true
!!true;    // true

Number、String、Boolean轉換對象時主要使用了對象內部的valueOf和toString方法進行轉換。

Number轉換對象:

1.先調用對象自身的valueOf方法。若是返回原始類型的值,則直接對該值使用Number函數,返回結果。
2.若是valueOf返回的仍是對象,繼續調用對象自身的toString方法。若是toString返回原始類型的值,則對該值使用Number函數,返回結果。
3.若是toString返回的仍是對象,報錯。

Number([1]); //1
轉換演變:
[1].valueOf(); // [1];
[1].toString(); // '1';
Number('1'); //1

String轉換對象

1.先調用對象自身的toString方法。若是返回原始類型的值,則對該值使用String函數,返回結果。
2.若是toString返回的是對象,繼續調用valueOf方法。若是valueOf返回原始類型的值,則對該值使用String函數,返回結果。
3.若是valueOf返回的仍是對象,報錯。

String([1,2]) //"1,2"
轉化演變:
[1,2].toString();  //"1,2"
String("1,2");  //"1,2"

Boolean轉換對象

Boolean轉換對象很特別,除了如下六個值轉換爲false,其餘都爲true

undefined  null  false  0(包括+0和-0)  NaN  空字符串('')
Boolean(undefined)   //false
Boolean(null)        //false
Boolean(false)       //false
Boolean(0)           //false
Boolean(NaN)         //false
Boolean('')          //false

Boolean([])          //true
Boolean({})          //true
Boolean(new Date())  //true

寫寫博客打打球...要代碼,要籃球,更要生活。。。

相關文章
相關標籤/搜索