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