一、基本語法
- 基本語法
- JavaScript的每個語句以
;
結束,語句塊在花括號內{...}
。 - JavaScript并不強制要求在每個語句的結尾加
;
,瀏覽器中負責執行JavaScript代碼的引擎會自動在每個語句的結尾補上;
。 - 語句具有縮進,通常是4個空格。非必須,但可以增強可讀性!
- 請注意: JavaScript嚴格區分大小寫!
注釋:
行注釋://
塊注釋:/*...*/
變量
關鍵字:var
變量名:
- 是
大小寫英文、數字、$和_(下劃線)
的組合。 - 且不能用數字開頭。
- 不能是JavaScript的關鍵字。
- 嚴格區分大小寫
var a; // 申明了變量a,此時a的值為undefined類型
var $b = 1; // 申明了變量$b,同時給$b賦值,此時$b的值為1
var s_007 = '007'; // s_007是一個字符串
var Answer = true; // Answer是一個布爾值true
var t = null; // t的值是null
-
動態語言:
在JavaScript中,使用等號=對變量進行賦值。可以把任意數據類型賦值給變量,同一個變量可以反復賦值,而且可以是不同類型的變量:
var a = 123; // a的值是整數123
a = 'ABC'; // a變為字符串
-
strict模式:
如果一個變量沒有通過var
申明就被使用,那么該變量就自動被申明為全局變量; 為了修補JavaScript這一嚴重設計缺陷,ECMA在后續規范中推出了strict模式('use strict')
,在strict模式下運行的JavaScript代碼,強制通過var
申明變量,未使用var
申明變量就使用的,將導致運行錯誤。
二、數據類型
基本數據類型:number, string, boolean, undefined (儲存數據)
引用數據類型:Number, String, Boolean, Object, Array, Function, Date,null (儲存數據和功能)
基本類型 & 引用類型的對比:
基本類型只是儲存數據,在 棧 開辟內存;
引用類型即能儲存數據也能儲存功能(函數),變量內在在棧內,存儲地址,指向在 堆 開辟內存存儲的數據。

