JavaScript中toStirng()與Object.prototype.toString.call()方法淺談


toStirng()與Object.prototype.toString.call()方法淺談

一、toString()是一個怎樣的方法?它是能將某一個值轉化為字符串的方法。然而它是如何將一個值從一種類型轉化為字符串類型的呢?

通過下面幾個例子,我們便能獲得答案:

1.將boolean類型的值轉化為string類型:

console.log(true.toString());//"true"
console.log(false.toString());//"false"

2.將string類型按其字面量形式輸出:

var str = "test123y";
console.log(str.toString());//"test123y"

3.將Object類型轉化成string類型(JavaScript原生的Array類型、Date類型、RegExp類型以及Number、Boolean、String這些包裝類型都是Object的子類型):

自定義Object類型(沒有重新定義toString方法):
var obj = {name:"Tom", age:18};
console.log(obj.toString());//"[object Object]"此時調用的是從Object繼承來的原始的toString()方法

接下來的三個例子都是以重寫的方式實現了toString()方法;

1.Array類型:

var arr = ["tom",12,"rose",18];
console.log(arr.toString());//"tom,12,rose,18"

2.RegExp類型

var patten = new RegExp("\\[hbc\\]at", "gi");
console.log(patten.toString());//"/\[hbc\]at/gi"

3.Date類型

var date = new Date(2014,02,26);//注意這種格式創建的日期,其月份是3月
console.log(date.toString());//"Wed Mar 26 2014 00:00:00 GMT+0800"輸出格式因瀏覽器不同而不同,此為firefox的輸出格式;

4.Number類型也是以重寫的方式實現toString()方法的,請看以下例子:

(1)它可以接受一個整數參數,並將調用這個方法的數值轉化成相應進制的字符串:

var num = 16;
console.log(num.toString(2));//10000 二進制
console.log(num.toString(8));//20 八進制
console.log(num.toString(16));//10 十六進制
console.log(num.toString(5));//31 雖然沒有五進制,但是這樣傳參是可以被toString()方法接受的

(2)再看下面的代碼:

console.log(1.toString());//這種寫法會報錯語法錯誤,但是下面的寫法都是合法的;
console.log((1).toString());//"1"
console.log(typeof (1).toString());//string
console.log(1..toString());//"1"
console.log(typeof (1).toString());//string
console.log(1.2.toString());//"1"
console.log(typeof (1).toString());//string
這是因為javascript引擎在解釋代碼時對於“1.toString()”認為“.”是浮點符號,但因小數點后面的字符是非法的,所以報語法錯誤;
而后面的“1..toString()和1.2.toStirng()”寫法,javascript引擎認為第一個“.”小數點,的二個為屬性訪問語法,所以都能正確解釋執行;
對於“(1).toStirng()”的寫法,用“()”排除了“.”被視為小數點的語法解釋,所以這種寫法能夠被解釋執行;

(3)純小數的小數點后面有連續6或6個以上的“0”時,小數將用e表示法進行輸出;

var num = 0.000006;//小數點后面有5個“0”
console.log(num.toString());//"0.000006"
var num = 0.0000006;//小數點后面有6個“0”
console.log(num.toString());//"6e-7"

(4)浮點數整數部分的位數大於21時,輸出時采用e表示法;

var num = 1234567890123456789012;
console.log(num.toString());//"1.2345678901234568e+21"

看到這里大家難免會有些疑問,這些基本的數據類型的值都是常量,而常量是沒有方法的,為什么能夠調用方法呢?答案是這樣的,五種基本類型除了null、undefined以外都有與之對應的特殊的引用類型——包裝類型。當代碼被解釋執行時,底層會對基本類型做一個類型轉換,即將基本類型轉換成引用類型,這樣就可以調用相應引用類型有權訪問到的方法。

二、toString()方法定義在何處?

運行以下代碼:
var pro = Object.prototype;
var pr = pro.__proto__;//ie11之前版本不支持該屬性
console.log(typeof pro);//"object"
console.log(String(pro));//"[object Object]"
console.log(pro.hasOwnProperty("toString"));//true
console.log(typeof pr);//"object"
console.log(String(pr));//"null"
console.log(pr.hasOwnProperty("toString"));//報錯
由此可知,toString()定義在Object.prototype上;

三、使用Object.prototype上的原生toString()方法判斷數據類型,使用方法如下:

Object.prototype.toString.call(value)

1.判斷基本類型:

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]”

2.判斷原生引用類型:

函數類型
Function fn(){console.log(“test”);}
Object.prototype.toString.call(fn);//”[object Function]”
日期類型
var date = new Date();
Object.prototype.toString.call(date);//”[object Date]”
數組類型
var arr = [1,2,3];
Object.prototype.toString.call(arr);//”[object Array]”
正則表達式
var reg = /[hbc]at/gi;
Object.prototype.toString.call(arr);//”[object Array]”
自定義類型
function Person(name, age) {
    this.name = name;
    this.age = age;
}
var person = new Person("Rose", 18);
Object.prototype.toString.call(arr); //”[object Object]”
很明顯這種方法不能准確判斷person是Person類的實例,而只能用instanceof 操作符來進行判斷,如下所示:
console.log(person instanceof Person);//輸出結果為true

3.判斷原生JSON對象:

var isNativeJSON = window.JSON && Object.prototype.toString.call(JSON);
console.log(isNativeJSON);//輸出結果為”[object JSON]”說明JSON是原生的,否則不是;

注意:Object.prototype.toString()本身是允許被修改的,而我們目前所討論的關於Object.prototype.toString()這個方法的應用都是假設toString()方法未被修改為前提的。

本文所討論內容多參考於《JavaScrip高級編程》第三版,另因個人水平有限,如有描述不當之處還請高手指正。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM