javascript
json tostringfiy_JS学习笔记 : 类型转换之「抽象值操作」
這要是沒搞懂你好意思說學過JS?
這怕是JavaScript中最坑、最有毒的一個部分了。
將值從一種類型轉換成另一種類型叫做類型轉換。例如:
var a = 1;
var b = String(a); // "1" 顯式轉換var c = "" + a; // "1" 隱式轉換
在JavaScript中,我們把上面列舉的兩類轉換都稱為 強制類型轉換 ,按照顯式和隱式的區別我們可以將強制類型轉換分為 顯式強制類型轉換 和 隱式強制類型轉換 。
當然要注意,這里的顯式和隱式都是相對的。假如你對JavaScript運行中的所有將要執行的類型轉換都牢記于心,那當然可以把他們全部稱為顯式強制類型轉換。本文主要參考《你不知道的JavaScript中卷》,因此參照書中的標準來界定顯式和隱式。
JavaScript中的強制類型轉換總是返回標量基本類型值,例如字符串、數字和布爾值,不會返回對象和函數。
這篇文章會學習抽象值操作。
ToString
基本類型的字符串化規則為:null轉換為"null"
undefined轉換為"undefined"
true轉換為true
數字的字符串化則遵循通用規則,對于極小和極大的數使用指數形式
對于對象來說,字符串化的時候會調用對象的toString()方法,并使用其返回值。如果沒有自行定義的話,toString()方法會默認返回內部屬性[[Class]]的值。例如以下的例子:
"" + {}; // "[object Object]"
"" + [1,2,3]; // "1,2,3""" + {toString: function(){return "1"}}; // "1"
toString() 可以被顯式調用,或在需要字符串化的時候自動調用。
JSON 字符串化
JSON應該是我們在JS中最常用的序列化和反序列化工具之一了。JSON.stringify()在將對象序列化為字符串的時候也用到了ToString。但是需要注意,JSON字符串化并非嚴格意義上的強制類型轉換。
對于大多數基本類型值來說,JSON字符串化的結果和toString()是差不多的,只不過序列化的結果總是字符串:
JSON.stringify(1); // "1"JSON.stringify("1"); // ""1"" (帶有雙引號的字符串)JSON.stringify(null); // "null"JSON.stringify(true); // "true"
有些值JSON是無法處理的,例如:undefined、function、symbol 和包含循環引用(對象之間相互引用)的對象。我們把這些它們稱作 不安全的JSON值 。
相對的,所有 安全的JSON值(JSON-safe) 都可以使用JSON.stringify()字符串化。
JSON.stringify() 在對象中遇到 undefined、 function 和 symbol的時候會自動忽略他們,在數組中這回返回null(為的是保證數據的下標不變),在遇到循環引用的對象時會報錯。例如:
JSON.stringify(undefined); // undefinedJSON.stringify(function(){}); // undefined
JSON.stringfiy(
[1, undefined, function(){}, 4]
); // "[1,null,null,4]"JSON.stringify(
{a: 1, b: function(){}, c: undefined }
); // "{"a":1}"JSON.stringify(
{toString: function(){return "1"}}
); // "{}"
var a = {};
var b = {a: a};
a.b = b;
JSON.stringify(a); // Uncaught TypeError: Converting circular structure to JSON
如果對象中定義了toJSON()方法,JSON字符串化的時候會首先調用該方法,然后用它的返回值來進行序列化。如果你對某些非法JSON值定義了toJSON()方法,并返回一個安全的JSON值,那么這個值就能被字符串化了。 注意,對象是不自帶toJSON()方法的,需要你主動定義它。 例如:
var a = {};
var b = {a: a};
a.b = b;
b.toJSON = function(){
return {};
};
JSON.stringify(a); // "{"b":{}}"
var foo = function(){}
foo.toJSON = function(){return 123}
JSON.stringify(foo); // "123"
var bar = {
a: undefined,
toJSON: function (){ return {a: null} }
}
JSON.stringify(bar); // "{"a":null}"
toJSON()返回的并不一定是JSON字符串化后的值(這樣其實會對字符串再做一次字符串化),而應當是一個適當的值,可以是任何類型,然后再由JSON.stringify()對其字符串化。
ToNumber
ToNumber相比ToString來說就簡單很多。
將基本數據類型轉換為數字的規則為:
- true轉換為1
- false轉換為0
- undefined轉換為NaN
- null轉換為0
- 對字符串的轉換遵循通用規則,處理失敗時返回NaN,對以0開頭的十六進制數按十進制處理而非十六進制。
對于對象來說,它們會先被轉換成相應的基本類型值,如果返回的是非數字的基本類型值,則再遵循以上規則將其轉換成數字。
對象轉換成基本類型值的規則為:首先檢查是否有valueOf()方法,如果有并且返回基本類型值,就使用改值進行轉換。如果沒有則使用toString()方法的返回值(如果存在)來進行強制類型轉換。如果valueOf()和toString()都不反悔基本類型值,則會產生TypeError錯誤。
幾個例子:
var a = {valueOf: function(){return "1"}};
var b = {toString: function(){return "2"}}
Number(a); // 1Number(b); // 2
var c = [1,2,3];
Number(c); // NaNc.valueOf = function(){
return 1;
}
Number(c); // 1
var d = [];
Number(d); // 0d.toString = function(){
return 1;
}
Number(d); // 1
var e = [1,2,3];
e.toString = function(){
return this.join("") // 123}
Number(e) //123
ToBoolean
boolean的兩個字true和false分別代表著 真 和 假 。在JavaScript中,數字1和0與true和false并不等價。
對于基本類型值來說,JavaScript中的值可以分為兩類:
- 可以被強制類型轉換成false的值
- 其他(可以被強制類型轉換成true)的值
以下的值為 假值 :
- undefined
- null
- false
- +0、-0和NaN
- ""
除了假值表以外的所有值都可以理解為 真值 。
一般來說,所有的對象都是真值,但是有一些特殊情況,我們可以把他們叫做 假值對象 。
先來說幾個例子——
var a = new Boolean(false);
var b = new Number(0);
var c = new String("");
var d = new Boolean(0);
var foo = Boolean(a && b && c &&d);
foo; // true
foo為true,說明a、b、c、d都為true。
這些封裝了假值的對象都并非假值。
我們來看看真正的假值對象——他們是來自瀏覽器在某些特定條件下創造的對象,例如document.all:
document.all; // 返回一個 HTMLAllCollection 對象!!document.all; // false
這是一個類數組對象,由DOM提供(而非JavaScript引擎)提供給JavaScript程序使用。它以前曾是一個真正意義上的對象,布爾強制類型轉換的結果為true,但現在它是一個假值對象——并且這已經死一個被廢止的方法了。
由于很多JavaScript程序依賴document.all來判斷是否是舊版瀏覽器,因此一直沒有把它去掉。
再說一說幾個真值的情況——雖然剛才說過了假值表以外的都是真值,但是你還可能會遇到一些比較刁鉆的狀況:
var a = Boolean("false");
a; // true
var b = Boolean("0");
b; // true
var c = Boolean("\"\"");
c; // true
對于字符串來說,除了""以外都是真值。同時,對于[]、{}、function(){}這一類的對象都是真值。
參考《你不知道的JavaScript中卷》第一部分第四章
總結
以上是生活随笔為你收集整理的json tostringfiy_JS学习笔记 : 类型转换之「抽象值操作」的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蛏子多少钱啊?
- 下一篇: java json帮助类_java 写