為了區(qū)分對(duì)象的類(lèi)型腮考,我們用typeof操作符獲取對(duì)象的類(lèi)型惕稻,它總是返回一個(gè)字符串:
typeof 123; // 'number'
typeof NaN; // 'number'
typeof 'str'; // 'string'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof Math.abs; // 'function'
typeof null; // 'object'
typeof []; // 'object'
typeof {}; // 'object'
2.包裝對(duì)象
number、boolean和string都有包裝對(duì)象坛善。
沒(méi)錯(cuò),在JavaScript中戚丸,字符串也區(qū)分string類(lèi)型和它的包裝類(lèi)型羞反。包裝對(duì)象用new創(chuàng)建:
var n = new Number(123); // 123,生成了新的包裝類(lèi)型
var b = new Boolean(true); // true,生成了新的包裝類(lèi)型
var s = new String('str'); // 'str',生成了新的包裝類(lèi)型
雖然包裝對(duì)象看上去和原來(lái)的值一模一樣,顯示出來(lái)也是一模一樣腿倚,
但他們的類(lèi)型已經(jīng)變?yōu)閛bject了纯出!所以,包裝對(duì)象和原始值用===比較會(huì)返回false:
typeof new Number(123); // 'object'
new Number(123) === 123; // false
typeof new Boolean(true); // 'object'
new Boolean(true) === true; // false
typeof new String('str'); // 'object'
new String('str') === 'str'; // false
所以閑的蛋疼也不要使用包裝對(duì)象敷燎!尤其是針對(duì)string類(lèi)型T蒹荨!硬贯!
如果我們?cè)谑褂肗umber焕襟、Boolean和String時(shí),沒(méi)有寫(xiě)new會(huì)發(fā)生什么情況饭豹?
此時(shí)鸵赖,Number()务漩、Boolean和String()被當(dāng)做普通函數(shù),把任何類(lèi)型的數(shù)據(jù)轉(zhuǎn)換為number它褪、boolean和string類(lèi)型(注意不是其包裝類(lèi)型):
var n = Number('123'); // 123饵骨,相當(dāng)于parseInt()或parseFloat()
typeof n; // 'number'
var b = Boolean('true'); // true
typeof b; // 'boolean'
var b2 = Boolean('false'); // true! 'false'字符串轉(zhuǎn)換結(jié)果為true!因?yàn)樗欠强兆址?var b3 = Boolean(''); // false
var s = String(123.45); // '123.45'
typeof s; // 'string'
總結(jié)一下茫打,有這么幾條規(guī)則需要遵守:
不要使用new Number()居触、new Boolean()、new String()創(chuàng)建包裝對(duì)象老赤;
用parseInt()或parseFloat()來(lái)轉(zhuǎn)換任意類(lèi)型到number轮洋;
用String()來(lái)轉(zhuǎn)換任意類(lèi)型到string,或者直接調(diào)用某個(gè)對(duì)象的toString()方法抬旺;
通常不必把任意類(lèi)型轉(zhuǎn)換為boolean再判斷弊予,因?yàn)榭梢灾苯訉?xiě)if (myVar) {...};
typeof操作符可以判斷出number开财、boolean汉柒、string、function和undefined床未;
判斷Array要使用Array.isArray(arr)竭翠;
判斷null請(qǐng)使用myVar === null;
判斷某個(gè)全局變量是否存在用typeof window.myVar === 'undefined'薇搁;
函數(shù)內(nèi)部判斷某個(gè)變量是否存在用typeof myVar === 'undefined'斋扰。
最后有細(xì)心的同學(xué)指出,任何對(duì)象都有toString()方法嗎啃洋?
null和undefined就沒(méi)有传货!確實(shí)如此,這兩個(gè)特殊值要除外宏娄,雖然null還偽裝成了object類(lèi)型问裕。
更細(xì)心的同學(xué)指出,number對(duì)象調(diào)用toString()報(bào)SyntaxError:
123.toString(); // SyntaxError
遇到這種情況孵坚,要特殊處理一下:
123..toString(); // '123', 注意是兩個(gè)點(diǎn)粮宛!
(123).toString(); // '123'
4.json
在JSON中,一共就這么幾種數(shù)據(jù)類(lèi)型:
number:和JavaScript的number完全一致卖宠;
boolean:就是JavaScript的true或false巍杈;
string:就是JavaScript的string;
null:就是JavaScript的null扛伍;
array:就是JavaScript的Array表示方式——[]筷畦;
object:就是JavaScript的{ ... }表示方式。
以及上面的任意組合刺洒。
并且鳖宾,JSON還定死了字符集必須是UTF-8吼砂,表示多語(yǔ)言就沒(méi)有問(wèn)題了。
為了統(tǒng)一解析鼎文,JSON的字符串規(guī)定必須用雙引號(hào)""渔肩,Object的鍵也必須用雙引號(hào)""。
由于JSON非常簡(jiǎn)單漂问,很快就風(fēng)靡Web世界赖瞒,并且成為ECMA標(biāo)準(zhǔn)女揭。
幾乎所有編程語(yǔ)言都有解析JSON的庫(kù)蚤假,而在JavaScript中,我們可以直接使用JSON吧兔,
因?yàn)镴avaScript內(nèi)置了JSON的解析磷仰。
把任何JavaScript對(duì)象變成JSON,就是把這個(gè)對(duì)象序列化成一個(gè)JSON格式的字符串境蔼,
這樣才能夠通過(guò)網(wǎng)絡(luò)傳遞給其他計(jì)算機(jī)灶平。
如果我們收到一個(gè)JSON格式的字符串,只需要把它反序列化成一個(gè)JavaScript對(duì)象箍土,
就可以在JavaScript中直接使用這個(gè)對(duì)象了逢享。
4.1.序列化
讓我們先把小明這個(gè)對(duì)象序列化成JSON格式的字符串:
var xiaoming = {
name: '小明',
age: 14,
gender: true,
height: 1.65,
grade: null,
'middle-school': '\\"W3C\\" Middle School',
skills: ['JavaScript', 'Java', 'Python', 'Lisp']
};
JSON.stringify(xiaoming); // '{"name":"小明","age":14,"gender":true,"height":1.65,"grade":null,"middle-school":"\\"W3C\\" Middle School","skills":["JavaScript","Java","Python","Lisp"]}'
要輸出得好看一些,可以加上參數(shù)吴藻,按縮進(jìn)輸出:
JSON.stringify(xiaoming, null, ' ');
結(jié)果:
{
"name": "小明",
"age": 14,
"gender": true,
"height": 1.65,
"grade": null,
"middle-school": "\\"W3C\\" Middle School",
"skills": [
"JavaScript",
"Java",
"Python",
"Lisp"
]
}
第二個(gè)參數(shù)用于控制如何篩選對(duì)象的鍵值瞒爬,如果我們只想輸出指定的屬性,可以傳入Array:
JSON.stringify(xiaoming, ['name', 'skills'], ' ');
結(jié)果:
{
"name": "小明",
"skills": [
"JavaScript",
"Java",
"Python",
"Lisp"
]
}
還可以傳入一個(gè)函數(shù)沟堡,這樣對(duì)象的每個(gè)鍵值對(duì)都會(huì)被函數(shù)先處理:
function convert(key, value) {
if (typeof value === 'string') {
return value.toUpperCase();
}
return value;
}
JSON.stringify(xiaoming, convert, ' ');
上面的代碼把所有屬性值都變成大寫(xiě):
{
"name": "小明",
"age": 14,
"gender": true,
"height": 1.65,
"grade": null,
"middle-school": "\\"W3C\\" MIDDLE SCHOOL",
"skills": [
"JAVASCRIPT",
"JAVA",
"PYTHON",
"LISP"
]
}
如果我們還想要精確控制如何序列化小明侧但,可以給xiaoming定義一個(gè)toJSON()的方法,直接返回JSON應(yīng)該序列化的數(shù)據(jù):
var xiaoming = {
name: '小明',
age: 14,
gender: true,
height: 1.65,
grade: null,
'middle-school': '\\"W3C\\" Middle School',
skills: ['JavaScript', 'Java', 'Python', 'Lisp'],
toJSON: function () {
return { // 只輸出name和age航罗,并且改變了key:
'Name': this.name,
'Age': this.age
};
}
};
JSON.stringify(xiaoming); // '{"Name":"小明","Age":14}'
4.2.反序列化
拿到一個(gè)JSON格式的字符串禀横,我們直接用JSON.parse()把它變成一個(gè)JavaScript對(duì)象:
JSON.parse('[1,2,3,true]'); // [1, 2, 3, true]
JSON.parse('{"name":"小明","age":14}'); // Object {name: '小明', age: 14}
JSON.parse('true'); // true
JSON.parse('123.45'); // 123.45
JSON.parse()還可以接收一個(gè)函數(shù),用來(lái)轉(zhuǎn)換解析出的屬性:
JSON.parse('{"name":"小明","age":14}', function (key, value) {
// 把number * 2:
if (key === 'name') {
return value + '同學(xué)';
}
return value;
}); // Object {name: '小明同學(xué)', age: 14}
在JavaScript中使用JSON粥血,就是這么簡(jiǎn)單柏锄!