//基本類型有對應的引用類型:
//number--->Number boolean--->Boolean string--->String
var a = "abc"; //基本類型字符串:string類型
var s = new Sting("abc"); //引用類型的字符串:Object類型
//最大的區別是:
a.text = "呵呵"; //基本類型不能添加屬性
s.text = "哈哈"; //引用類型能添加屬性
//引用類型的空 null
Number類型
JavaScript不區分整數和浮點數,統一用Number表示。
123; // 整數123
0.456; // 浮點數0.456
1.2345e3; // 科學計數法表示1.2345x1000,等同于1234.5
-99; //負數
NaN; //NaN表示Not a Number,不是一個數字
Infinity; // Infinity表示無限大,當數值超過了JavaScript的Number所能表示的最大值時,就表示為Infinity
進制
十進制:
八進制:0_
十六進制:0x_
對照表:
十進制(D) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
二進制(B) 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
八進制(O) 0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17
十六進制(H) 0 1 2 3 4 5 6 7 8 9 A B C D E F
二進制:電信號開關
1 byte = 8bit <比特位>
1k = 1024 byte
1M = 1024k
八進制由來:每三位bit表示一位數字 就產生的八進制!
三個bit最大數值是:111 即7;
十六進制:每四個bit表示一位數字 就產生了十六進制。
四個bit最大數值是:1111 即15;
進制轉換:
十進制轉成其他進制:反復除以進制值取余數!
其他進制轉換十進制:進制冪數和
字符串String
字符串是以單引號'
或雙引號"
括起來的任意文本, 字符串abc由a,b,c
這3個字符。
"abc"
'abc'
連接符和轉義字符
連接符: +
- 字符串類型和任何類型相連接,最終都是字符串類型!
var name = '小明';
var age = 20;
var message = '你好, ' + name + ', 你今年' + age + '歲了!';
轉義字符:\ <反斜杠>
\n 換行
\t 制表符tab健
\\ \
\" "
//ASCII字符可以以` \x## `形式的十六進制表示:
'\x41'; //完全等同于 'A'
//還可以用` \u#### `表示一個Unicode字符:
'\u4e2d\u6587'; //完全等同于 '中文'
模板字符串: ${}
var name = '小明';
var age = 20;
var message = `你好, ${name}, 你今年${age}歲了!`;
字符串的常用Api
//字符串長度:
var s = 'Hello, world!';
s.length; // 13 空格 符號都計算在內
//下標:獲取字符串指定位置的字符,索引號從0開始:
var s = 'Hello, world!';
s[0]; // 'H'
s[13]; //undefined 超出范圍的索引不會報錯,但一律返回undefined
//charAt(index) 獲取對應索引的字符
var ss = "abc0123def&#*";
ss.charAt(ss.length-1); //*
ss.charAt(-1); //不存在返回空“_”
//遍歷字符串
for (var i = 0; i < ss.length; i++) {
document.write(ss.charAt(i));
document.write("<br />");
}
//charCodeAt(index) 獲取索引對應的字符的ASCII編碼
ss.charCodeAt(3) //48
//fromCharCode() 根據ASCII編碼生成字符串
var str = String.fromCharCode(48,49,90);
//indexOf(str) 指定字符or字符串 第一次出現的位置
//indexOf(str,posotion) 從指定位置開始第一次出現的位置
//lastIndexOf(str) 最后一次出現的位置
var s = 'hello, world';
s.indexOf('world'); // 返回7
s.indexOf('World'); // 沒有找到指定的子串,返回-1
//截取
//substr(index) //截取index開始至末尾,返回截取的新字符串
//substr(index1,num) //截取index開始截取 num 個字符串,返回截取的新字符串
//subString(index)
//subString(index1,index2) //截取index1 到 index2-1 之間的字符
var s = 'hello, world'
s.substring(0, 5); //從索引0開始到5(不包括5),返回'hello'
s.substring(7); // 從索引7開始到結束,返回'world'
//match(str) 返回匹配的字符串,是一個數組(引用類型)
//search(str) str第一次出現時的起始位置
//replace(str1,str2) 用str2替換第一次出現的str1;返回新字符串
//split(",") //根據,切割字符串,返回一個數組
//toUpperCase(): 全部變為大寫
//toLowerCase(): 全部變為小寫
var s = 'Hello';
s.toUpperCase(); // 返回'HELLO'
s.toLowerCase(); // 返回'hello'
布爾值boolean
一個布爾值只有true
、false
兩種值。
true; // 這是一個true值
false; // 這是一個false值
2 > 1; // 這是一個true值
2 >= 3; // 這是一個false值
null和undefined類型
null
表示一個“空”的值,它和0
以及空字符串''
不同,0
是一個數值,''
表示長度為0
的字符串,而null
表示“空”的引用類型。
undefined
表示值未定義類型。
var a;
typeof a //獲取變量a的類型(undefined)
數組Array
數組是一組按順序排列的集合,集合的每個值稱為元素。JavaScript的數組可以包括任意數據類型。
//數組初始化
//數組用` [] `表示,元素之間用` , `分隔。
var arr1 = [1, 2, 3.14, 'Hello', null, true]; //字面量的方式
//另一種創建數組的方法是通過` Array() `函數實現:
var arr2 = new Array(1, 2, 3); // 創建了數組[1, 2, 3]
var arr3 = new Array(10); //長度為10 的數據
var arr4 = new Array(); //長度為0的數據,可以添加數據
數組的常用Api
//數組的元素可以通過索引來訪問,索引的起始值為0:
var arr = [1, 2, 3.14, 'Hello', null, true];
arr[0]; // 返回索引為0的元素,即1
arr[5]; // 返回索引為5的元素,即true
arr[6]; // 索引超出了范圍,返回undefined
//可以通過索引把對應的元素修改為新的值:
var arr = ['A', 'B', 'C'];
arr[1] = 99;
arr; // arr現在變為['A', 99, 'C']
//通過索引賦值時,即使索引超過了范圍,同樣會引起Array大小的變化:
var arr = [1, 2, 3];
arr[5] = 'x';
arr; // arr變為[1, 2, 3, undefined, undefined, 'x']
// 要取得Array的長度,直接訪問length屬性:
var arr = [1, 2, 3.14, 'Hello', null, true];
arr.length; // 6
//注意: 直接給length賦一個新的值會導致Array大小的變化:
var arr = [1, 2, 3];
arr.length; // 3
arr.length = 6;
arr; // arr變為[1, 2, 3, undefined, undefined, undefined]
arr.length = 2;
arr; // arr變為[1, 2]
// indexOf() : 搜索指定的元素的位置
var arr = [10, 20, '30', 'xyz'];
arr.indexOf(10); // 元素10的索引為0
arr.indexOf(60); // 元素30沒有找到,返回-1
arr.indexOf('30'); // 元素'30'的索引為2
// slice() : 截取Array的部分元素,返回一個新的Array;原有數組不變
var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
arr.slice(0, 3); // 從索引0開始,到索引3結束,但不包括索引3: ['A', 'B', 'C']
arr.slice(3); // 從索引3開始到結束: ['D', 'E', 'F', 'G']
arr.slice(); //如果不給slice()傳遞任何參數,它就會從頭到尾截取所有元素。復制一個Array。
// push() 向Array的末尾添加若干元素,返回新數據長度
// pop() 把Array的最后一個元素刪除掉,返回被刪除值
var arr = [1, 2];
arr.push('A', 'B'); // 返回Array新的長度: 4
arr; // [1, 2, 'A', 'B']
arr.pop(); // pop()返回'B'
arr; // [1, 2, 'A']
arr.pop(); arr.pop(); arr.pop(); // 連續pop 3次
arr; // []
arr.pop(); // 空數組繼續pop不會報錯,而是返回undefined
arr; // []
//unshift() 往Array的頭部添加若干元素,返回新數據長度
//shift() 把Array的第一個元素刪掉,返回被刪除值
var arr = [1, 2];
arr.unshift('A', 'B'); // 返回Array新的長度: 4
arr; // ['A', 'B', 1, 2]
arr.shift(); // 'A'
arr; // ['B', 1, 2]
arr.shift(); arr.shift(); arr.shift(); // 連續shift 3次
arr; // []
arr.shift(); // 空數組繼續shift不會報錯,而是返回undefined
arr; // []
// splice() 修改Array的“萬能方法”,它可以從指定的索引開始刪除若干元素,然后再從該位置添加若干元素
// 實現 刪除 添加 替換 功能!
var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 替換:從索引2開始刪除3個元素,然后再添加兩個元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回刪除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只刪除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不刪除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因為沒有刪除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// sort() 對當前Array進行排序,它會直接修改當前Array的元素位置
var arr = [6,3,17,"a","B","你好"];
arr.sort(); //默認按照ASCII字符順序排序 [17,3,6,B,a,你好]
//傳參:定義排序規則的函數(函數的返回值:負值---前者比后者小 零---相等 正值---前者比后者大)
function paixu(m,n){
if (m>n) {
return 1;
} else if (m==n) {
return 0
} else {
return -1;
}
}
arr.sort(paixu); //[B,a,你好,3,6,17]
// reverse() 把整個Array的元素反轉
var arr = ['one', 'two', 'three'];
arr.reverse();
arr; // ['three', 'two', 'one']
// concat() 把當前的Array和另一個Array連接起來,返回一個新的Array
var arr = ['A', 'B', 'C'];
var added = arr.concat([1, 2, 3]);
added; // ['A', 'B', 'C', 1, 2, 3]
arr; // ['A', 'B', 'C']
實際上,concat()方法可以接收任意個元素和Array,并且自動把Array拆開,然后全部添加到新的Array里:
var arr = ['A', 'B', 'C'];
arr.concat(1, 2, [3, 4]); // ['A', 'B', 'C', 1, 2, 3, 4]
// join() 把當前Array的每個元素都用指定的字符串連接起來,然后返回連接后的字符串:
var arr = ['A', 'B', 'C', 1, 2, 3];
arr.join('-'); // 'A-B-C-1-2-3'
//toString() 把數據轉成字符串,逗號鏈接
var arr = ['A', 'B', 'C', 1, 2, 3];
arr.toString(); // 'A,B,C,1,2,3'
多維數組
如果數組的某個元素又是一個Array,則可以形成多維數組:
var arr = [[1, 2, 3], [400, 500, 600], '-'];
var x = arr[1][1]; //返回 500
對象Object
JavaScript的對象是一組由鍵-值組成的無序集合;
- 鍵都是字符串類型(每個鍵又稱為對象的屬性),
- 值可以是任意數據類型。
JavaScript用一個{...}表示一個對象,
鍵值對以xxx: xxx形式申明,用,隔開。
//創建對象:四種方式
var obj1 = new Object();
var obj2 = Object();
var obj3 = {}
var xiaoming = {
name: '小明',
birth: 1990,
school: 'No.1 Middle School',
height: 1.70,
weight: 65,
score: null
newfunc: function() { //可以直接賦值匿名函數
alert("newfunc")
}
};
//訪問屬性: 點語法:對象變量.屬性名
xiaoming.name; // '小明'
xiaoming.birth; // 1990
xiaoming.age; // 訪問不存在的屬性,返回undefined
//JavaScript的對象是動態類型,可以自由地給一個對象添加或刪除屬性:
var xiaoming = {
name: '小明'
};
xiaoming.age = 18; // 新增一個age屬性
xiaoming.age; // 18
delete xiaoming.age; // 刪除age屬性
xiaoming.age; // undefined
delete xiaoming.school; // 刪除一個不存在的school屬性也不會報錯
// in 檢測是否擁有某一屬性:
var xiaoming = {
name: '小明',
birth: 1990,
school: 'No.1 Middle School',
height: 1.70,
weight: 65,
score: null
};
'name' in xiaoming; // true
'grade' in xiaoming; // false
//不過要小心,如果in判斷一個屬性存在,這個屬性不一定是xiaoming的,它可能是xiaoming繼承得到的:
'toString' in xiaoming; // true 因為toString定義在object對象中,而所有對象最終都會在原型鏈上指向object,所以xiaoming也擁有toString屬性。
要判斷一個屬性是否是xiaoming自身擁有的,而不是繼承得到的,可以用hasOwnProperty()方法:
var xiaoming = {
name: '小明'
};
xiaoming.hasOwnProperty('name'); // true
xiaoming.hasOwnProperty('toString'); // false
Map & Set
JavaScript的對象有個小問題,就是鍵必須是字符串。但實際上Number或者其他數據類型作為鍵也是非常合理的。
為了解決這個問題,最新的ES6規范引入了新的數據類型 Map 和 Set。
注意:Map和Set是ES6標準新增的數據類型,請根據瀏覽器的支持情況決定是否要使用。
Map:
Map是一組鍵值對的結構,具有極快的查找速度。
var m = new Map(); //初始化一個空Map
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]); //初始化Map
m.set('Adam', 67); // 添加新的key-value
m.set('Bob', 59);
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 獲取key對應的值 67
m.delete('Adam'); // 刪除key 'Adam'
m.get('Adam'); // undefined
//注意:一個key只能對應一個value
var m = new Map();
m.set('Adam', 67);
m.set('Adam', 88);
m.get('Adam'); // 88 會沖掉前面的賦值
Set:
Set是一組key的集合,但不存儲value。key不能重復。
var s1 = new Set(); // 初始化一個空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3
var s = new Set([1, 2, 3, 3, '3']); //重復元素在Set中自動被過濾:
s.add(4) //添加元素
s.delete(3); //刪除元素
iterable類型
遍歷Array可以采用下標循環,遍歷Map和Set就無法使用下標。為了統一集合類型,ES6標準引入了新的iterable
類型,Array、Map和Set都屬于iterable類型。具有iterable類型的集合可以通過新的for ... of
循環來遍歷。
注意:for ... of循環是ES6引入的新的語法,請測試你的瀏覽器是否支持!
用for ... of循環遍歷集合,用法如下:
var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍歷Array
alert(x);
}
for (var x of s) { // 遍歷Set
alert(x);
}
for (var x of m) { // 遍歷Map
alert(x[0] + '=' + x[1]);
}
然而,更好的方式是直接使用iterable內置的forEach方法,它接收一個函數,每次迭代就自動回調該函數:
var a = ['A', 'B', 'C'];
a.forEach(function (element, index, array) {
// element: 指向當前元素的值
// index: 指向當前索引
// array: 指向Array對象本身
alert(element);
});
var s = new Set(['A', 'B', 'C']);
s.forEach(function (element, sameElement, set) {
alert(element);
});
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
alert(value);
});
//如果對某些參數不感興趣,由于JavaScript的函數調用不要求參數必須一致,因此可以忽略它們:
var a = ['A', 'B', 'C'];
a.forEach(function (element) {
alert(element);
});
三、運算符
表達式:運算符和變量常量組合在一起就叫做表達式!表達式一定有值!
5.1 算術運算符
+ - * / % ++ --
++ 前后的區別
--
5.2 賦值運算符
= += -= /= *= %=
5.3 關系運算符
返回值:true false
> >= < <= == === != !==
== 只比較數值,不比較類型 100 == ”100“(true)
=== 比較數值和數據類型 100 == ”100“(fasle)
!= 只比較數值,不比較類型 100 == ”100“(fasle)
!== 比較數值和數據類型 100 == ”100“(true)
==: 它會自動轉換數據類型再比較;
=== : 它不會自動轉換數據類型,如果數據類型不一致,返回false
一個例外是NaN,這個特殊的Number與所有其他值都不相等,包括它自己:
NaN === NaN; // false
唯一能判斷NaN的方法是通過isNaN()函數:
isNaN(NaN); // true
5.4 條件運算符
?:
(表達式):(值1)?(值2)
5.5 邏輯運算符
或與非: || && !
表達式值:true false
短路計算:
&&:當前面一個條件不滿足即可返回,不再計算右邊余下表達式的值。
||:當前面一個條件為true可返回,不再計算右邊余下表達式的值。
3&&6 返回6-true
0&&6 返回0
“hello”&&“world” 返回值world (空字符串相當于false,非空字符串相當于true)
“”&&“hello” 返回值“”
5.6 typeof運算符
js是弱類型語言,var 變量可以存放各種類型;通過(typeof 變量名) 獲取數據類型
四、流程控制
4.1 條件語句
- if&ife結果語句
if (true) {
...
}
if (true) {
...
} else {
...
}
if ( ) {
...
} else if ( ) {
...
} else if ( ) {
...
} else {
...
}
//嵌套
if (true) {
if (true) {
}
} else {
}
注意1:單條語句 可以省略花括號。
注意2:else總是和離它最近的且沒有對應的if對應。
注意3:JavaScript把null、undefined、0、NaN
和空字符串''
視為false`,其他值一概視為true。
- switch語句:
switch ()
{
case 值1:語句; break;
case 值2:語句; break;
case 值3:語句; break;
default:語句; break; <default可以放在任何位置>
}
//注意1:case后面可以是 常量 變量 表達式。
case 9: alert("常量"); break;
case a: alert("變量"); break;
case s>90: alert("表達式"); break; //比較表達式的值
注意2:如果沒有`break`,代碼會繼續執行,向下貫穿, 且不會判斷條件。
4.2 循環結構哦
- while
while (condition)
{
//循環體
}
- do...while
do {
//循環體
}while (condition);
- for 循環
for (循環變量初始化語句; 循環條件; 循環變量的改變) {
//循環體
}
for (var i = Things.length - 1; i >= 0; i--) {
Things[i]
}
for (var i = 0; i < Things.length; i++) {
Things[i]
}
var i = 0; //第一步可以寫在外面
for (; i < Things.length; i++) {
Things[i]
}
for (var i = 0; i < Things.length; ) {
Things[i]
i++ //第三步可以寫在循環體內
}
- for...in...
var o = {
name: 'Jack',
age: 20,
city: 'Beijing'
};
for (var key in o) {
alert(key); // 'name', 'age', 'city'
}
//要過濾掉對象繼承的屬性,用hasOwnProperty()來實現:
for (var key in o) {
if (o.hasOwnProperty(key)) {
alert(key); // 'name', 'age', 'city'
}
}
//Array數組實際上也是一個對象,它的每個元素的索引被視為一個屬性。for ... in循環可以直接循環出Array的索引:
var a = ['A', 'B', 'C'];
for (var i in a) {
alert(i); // '0', '1', '2' //注意,for...in對Array的循環得到的是String而不是Number。
alert(a[i]); // 'A', 'B', 'C'
}
- break和continue
continue 結束本輪循環,繼續下一輪循環。
break 結束所在的整個循環,不影響外部循環。
flag:
for (var i = Things.length - 1; i >= 0; i--) {
Things[i]
if (true) {
break flag: //結束外部循環的方法,加標簽flag。
}
}
flag:
for (var i = Things.length - 1; i >= 0; i--) {
Things[i]
if (true) {
coutinue flag: //結束本輪的外部循環,進入下一輪
}
}