前言
看不懂系列 [滑稽.jpg] 最近在找工作,後面的部落格內容也算自己的準備了,嘿嘿 其實自己平常看書的時候,也會發現很多東西講的太官話,有點看不懂 有些資料呢,可能又將的太碎片化了, 所以我經常把書上知識點當做一個擴散點,去擴充套件一些原來不知道的 像這篇,其實講隱式轉換的文章還是比較多,好的也比較多的 但可能我太小白了,有些一筆帶過的內容比如說,原始值,引用值,toString,valueOf這些一筆帶過 所以在講之前先鋪墊鋪墊 講些原理 PS: 小白一個 歡迎吐槽 嘿嘿嘿
原始值和引用值
原始值
儲存在棧(stack)中的簡單資料段,也就是說,它們的值直接儲存在變數訪問的位置。
Undefined、Null、Boolean、Number 和 String 由於這些原始型別佔據的空間是固定的,所以可將他們儲存在較小的記憶體區域 - 棧中。這樣儲存便於迅速查尋變數的值。
引用值
儲存在堆(heap)中的物件,也就是說,儲存在變數處的值是一個指標(point),指向儲存物件的記憶體處。
object,Array , 函式
儲存在變數處的值是一個指標(point),指向儲存物件的記憶體處。
var a = "i am string";
typeof a; // "string"
a instanceof String //false
var b = new String("i am a string");
typeof b; // "object"
b instanceof String //true
複製程式碼
WTF ???
WHY ???
一開始看這道題的時候滿臉問號
其實吧 這是因為 "i am string" 他是一個原始值
But
"i am string".length // 8 這些本屬於String的方法卻能被呼叫
複製程式碼
這是應為在必要時。js語言會把字串字面量轉換成String物件。也就是你並不需要顯示的建立一個物件valueOf()
toString valueOf()
toString 使用方法
var x = {};
console.log(x.toString());
// [object Object]
//特別的用法
toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
var x = [1,2,3];
x.toString(); //返回'1,2,3'
var x = function(){console.log('lalala')}
x.toString();// 返回'function(){console.log('lalala')}'
var x = 33333;
x.toString();// 返回'33333'
複製程式碼
網上copy的一段示例,接下來詳細瞭解一下toString()常用語法
obj.toString();
這種使用形式可以把除null undefined外,所有物件轉為字串
//boolean型別
true.toString() //true
false.toString() // false
//string型別
var str = "stringlalala"
str.toString() //"stringlalala"
複製程式碼
但是下面出現了一個非常好玩的現象
// Object
var obj = {
name: "MrZss",
age: "23"
};
obj.toString(); //[object Object]
// Array
var arr = ["MrZss","23"];
arr.toString(); // "MrZss","23"
//Date
var date = new Date();//
date.toString() // Wed Feb 27 2019 13:46:35 GMT+0800 (CST)
// Number
var num = 23;
var num = 23;
console.log(num.toString(2)); //10111 二進位制
console.log(num.toString(8)); //27 八進位制
console.log(num.toString(16)); //17 十六進位制
複製程式碼
問題來了 按理來說 Array Date這些物件toString方法 都是從Object物件繼承來的呀。為什麼表現完全不一樣
友情提醒:Array,RegExp,Date,Number等內建物件中的toString重寫了,用於本身的型別轉化
Object.prototype.toString()
來來來 敲黑板畫重點了
實在不行就一鍵翻譯吧 [滑稽.jpg]
這一塊我也去搜了搜大佬的資料,看這個理解的比較詳細
所以,可以使用Object.prototype上的原生toString()方法判斷資料型別
因為其他物件例如Array,Date的toString方法都沒覆蓋了 所以還是需要使用
Object.prototype.toString.call(value) 來調取
Object.prototype.toString.call(null);//”[object Null]”
Object.prototype.toString.call(undefined);//”[object Undefined]”
Object.prototype.toString.call(“abc”);//”[object String]”
Object.prototype.toString.call(123);//”[object Number]”
Object.prototype.toString.call(true);//”[object Boolean]”
....
就不一一列舉了
可以自己414
複製程式碼
Object.prototype.toString.call、instanceof、typeof又有啥不同呢
typeof undefined //undefined
typeof null //object
typeof true //boolean
typeof 1.11 //number
typeof "lalala" //string
typeof function(){} //function
typeof new Object() //object
typeof new Array() //object
typeof new RegExp() //object
複製程式碼
typeof 的侷限性
在於 像Array,RegExp,null都會被判斷為object,這就很尷尬了,無法去判斷這些內建物件的具體型別
instanceof 的侷限性
在於你必須知道實際型別和父型別再去判斷對與,,對未知建構函式構造的物件來說無法提前給定,constructor屬性返回的值又不是預期的單純的建構函式名。
Object.prototype.toString 的侷限性
Object.prototype.toString 就非常牛批了,對所有的內建物件都能支援得非常好 唯一不好的地方 自定義的構建的物件,無法通過原型鏈去查父型別
Object.prototype.toString.call(''); //[object String]
Object.prototype.toString.call(undefined); // [object Undefined]
Object.prototype.toString.call(null); //[object Null]
Object.prototype.toString.call(1111); // [object Number]
Object.prototype.toString.call(true); //[object Boolean]
複製程式碼
valueOf
這個方法在Array等物件中也會被覆寫
表現形式如下
先盜一個MDN的圖嘿嘿
好了鋪墊完了,待會進入正題