摘要:說(shuō)句玩笑話,如果是基于的,可能就叫了,形式可能就是這樣的了,如果這樣,那么可能現(xiàn)在是和比較密切了。此外,還有一個(gè)函數(shù),我們較少看到,但是它會(huì)影響。
我們先來(lái)看一個(gè)JS中常見的JS對(duì)象序列化成JSON字符串的問(wèn)題,請(qǐng)問(wèn),以下JS對(duì)象通過(guò)JSON.stringify后的字符串是怎樣的?先不要急著復(fù)制粘貼到控制臺(tái),先自己打開一個(gè)代碼編輯器或者紙,寫寫看,寫完再去仔細(xì)對(duì)比你的控制臺(tái)輸出,如果有誤記得看完全文并評(píng)論,哈哈。
var friend={ firstName: "Good", "lastName": "Man", "address": undefined, "phone": ["1234567",undefined], "fullName": function(){ return this.firstName + " " + this.lastName; } }; JSON.stringify(friend);//這一行返回什么呢?
第二個(gè)問(wèn)題,如果我想在最終JSON字符串將這個(gè)"friend"的姓名全部變成大寫字母,也就是把"Good"變成"GOOD",把"Man"變成"MAN",那么可以怎么做?
基于以上兩個(gè)問(wèn)題,我們?cè)僮繁舅菰磫?wèn)一下,JSON究竟是什么東西?為什么JSON就是易于數(shù)據(jù)交換?JSON和JS對(duì)象的區(qū)別?JS中JSON.parse、JSON.stringify和不常見的toJSON,這幾個(gè)函數(shù)的參數(shù)和處理細(xì)節(jié)到底是怎樣的?
歡迎進(jìn)入本次“深挖JSON之旅”,下文將從以下幾個(gè)方面去理解JSON:
首先是對(duì)“JSON是一種輕量的數(shù)據(jù)交換格式”的理解;
然后來(lái)看經(jīng)常被混為一談的JSON和JS對(duì)象的區(qū)別;
最后我們?cè)賮?lái)看JS中這幾個(gè)JSON相關(guān)函數(shù)具體的執(zhí)行細(xì)節(jié)。
希望全文能讓如之前的我一樣對(duì)JSON一知半解的親能說(shuō)清楚JSON是什么,也能熟練運(yùn)用JSON,不看控制臺(tái)就知道JS對(duì)象序列化成JSON字符串后輸出是啥。
一、JSON是一種格式,基于文本,優(yōu)于輕量,用于交換數(shù)據(jù)如果沒(méi)有去過(guò)JSON的官方介紹可以去一下這里,官方介紹第一、二段已經(jīng)很清楚地表述了JSON是什么,我將JSON是什么提煉成以下幾個(gè)方面:
1. 一種數(shù)據(jù)格式什么是格式?就是規(guī)范你的數(shù)據(jù)要怎么表示,舉個(gè)栗子,有個(gè)人叫“二百六”,身高“160cm”,體重“60kg”,現(xiàn)在你要將這個(gè)人的這些信息傳給別人或者別的什么東西,你有很多種選擇:
姓名“二百六”,身高“160cm”,體重“60kg”
name="二百六"&height="160cm"&weight="60kg"
{"name":"二百六","height":160,"weight":60}
... ...
以上所有選擇,傳遞的數(shù)據(jù)是一樣的,但是你可以看到形式是可以各式各樣的,這就是各種不同格式化后的數(shù)據(jù),JSON是其中一種表示方式。
2. 基于文本的數(shù)據(jù)格式JSON是基于文本的數(shù)據(jù)格式,相對(duì)于基于二進(jìn)制的數(shù)據(jù),所以JSON在傳遞的時(shí)候是傳遞符合JSON這種格式(至于JSON的格式是什么我們第二部分再說(shuō))的字符串,我們常會(huì)稱為“JSON字符串”。
3. 輕量級(jí)的數(shù)據(jù)格式在JSON之前,有一個(gè)數(shù)據(jù)格式叫xml,現(xiàn)在還是廣泛在用,但是JSON更加輕量,如xml需要用到很多標(biāo)簽,像上面的例子中,你可以明顯看到xml格式的數(shù)據(jù)中標(biāo)簽本身占據(jù)了很多空間,而JSON比較輕量,即相同數(shù)據(jù),以JSON的格式占據(jù)的帶寬更小,這在有大量數(shù)據(jù)請(qǐng)求和傳遞的情況下是有明顯優(yōu)勢(shì)的。
4. 被廣泛地用于數(shù)據(jù)交換輕量已經(jīng)是一個(gè)用于數(shù)據(jù)交換的優(yōu)勢(shì)了,但更重要的JSON是易于閱讀、編寫和機(jī)器解析的,即這個(gè)JSON對(duì)人和機(jī)器都是友好的,而且又輕,獨(dú)立于語(yǔ)言(因?yàn)槭腔谖谋镜模訨SON被廣泛用于數(shù)據(jù)交換。
以前端JS進(jìn)行ajax的POST請(qǐng)求為例,后端PHP處理請(qǐng)求為例:
前端構(gòu)造一個(gè)JS對(duì)象,用于包裝要傳遞的數(shù)據(jù),然后將JS對(duì)象轉(zhuǎn)化為JSON字符串,再發(fā)送請(qǐng)求到后端;
后端PHP接收到這個(gè)JSON字符串,將JSON字符串轉(zhuǎn)化為PHP對(duì)象,然后處理請(qǐng)求。
可以看到,相同的數(shù)據(jù)在這里有3種不同的表現(xiàn)形式,分別是前端的JS對(duì)象、傳輸?shù)腏SON字符串、后端的PHP對(duì)象,JS對(duì)象和PHP對(duì)象明顯不是一個(gè)東西,但是由于大家用的都是JSON來(lái)傳遞數(shù)據(jù),大家都能理解這種數(shù)據(jù)格式,都能把JSON這種數(shù)據(jù)格式很容易地轉(zhuǎn)化為自己能理解的數(shù)據(jù)結(jié)構(gòu),這就方便啦,在其他各種語(yǔ)言環(huán)境中交換數(shù)據(jù)都是如此。
二、JSON和JS對(duì)象之間的“八卦”很多時(shí)候都聽到“JSON是JS的一個(gè)子集”這句話,而且這句話我曾經(jīng)也一直這么認(rèn)為,每個(gè)符合JSON格式的字符串你解析成js都是可以的,直到后來(lái)發(fā)現(xiàn)了一個(gè)奇奇怪怪的東西...
1. 兩個(gè)本質(zhì)不同的東西為什么那么密切JSON和JS對(duì)象本質(zhì)上完全不是同一個(gè)東西,就像“斑馬線”和“斑馬”,“斑馬線”基于“斑馬”身上的條紋來(lái)呈現(xiàn)和命名,但是斑馬是活的,斑馬線是非生物。
同樣,"JSON"全名"JavaScript Object Notation",所以它的格式(語(yǔ)法)是基于JS的,但它就是一種格式,而JS對(duì)象是一個(gè)實(shí)例,是存在于內(nèi)存的一個(gè)東西。
說(shuō)句玩笑話,如果JSON是基于PHP的,可能就叫PON了,形式可能就是這樣的了["propertyOne" => "foo", "propertyTwo" => 42,],如果這樣,那么JSON可能現(xiàn)在是和PHP比較密切了。
此外,JSON是可以傳輸?shù)模驗(yàn)樗俏谋靖袷剑荍S對(duì)象是沒(méi)辦法傳輸?shù)模谡Z(yǔ)法上,JSON也會(huì)更加嚴(yán)格,但是JS對(duì)象就很松了。
那么兩個(gè)不同的東西為什么那么密切,因?yàn)镴SON畢竟是從JS中演變出來(lái)的,語(yǔ)法相近。
2. JSON格式別JS對(duì)象語(yǔ)法表現(xiàn)上嚴(yán)格在哪先就以“鍵值對(duì)為表現(xiàn)的對(duì)象”形式上,對(duì)比下兩者的不同,至于JSON還能以怎樣的形式表現(xiàn),對(duì)比完后再羅列。
對(duì)比內(nèi)容 | JSON | JS對(duì)象 |
---|---|---|
鍵名 | 必須是加雙引號(hào) | 可允許不加、加單引號(hào)、加雙引號(hào) |
屬性值 | 只能是數(shù)值(10進(jìn)制)、字符串(雙引號(hào))、布爾值和null, 也可以是數(shù)組或者符合JSON要求的對(duì)象, 不能是函數(shù)、NaN, Infinity, -Infinity和undefined |
愛啥啥 |
逗號(hào)問(wèn)題 | 最后一個(gè)屬性后面不能有逗號(hào) | 可以 |
數(shù)值 | 前導(dǎo)0不能用,小數(shù)點(diǎn)后必須有數(shù)字 | 沒(méi)限制 |
可以看到,相對(duì)于JS對(duì)象,JSON的格式更嚴(yán)格,所以大部分寫的JS對(duì)象是不符合JSON的格式的。
以下代碼引用自這里
var obj1 = {}; // 這只是 JS 對(duì)象 // 可把這個(gè)稱做:JSON 格式的 JavaScript 對(duì)象 var obj2 = {"width":100,"height":200,"name":"rose"}; // 可把這個(gè)稱做:JSON 格式的字符串 var str1 = "{"width":100,"height":200,"name":"rose"}"; // 這個(gè)可叫 JSON 格式的數(shù)組,是 JSON 的稍復(fù)雜一點(diǎn)的形式 var arr = [ {"width":100,"height":200,"name":"rose"}, {"width":100,"height":200,"name":"rose"}, {"width":100,"height":200,"name":"rose"}, ]; // 這個(gè)可叫稍復(fù)雜一點(diǎn)的 JSON 格式的字符串 var str2="["+ "{"width":100,"height":200,"name":"rose"},"+ "{"width":100,"height":200,"name":"rose"},"+ "{"width":100,"height":200,"name":"rose"},"+ "]";
另外,除了常見的“正常的”JSON格式,要么表現(xiàn)為一個(gè)對(duì)象形式{...},要么表現(xiàn)為一個(gè)數(shù)組形式[...],任何多帶帶的一個(gè)10進(jìn)制數(shù)值、雙引號(hào)字符串、布爾值和null都是有效符合JSON格式的。
這里有完整的JSON語(yǔ)法參考
3. 一個(gè)有意思的地方,JSON不是JS的子集首先看下面的代碼,你可以copy到控制臺(tái)執(zhí)行下:
var code = ""u2028u2029""; JSON.parse(code); // works fine eval(code); // fails
這兩個(gè)字符u2028和u2029分別表示行分隔符和段落分隔符,JSON.parse可以正常解析,但是當(dāng)做js解析時(shí)會(huì)報(bào)錯(cuò)。
三、這幾個(gè)JS中的JSON函數(shù),弄啥嘞在JS中我們主要會(huì)接觸到兩個(gè)和JSON相關(guān)的函數(shù),分別用于JSON字符串和JS數(shù)據(jù)結(jié)構(gòu)之間的轉(zhuǎn)化,一個(gè)叫JSON.stringify,它很聰明,聰明到你寫的不符合JSON格式的JS對(duì)象都能幫你處理成符合JSON格式的字符串,所以你得知道它到底干了什么,免得它只是自作聰明,然后讓你Debug long time;另一個(gè)叫JSON.parse,用于轉(zhuǎn)化json字符串到JS數(shù)據(jù)結(jié)構(gòu),它很嚴(yán)格,你的JSON字符串如果構(gòu)造地不對(duì),是沒(méi)辦法解析的。
而它們的參數(shù)不止一個(gè),雖然我們經(jīng)常用的時(shí)候只傳入一個(gè)參數(shù)。
此外,還有一個(gè)toJSON函數(shù),我們較少看到,但是它會(huì)影響JSON.stringify。
1. 將JS數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)化為JSON字符串 —— JSON.stringify這個(gè)函數(shù)的函數(shù)簽名是這樣的:
JSON.stringify(value[, replacer [, space]])
下面將分別展開帶1~3個(gè)參數(shù)的用法,最后是它在序列化時(shí)做的一些“聰明”的事,要特別注意。
1.1 基本使用 —— 僅需一個(gè)參數(shù)這個(gè)大家都會(huì)使用,傳入一個(gè)JSON格式的JS對(duì)象或者數(shù)組,JSON.stringify({"name":"Good Man","age":18})返回一個(gè)字符串"{"name":"Good Man","age":18}"。
可以看到本身我們傳入的這個(gè)JS對(duì)象就是符合JSON格式的,用的雙引號(hào),也沒(méi)有JSON不接受的屬性值,那么如果像開頭那個(gè)例子中的一樣,how to play?不急,我們先舉簡(jiǎn)單的例子來(lái)說(shuō)明這個(gè)函數(shù)的幾個(gè)參數(shù)的意義,再來(lái)說(shuō)這個(gè)問(wèn)題。
1.2 第二個(gè)參數(shù)可以是函數(shù),也可以是一個(gè)數(shù)組如果第二個(gè)參數(shù)是一個(gè)函數(shù),那么序列化過(guò)程中的每個(gè)屬性都會(huì)被這個(gè)函數(shù)轉(zhuǎn)化和處理
如果第二個(gè)參數(shù)是一個(gè)數(shù)組,那么只有包含在這個(gè)數(shù)組中的屬性才會(huì)被序列化到最終的JSON字符串中
如果第二個(gè)參數(shù)是null,那作用上和空著沒(méi)啥區(qū)別,但是不想設(shè)置第二個(gè)參數(shù),只是想設(shè)置第三個(gè)參數(shù)的時(shí)候,就可以設(shè)置第二個(gè)參數(shù)為null
這第二個(gè)參數(shù)若是函數(shù)
var friend={ "firstName": "Good", "lastName": "Man", "phone":"1234567", "age":18 }; var friendAfter=JSON.stringify(friend,function(key,value){ if(key==="phone") return "(000)"+value; else if(typeof value === "number") return value + 10; else return value; //如果你把這個(gè)else分句刪除,那么結(jié)果會(huì)是undefined }); console.log(friendAfter); //輸出:{"firstName":"Good","lastName":"Man","phone":"(000)1234567","age":28}
如果制定了第二個(gè)參數(shù)是函數(shù),那么這個(gè)函數(shù)必須對(duì)每一項(xiàng)都有返回,這個(gè)函數(shù)接受兩個(gè)參數(shù),一個(gè)鍵名,一個(gè)是屬性值,函數(shù)必須針對(duì)每一個(gè)原來(lái)的屬性值都要有新屬性值的返回。
那么問(wèn)題來(lái)了,如果傳入的不是鍵值對(duì)的對(duì)象形式,而是方括號(hào)的數(shù)組形式呢?,比如上面的friend變成這樣:friend=["Jack","Rose"],那么這個(gè)逐屬性處理的函數(shù)接收到的key和value又是什么?如果是數(shù)組形式,那么key是索引,而value是這個(gè)數(shù)組項(xiàng),你可以在控制臺(tái)在這個(gè)函數(shù)內(nèi)部打印出來(lái)這個(gè)key和value驗(yàn)證,記得要返回value,不然會(huì)出錯(cuò)。
這第二個(gè)參數(shù)若是數(shù)組
var friend={ "firstName": "Good", "lastName": "Man", "phone":"1234567", "age":18 }; //注意下面的數(shù)組有一個(gè)值并不是上面對(duì)象的任何一個(gè)屬性名 var friendAfter=JSON.stringify(friend,["firstName","address","phone"]); console.log(friendAfter); //{"firstName":"Good","phone":"1234567"} //指定的“address”由于沒(méi)有在原來(lái)的對(duì)象中找到而被忽略
如果第二個(gè)參數(shù)是一個(gè)數(shù)組,那么只有在數(shù)組中出現(xiàn)的屬性才會(huì)被序列化進(jìn)結(jié)果字符串,只要在這個(gè)提供的數(shù)組中找不到的屬性就不會(huì)被包含進(jìn)去,而這個(gè)數(shù)組中存在但是源JS對(duì)象中不存在的屬性會(huì)被忽略,不會(huì)報(bào)錯(cuò)。
1.3 第三個(gè)參數(shù)用于美化輸出 —— 不建議用指定縮進(jìn)用的空白字符,可以取以下幾個(gè)值:
是1-10的某個(gè)數(shù)字,代表用幾個(gè)空白字符
是字符串的話,就用該字符串代替空格,最多取這個(gè)字符串的前10個(gè)字符
沒(méi)有提供該參數(shù) 等于 設(shè)置成null 等于 設(shè)置一個(gè)小于1的數(shù)
var friend={ "firstName": "Good", "lastName": "Man", "phone":{"home":"1234567","work":"7654321"} }; //直接轉(zhuǎn)化是這樣的: //{"firstName":"Good","lastName":"Man","phone":{"home":"1234567","work":"7654321"}} var friendAfter=JSON.stringify(friend,null,4); console.log(friendAfter); /* { "firstName": "Good", "lastName": "Man", "phone": { "home": "1234567", "work": "7654321" } } */ var friendAfter=JSON.stringify(friend,null,"HAHAHAHA"); console.log(friendAfter); /* { HAHAHAHA"firstName": "Good", HAHAHAHA"lastName": "Man", HAHAHAHA"phone": { HAHAHAHAHAHAHAHA"home": "1234567", HAHAHAHAHAHAHAHA"work": "7654321" HAHAHAHA} } */ var friendAfter=JSON.stringify(friend,null,"WhatAreYouDoingNow"); console.log(friendAfter); /* 最多只取10個(gè)字符 { WhatAreYou"firstName": "Good", WhatAreYou"lastName": "Man", WhatAreYou"phone": { WhatAreYouWhatAreYou"home": "1234567", WhatAreYouWhatAreYou"work": "7654321" WhatAreYou} } */
笑笑就好,別這樣用,序列化是為了傳輸,傳輸就是能越小越好,加莫名其妙的縮進(jìn)符,解析困難(如果是字符串的話),也弱化了輕量化這個(gè)特點(diǎn)。。
1.4 注意這個(gè)函數(shù)的“小聰明”(重要)如果有其他不確定的情況,那么最好的辦法就是"Have a try",控制臺(tái)做下實(shí)驗(yàn)就明了。
鍵名不是雙引號(hào)的(包括沒(méi)有引號(hào)或者是單引號(hào)),會(huì)自動(dòng)變成雙引號(hào);字符串是單引號(hào)的,會(huì)自動(dòng)變成雙引號(hào)
最后一個(gè)屬性后面有逗號(hào)的,會(huì)被自動(dòng)去掉
非數(shù)組對(duì)象的屬性不能保證以特定的順序出現(xiàn)在序列化后的字符串中
這個(gè)好理解,也就是對(duì)非數(shù)組對(duì)象在最終字符串中不保證屬性順序和原來(lái)一致
布爾值、數(shù)字、字符串的包裝對(duì)象在序列化過(guò)程中會(huì)自動(dòng)轉(zhuǎn)換成對(duì)應(yīng)的原始值
也就是你的什么new String("bala")會(huì)變成"bala",new Number(2017)會(huì)變成2017
undefined、任意的函數(shù)(其實(shí)有個(gè)函數(shù)會(huì)發(fā)生神奇的事,后面會(huì)說(shuō))以及 symbol 值(symbol詳見ES6對(duì)symbol的介紹)
出現(xiàn)在非數(shù)組對(duì)象的屬性值中:在序列化過(guò)程中會(huì)被忽略
出現(xiàn)在數(shù)組中時(shí):被轉(zhuǎn)換成 null
JSON.stringify({x: undefined, y: function(){return 1;}, z: Symbol("")}); //出現(xiàn)在非數(shù)組對(duì)象的屬性值中被忽略:"{}" JSON.stringify([undefined, Object, Symbol("")]); //出現(xiàn)在數(shù)組對(duì)象的屬性值中,變成null:"[null,null,null]"
NaN、Infinity和-Infinity,不論在數(shù)組還是非數(shù)組的對(duì)象中,都被轉(zhuǎn)化為null
所有以 symbol 為屬性鍵的屬性都會(huì)被完全忽略掉,即便 replacer 參數(shù)中強(qiáng)制指定包含了它們
不可枚舉的屬性會(huì)被忽略
2. 將JSON字符串解析為JS數(shù)據(jù)結(jié)構(gòu) —— JSON.parse這個(gè)函數(shù)的函數(shù)簽名是這樣的:
JSON.parse(text[, reviver])
如果第一個(gè)參數(shù),即JSON字符串不是合法的字符串的話,那么這個(gè)函數(shù)會(huì)拋出錯(cuò)誤,所以如果你在寫一個(gè)后端返回JSON字符串的腳本,最好調(diào)用語(yǔ)言本身的JSON字符串相關(guān)序列化函數(shù),而如果是自己去拼接實(shí)現(xiàn)的序列化字符串,那么就尤其要注意序列化后的字符串是否是合法的,合法指這個(gè)JSON字符串完全符合JSON要求的嚴(yán)格格式。
值得注意的是這里有一個(gè)可選的第二個(gè)參數(shù),這個(gè)參數(shù)必須是一個(gè)函數(shù),這個(gè)函數(shù)作用在屬性已經(jīng)被解析但是還沒(méi)返回前,將屬性處理后再返回。
var friend={ "firstName": "Good", "lastName": "Man", "phone":{"home":"1234567","work":["7654321","999000"]} }; //我們先將其序列化 var friendAfter=JSON.stringify(friend); //"{"firstName":"Good","lastName":"Man","phone":{"home":"1234567","work":["7654321","999000"]}}" //再將其解析出來(lái),在第二個(gè)參數(shù)的函數(shù)中打印出key和value JSON.parse(friendAfter,function(k,v){ console.log(k); console.log(v); console.log("----"); }); /* firstName Good ---- lastName Man ---- home 1234567 ---- 0 7654321 ---- 1 999000 ---- work [] ---- phone Object ---- Object ---- */
仔細(xì)看一下這些輸出,可以發(fā)現(xiàn)這個(gè)遍歷是由內(nèi)而外的,可能由內(nèi)而外這個(gè)詞大家會(huì)誤解,最里層是內(nèi)部數(shù)組里的兩個(gè)值啊,但是輸出是從第一個(gè)屬性開始的,怎么就是由內(nèi)而外的呢?
這個(gè)由內(nèi)而外指的是對(duì)于復(fù)合屬性來(lái)說(shuō)的,通俗地講,遍歷的時(shí)候,從頭到尾進(jìn)行遍歷,如果是簡(jiǎn)單屬性值(數(shù)值、字符串、布爾值和null),那么直接遍歷完成,如果是遇到屬性值是對(duì)象或者數(shù)組形式的,那么暫停,先遍歷這個(gè)子JSON,而遍歷的原則也是一樣的,等這個(gè)復(fù)合屬性遍歷完成,那么再完成對(duì)這個(gè)屬性的遍歷返回。
本質(zhì)上,這就是一個(gè)深度優(yōu)先的遍歷。
有兩點(diǎn)需要注意:
如果 reviver 返回 undefined,則當(dāng)前屬性會(huì)從所屬對(duì)象中刪除,如果返回了其他值,則返回的值會(huì)成為當(dāng)前屬性新的屬性值。
你可以注意到上面例子最后一組輸出看上去沒(méi)有key,其實(shí)這個(gè)key是一個(gè)空字符串,而最后的object是最后解析完成對(duì)象,因?yàn)榈搅俗钌蠈樱呀?jīng)沒(méi)有真正的屬性了。
3. 影響 JSON.stringify 的神奇函數(shù) —— object.toJSON如果你在一個(gè)JS對(duì)象上實(shí)現(xiàn)了toJSON方法,那么調(diào)用JSON.stringify去序列化這個(gè)JS對(duì)象時(shí),JSON.stringify會(huì)把這個(gè)對(duì)象的toJSON方法返回的值作為參數(shù)去進(jìn)行序列化。
var info={ "msg":"I Love You", "toJSON":function(){ var replaceMsg=new Object(); replaceMsg["msg"]="Go Die"; return replaceMsg; } }; JSON.stringify(info); //出si了,返回的是:""{"msg":"Go Die"}"",說(shuō)好的忽略函數(shù)呢
這個(gè)函數(shù)就是這樣子的。
其實(shí)Date類型可以直接傳給JSON.stringify做參數(shù),其中的道理就是,Date類型內(nèi)置了toJSON方法。
四、小結(jié)以及關(guān)于兼容性的問(wèn)題到這里終于把,JSON和JS中的JSON,梳理了一遍,也對(duì)里面的細(xì)節(jié)和注意點(diǎn)進(jìn)行了一次遍歷,知道JSON是一種語(yǔ)法上衍生于JS語(yǔ)言的一種輕量級(jí)的數(shù)據(jù)交換格式,也明白了JSON相對(duì)于一般的JS數(shù)據(jù)結(jié)構(gòu)(尤其是對(duì)象)的差別,更進(jìn)一步,仔細(xì)地討論了JS中關(guān)于JSON處理的3個(gè)函數(shù)和細(xì)節(jié)。
不過(guò)遺憾的是,以上所用的3個(gè)函數(shù),不兼容IE7以及IE7之前的瀏覽器。有關(guān)兼容性的討論,留待之后吧。如果想直接在應(yīng)用上解決兼容性,那么可以套用JSON官方的js,可以解決。
如有紕漏,歡迎留言指出。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/88201.html
摘要:基本用法屬性目前只支持你可以看出他們?cè)诶锉憩F(xiàn)的差異關(guān)于標(biāo)簽支持的音頻類型,可以參考常用屬性音頻流文件就緒后是否自動(dòng)播放無(wú)需預(yù)加載只需要加載元數(shù)據(jù),例如音頻時(shí)長(zhǎng),文件大小等。 我覺(jué)得DOM就好像是元素周期表里的元素,JS就好像是實(shí)驗(yàn)器材,通過(guò)各種化學(xué)反應(yīng),產(chǎn)生各種魔術(shù)。 showImg(https://segmentfault.com/img/bVO9vK?w=1440&h=814); ...
摘要:大潮來(lái)襲前端開發(fā)能做些什么去年谷歌和火狐針對(duì)提出了的標(biāo)準(zhǔn),顧名思義,即的體驗(yàn)方式,我們可以戴著頭顯享受沉浸式的網(wǎng)頁(yè),新的標(biāo)準(zhǔn)讓我們可以使用語(yǔ)言來(lái)開發(fā)。 VR 大潮來(lái)襲 --- 前端開發(fā)能做些什么 去年谷歌和火狐針對(duì) WebVR 提出了 WebVR API 的標(biāo)準(zhǔn),顧名思義,WebVR 即 web + VR 的體驗(yàn)方式,我們可以戴著頭顯享受沉浸式的網(wǎng)頁(yè),新的 API 標(biāo)準(zhǔn)讓我們可以使用 ...
摘要:巧前端基礎(chǔ)進(jìn)階全方位解讀前端掘金我們?cè)趯W(xué)習(xí)的過(guò)程中,由于對(duì)一些概念理解得不是很清楚,但是又想要通過(guò)一些方式把它記下來(lái),于是就很容易草率的給這些概念定下一些方便自己記憶的有偏差的結(jié)論。 計(jì)算機(jī)程序的思維邏輯 (83) - 并發(fā)總結(jié) - 掘金從65節(jié)到82節(jié),我們用了18篇文章討論并發(fā),本節(jié)進(jìn)行簡(jiǎn)要總結(jié)。 多線程開發(fā)有兩個(gè)核心問(wèn)題,一個(gè)是競(jìng)爭(zhēng),另一個(gè)是協(xié)作。競(jìng)爭(zhēng)會(huì)出現(xiàn)線程安全問(wèn)題,所以,本...
摘要:巧前端基礎(chǔ)進(jìn)階全方位解讀前端掘金我們?cè)趯W(xué)習(xí)的過(guò)程中,由于對(duì)一些概念理解得不是很清楚,但是又想要通過(guò)一些方式把它記下來(lái),于是就很容易草率的給這些概念定下一些方便自己記憶的有偏差的結(jié)論。 計(jì)算機(jī)程序的思維邏輯 (83) - 并發(fā)總結(jié) - 掘金從65節(jié)到82節(jié),我們用了18篇文章討論并發(fā),本節(jié)進(jìn)行簡(jiǎn)要總結(jié)。 多線程開發(fā)有兩個(gè)核心問(wèn)題,一個(gè)是競(jìng)爭(zhēng),另一個(gè)是協(xié)作。競(jìng)爭(zhēng)會(huì)出現(xiàn)線程安全問(wèn)題,所以,本...
閱讀 658·2021-11-25 09:43
閱讀 1671·2021-11-18 10:02
閱讀 1048·2021-10-15 09:39
閱讀 1896·2021-10-12 10:18
閱讀 2127·2021-09-22 15:43
閱讀 780·2021-09-22 15:10
閱讀 2092·2019-08-30 15:53
閱讀 993·2019-08-30 13:00