當程序須要將值保存起來以備未來使用時,便將其賦值給一個變量,值的類型稱做數據類型。javascript
JavaScript 的變量是鬆散類型的,所謂鬆散類型就是能夠用來保存任何類型的數據。換句話說,每一個變量僅僅是一個用於保存值的佔位符而已。定義變量時要使用關鍵字 var
來聲明的,以下所示:java
var message;複製代碼
這行代碼定義了一個名爲 message
的變量,該變量能夠用來保存任何值(像這樣未通過初始化的變量,會保存一個特殊的值 undefined
)。JavaScript 也支持直接初始化變量,所以在定義變量的同時就能夠設置變量的值,以下所示:git
var message = "hello";複製代碼
此時,變量 message
中保存了一個字符串值 "hello"
。像這樣初始化變量並不會把它標記爲字符串類型,所以,能夠在修改變量值的同時修改值的類型。以下所示:github
var message = "hello";
message = 100; // 有效的語句,很差的寫法複製代碼
在這個例子中,變量 message
一開始保存了一個字符串值 "hello"
,而後該值又被一個數字值100取代。雖然咱們不建議修改變量所保存值的類型,但這種操做在 JavaScript 中徹底有效。編程
有一點必須注意,即便用 var
運算符定義的變量是的該做用域中的局部變量。也就是說,若是在函數中使用 var
定義一個變量,那麼這個變量在函數退出後就會被銷燬,例如:微信
function test(){
var message = "hello"; // 局部變量
}
test();
console.log(message); // 產生錯誤複製代碼
這裏,變量 message
是在函數中使用 var
定義的,是局部變量。當函數被調用時,就會建立該變量併爲其賦值。而在此以後,這個變量又會當即被銷燬,所以例子中的下一行代碼就會致使錯誤。不過,能夠像下面這樣省略 var
運算符,從而建立一個全局變量:數據結構
function test(){
message = "hello"; // 全局變量,很差的寫法
}
test();
console.log(message); // "hello"複製代碼
這個例子省略了 var
運算符,於是 message
就成了全局變量。這樣,只要調用一次 test()
函數,這個變量就有了定義,就能夠在函數外部的任何地方被訪問到。less
雖然省略 var
運算符能夠定義全局變量,但這也不是推薦的作法,由於在局部做用域中定義全局變量很難維護,給未經聲明的變量賦值在嚴格模式下會拋出 ReferenceError
錯誤。編程語言
JavaScript 中有5種簡單數據類型(也稱爲「基本數據類型」或「原始數據類型」):Undefined
、Null
、Boolean
、Number
、String
。還有1種複雜數據類型 Object
,Object
本質上是由一組無序的名值對組成的。JavaScript 不支持任何建立自定義類型的機制,全部值最終都將是上述6種數據類型之一。函數
typeof
運算符鑑於 JavaScript 是鬆散類型的,所以須要有一種手段來檢測給定變量的數據類型,typeof
就是負責提供這方面信息的運算符。對一個值使用 typeof
運算符可能返回下列某個字符串:
"undefined"
,若是這個值未聲明或已聲明但未初始化。"boolean"
,若是這個值是布爾值。"string"
,若是這個值是字符串。"number"
,若是這個值是數值。"object"
,若是這個值是對象或 null
。"function"
,若是這個值是函數。下面是幾個使用 typeof
運算符的例子:
var message = "some string";
console.log(typeof message); // "string"
console.log(typeof(message)); // "string"
console.log(typeof 95); // "number"複製代碼
從以上例子能夠看出,typeof
運算符既能夠對變量使用,又能夠對字面量使用。因爲 typeof
是一個運算符而不是函數,所以例子中的圓括號儘管可使用,但並不提倡。
typeof null
結果是 "object"
是歷史遺留 Bug,在 ECMAScript 6中,曾經有提案爲歷史平反, 將 type null
的值糾正爲 "null"
,但最後該提案被拒。理由是歷史遺留代碼太多,不如繼續將錯就錯。
從技術角度講,函數在 JavaScript 中是對象,不是一種數據類型。然而,函數也確實有一些特殊的屬性,所以經過 typeof
運算符來區分函數和其餘對象是有必要的。
擴展閱讀「爲何 JavaScript 裏面
typeof null
的值是"object"
?」
www.zhihu.com/question/21…擴展閱讀「MDN 之
typeof
」
developer.mozilla.org/zh-CN/docs/…擴展閱讀「JavaScript 檢測原始值、引用值、屬性」
shijiajie.com/2016/06/20/…擴展閱讀「JavaScript 檢測之 basevalidate.js」
shijiajie.com/2016/06/25/…
Undefined
類型Undefined
類型只有1個值,即 undefined
。使用 var
聲明變量但未對其加以初始化時,這個變量的值就是 undefined
,直接使用未聲明的變量會產生錯誤。對未聲明或已聲明但未初始化的變量執行 typeof
運算符會返回 "undefined"
值,例如:
var message; // 這個變量聲明以後默認取得了 undefined 值
// var age // 這個變量並無聲明
console.log(message); // "undefined"
console.log(age); // 產生錯誤
console.log(typeof message); // "undefined"
console.log(typeof age); // "undefined"複製代碼
Null
類型Null
類型也只有1個值,即 null
。它用來表示值的空缺。你能夠認爲 undefined
是表示系統級的、出乎意料的或相似錯誤的值的空缺,而 null
是表示程序級的、正常的或在乎料之中的值的空缺。在下列場景中應當使用 null
。
在下列場景中不該當使用 null
。
null
來檢測是否傳入了某個參數。null
來檢測一個未初始化的變量。Boolean
類型Boolean
類型是 JavaScript 中使用得最多的一種類型,該類型只有兩個字面值:true
和 false
。須要注意的是,他們是區分大小寫的,也就是說 True
和 False
(以及其餘的混合大小寫形式)都不是 Boolean
值,只是標識符。
雖然 Boolean
類型的字面值只有兩個,但 JavaScript 中全部類型的值都能使用 if
語句或 Boolean()
函數轉換爲對應的 Boolean
值,例如:
var message = "Hello world!";
if (message){
console.log("Value is true."); // 被執行
}
var messageAsBoolean = Boolean(message);
console.log(messageAsBoolean); // true複製代碼
下表給出了各類數據類型及其對應的轉換規則。
數據類型 | 轉換爲true的值 | 轉換爲false的值 |
---|---|---|
Undefined | - | undefined |
Null | - | null |
Boolean | true | false |
String | 任何非空字符串 | ""(空字符串) |
Number | 任何非零數字值(包括無窮大) | 0和NaN |
Object | 任何對象 | - |
Number
類型Number
類型是 JavaScript 中最使人關注的數據類型,這種類型使用 IEEE 754 格式來表示整數和浮點數值(浮點數值在某些語言中也被稱爲雙精度數值)。和其餘編程語言不一樣,JavaScript 中的全部數字均用浮點數值表示。
擴展閱讀「IEEE 754-1985」
en.wikipedia.org/wiki/IEEE_7…
在 JavaScript 中進行算術計算時,全部以八進制和十六進制表示的數值最終都將被轉換成十進制數值。例如:
var a = 10; // 十進制
var b = 023; // 八進制
var c = 0x12ac; // 十六進制
console.log(b); // 19
console.log(c); // 4780複製代碼
八進制第一位必須是0,後面跟八進制序列0到7,若是超出了範圍,則忽略前導0,後面的數值當作十進制解析,例如:089會被解析爲89。(八進制字面量在嚴格模式下是無效的,會拋出錯誤。)
十六進制前兩位必須是 0x 或 0X,後跟十六進制序列0~九、a~f(不區分大小寫),若是超出了範圍,則會報語法錯誤。
所謂浮點數值,就是該數值中必須包含一個小數點,而且小數點後面必須至少有一位數字。雖然小數點前面能夠沒有整數,但咱們不推薦這種寫法。例如:
var a = 1.1;
var b = 0.1;
var c = .1; // 有效,但不推薦複製代碼
JavaScript 會不失時機的將浮點數轉換成整數。例如:
var a = 5.; // 解析成整數5
var b = 5.0; // 解析成整數5複製代碼
對於極大或者極小的數值,可採用科學技術法(也稱e表示法)。JavaScript 會將那些小數點後面帶有6個零以上的小於1的浮點數值轉換爲以e表示法表示的數值。例如:
var a = 3.14e7; // 等於31400000
var b = 3.14E-7; // 等於0.000000314
console.log(0.0000003); // 3e-7複製代碼
浮點數值的最高精度是17位小數,但在進行算術計算時其精確度遠遠不如整數,例如:
console.log(0.1 + 0.2); // 0.30000000000000004複製代碼
這個舍入偏差會致使沒法測試特定的浮點數值,所以,永遠不要測試某個特定的浮點數值。
因爲內存限制,JavaScript 能表示的數值範圍從 Number.MIN_VALUE
到 Number.MAX_VALUE
,並將超出範圍的數轉換成 Number.POSITIVE_INFINITY
或 Number.NEGATIVE_INFINITY
。0做爲除數是不會報錯的,正數除以0返回正無窮,負數除以0返回負無窮,0除以0返回NaN
。例如:
console.log(Number.MAX_VALUE); // 最大數 1.7976931348623157e+308
console.log(Number.MIN_VALUE); // 最小數 5e-324
console.log(Number.POSITIVE_INFINITY); // 正無窮 Infinity
console.log(Number.NEGATIVE_INFINITY); // 負無窮 -Infinity
console.log( 1 / 0); // Infinity
console.log(-1 / 0); // -Infinity複製代碼
JavaScript 提供了 isFinite()
函數,來肯定一個數是否是有窮的。例如:
console.log(isFinite(100)); // true
console.log(isFinite(Infinity)); // false複製代碼
NaN
(not a number),是一個特殊的數值。之因此稱它爲「非數值」,是由於它不能參與算數運算,任何涉及 NaN
的操做都返回 NaN
。而且 NaN
與任何值都不相等(包括自身)。例如:
console.log(typeof NaN); // "number"
console.log(0 / 0); // NaN
console.log(NaN - NaN); // NaN
console.log(Infinity - Infinity); // NaN
var a = NaN;
console.log(a === a); // false複製代碼
JavaScript 提供了 isNaN()
函數,來肯定一個數是否是 NaN
。例如:
console.log(isNaN(100)); // false
console.log(isNaN("100")); // false
console.log(isNaN(true)); // false
console.log(isNaN("sss")); // true
console.log(isNaN(NaN)); // true複製代碼
Number()
、parseInt()
、parseFloat()
轉型函數isNaN()
函數在接收到一個值以後,會嘗試使用轉型函數 Number()
將這個值轉換爲數值,轉換規則以下:
undefined
轉換爲 NaN
;null
轉換爲 0;true
轉換爲 1
、false
轉換爲 0
;number
整數轉換爲十進制,小數不變;string
若是隻包含十進制數和小數,則返回對應的數值,若是隻包含八進制數,則忽略前導0返回剩餘部分,若是隻包含十六進制,則返回十進制數,空字符串轉換爲0,其它字符串轉換爲 NaN
;object
先則調用對象的 valueOf()
方法,而後依照前面的規則轉換返回的值。若是轉換的結果是 NaN
,則調用對象的 toString()
方法,而後再次依照前面的規則轉換返回的字符串值。因爲 Number()
轉型函數在轉換字符串時不夠理想,所以還有兩個專門用來轉換字符串的函數 parseInt()
和 parseFloat()
函數。
parseInt()
函數會忽略字符串前面的空格,直至找到第一個非空格字符,只要第一個非空格字符不是數字或者正負號,一概返回 NaN
, 若是第一個非空格字符是數字字符,parseInt()
會繼續解析第二個字符,直到解析完全部後續字符或者遇到了一個非數字字符。例如:
console.log(parseInt("")); // NaN(Number("")返回 0)
console.log(parseInt("123S")); // 123
console.log(parseInt("12.4")); // 12複製代碼
parseFloat()
函數也會忽略字符串前面的空格,直至找到第一個非空格字符,只要第一個非空格字符不是數字或者正負號或者小數點,一概返回 NaN
, 若是第一個非空格字符是上述字符之一,parseFloat()
會繼續解析第二個字符,直到解析完全部後續字符或者遇到了一個非浮點數值。例如:
console.log(parseFloat("098.2")); // 98.2
console.log(parseFloat("123.23.23")); // 123.23複製代碼
String
類型String
類型用於表示由零或多個16位 Unicode 字符組成的字符序列,即字符串。字符串能夠由雙引號(")或單引號(')表示,所以下面兩種字符串的寫法都是有效的:
var firstName = "Nicholas";
var lastName = 'Zakas';複製代碼
JavaScript 中的這兩種語法形式沒有什麼區別。用雙引號表示的字符串和用單引號表示的字符串徹底相同。不過,以雙引號開頭的字符串也必須以雙引號結尾,而以單引號開頭的字符串必須以單引號結尾。
String
數據類型包含一些特殊的字符字面量,也叫轉義序列,用於表示非打印字符,或者具備其餘用途的字符。例如:\n
換行、\t
製表、\b
空格、\r
回車、\f
進紙、\\
斜槓、\'
單引號,在用單引號表示的字符串中使用、\"
雙引號,在用雙引號表示的字符串中使用。
轉義字符可出如今字符串中的任意位置,且長度爲1。如要在字符串中顯示 \
,則必須使用 \
進行轉義。例如:
console.log("\n\\".length); // 2
console.log("\\hello"); // "\hello"(長度爲6)複製代碼
大部分值均可以使用繼承而來的 toString()
方法轉換爲字符串,但 undefined
和 null
值沒有這個方法。對數值使用 toString()
方法時,能夠傳入一個數字基數,以此輸出對應進制的字符串值。例如:
console.log(true.toString()); // "true"
var num = 10;
console.log(num.toString()); // "10"
console.log(num.toString(2)); // "1010"
console.log(num.toString(8)); // "12"
console.log(num.toString(16)); // "a"複製代碼
在不知道要轉換的值是否是 undefined
或 null
的狀況下,還可使用轉型函數 String()
,這個函數可以將任何類型的值轉換爲字符串。String()
函數遵循下列轉換規則:
toString()
方法,則調用該方法(沒有參數)並返回相應的結果;undefined
,則返回 "undefined"
;null
,則返回 "null"
。var value;
console.log(String(10)); // "10"
console.log(String(true)); // "true"
console.log(String(null)); // "null"
console.log(String(value)); // "undefined"複製代碼
Object
類型JavaScript 中全部對象都繼承自 Object
類型,每一個對象都具備下列基本的屬性和方法:
constructor
:保存着用於建立當前對象的函數(構造函數)。hasOwnProperty()
:用於檢查給定的屬性在當前對象實例中是否存在。propertyIsEnumerable()
:用於檢查給定的屬性是否可以使用for-in語句來枚舉。isPrototypeOf()
:用於檢查對象是不是傳入對象的原型。toString()
方法:返回對象的字符串表示。toLocaleString()
:返回對象的本地字符串表示。valueOf()
:返回對象的字符串、數值或布爾值表示(一般與toString()方法的返回值相同)。Object
本質上是由一組無序的名值對組成,「名稱」部分是一個 JavaScript 字符串,「值」部分能夠是任何 JavaScript 的數據類型(包括對象和方法)。這使用戶能夠根據具體需求,建立出至關複雜的數據結構。
如下兩種方法均可以建立一個空對象,這兩種方法在語義上是相同的。第二種更方便的方法叫做「對象字面量」法。這也是 JSON 格式的核心語法,通常咱們優先選擇第二種方法。例如:
var obj = new Object();
var obj = {}; // 好的寫法複製代碼
「對象字面量」也能夠用來在對象實例中定義一個對象:
var obj = {
name: "Carrot",
"for": "Max",
details: {
color: "orange",
size: 12
}
}複製代碼
對象的屬性能夠經過鏈式(chain)表示方法進行訪問:
obj.details.color; // orange
obj["details"]["size"]; // 12複製代碼
完成建立後,對象屬性能夠經過以下兩種方式進行賦值和訪問:
obj.name = "Simon" // 賦值
var name = obj.name; // 訪問
obj["name"] = "Simon"; // 賦值
var name = obj["name"]; // 訪問複製代碼
// 挑戰一
console.log(typeof "undefined"); // ???
console.log(typeof null); // ???複製代碼
// 挑戰二
var message = "some string";
console.log(typeof massage); // ???
message = 10000;
console.log(typeof message); // ???複製代碼
// 挑戰三
var a;
var b = null;
var c = {};
if(a && b && c){
console.log("true."); // ???
}else{
console.log("false."); // ???
}複製代碼
// 挑戰四
console.log(typeof (0 / 0)); // ???
console.log(023 + 123); // ???複製代碼
// 挑戰五
console.log(Number("1234S")); // ???
console.log(parseInt("1234S")); // ???複製代碼
// 挑戰六
console.log(3.14E-7 === 0.000000314); // ???
console.log(0.1 + 0.6 === 0.7); // ???
console.log(0.1 + 0.7 === 0.8); // ???
console.log(NaN === NaN); // ???複製代碼
// 挑戰七
console.log("\right\now"); // ???
console.log("\right\now".length); // ???
console.log(010.toString(2)); // ???複製代碼
// 挑戰八
// 一、爲 person、wife、child 對象新增 weight 屬性,數值分別爲 6二、3六、15。
// 二、爲 person 對象新增二胎 child2 子對象,name 爲 emma,其餘屬性自行發揮。
var person = {
name: "stone",
age: 30,
wife: {
name: "sohpie",
age: 30
},
child:{
name: "tommy",
age: 3
}
}複製代碼
挑戰九,深度閱讀下面兩篇文章,提出你的疑問。
「JavaScript 檢測原始值、引用值、屬性」
shijiajie.com/2016/06/20/…「JavaScript 檢測之 basevalidate.js」
shijiajie.com/2016/06/25/…
關注微信公衆號「劼哥舍」回覆「答案」,獲取關卡詳解。
關注 github.com/stone0090/j…,獲取最新動態。