语法

JavaScript的语法和Java语言类似,每个语句以;结束,语句块用{...}。但是JavaScript并不强制要求在每个语句的结尾加;,浏览器中负责执行JavaScript代码的引擎会自动在每个语句的结尾补上;。缩进通常是4个空格。

...语句...{
    ...语句...;
    ...语句...;
    ...语句...{
        ...语句...;
    }
}

注释

以//开头直到行末的字符被视为行注释;

//alert('我不想执行');

以/*...*/把多行字符包裹起来为多行注释

/*
alert('我也不想执行');
alert('我也不想执行');
*/

变量

变量名是大小写英文、数字、$和_的组合。变量名不能用数字开头,不能是JavaScript的关键字。申明一个变量用var语句,重新给变量赋值时无需重申var

var name='wakamizu';
name='wakamizu2';

console.log

输出信息到浏览器控制台

var name='wakamizu';
console.log(name);
//输出name变量值到控制台

strict模式

在strict模式下运行的JavaScript代码,强制通过var申明变量,未使用var申明变量就使用的,将导致运行错误。

启用strict模式的方法是在JavaScript代码的第一行写上:

'use strict';

Number数据类型

JavaScript不区分整数和浮点数,统一用Number表示,以下都是合法的Number类型:

123; // 整数123
0.456; // 浮点数0.456
1.2345e3; // 科学计数法表示1.2345x1000,等同于1234.5
-99; // 负数
NaN; // NaN表示Not a Number,当无法计算结果时用NaN表示,这个特殊的Number与所有其他值都不相等,包括它自己,唯一能判断NaN的方法是通过isNaN()函数
Infinity; // Infinity表示无限大,当数值超过了JavaScript的Number所能表示的最大值时,就表示为Infinity

计算机由于使用二进制,所以,有时候用十六进制表示整数比较方便,十六进制用0x前缀和0-9,a-f表示,例如:0xff00,0xa5b4c3d2,等等,它们和十进制表示的数值完全一样。

字符串数据类型

字符串是以单引号'或双引号"括起来的任意文本,比如'abc',"xyz"等等。请注意,''或""本身只是一种表示方式,不是字符串的一部分,因此,字符串'abc'只有a,b,c这3个字符。

多行字符串

用``表示多行字符串

console.log(`多行
字符串
测试`);

模板字符串

用+号将多个字符串连接

var name= 'wakamizu';
var line='My name is';
var message=line+' '+name+'!';
console.log(message)

获取字符串长度

用length获取字符串长度

var name='wakamizu';
console.log(name.length);

大小写转换

toUpperCase()把一个字符串全部变为大写;toLowerCase()把一个字符串全部变为小写

var name='wakamizu';
console.log(name.toUpperCase());
var name='WAKAMIZU';
console.log(name.toLowerCase());

搜索字符串位置

indexOf()会搜索指定字符串出现的位置

var line = 'My name is wakamizu!';
console.log(line.indexOf('wakamizu')); // 返回11
console.log(line.indexOf('Wakamizu')); // 没有找到指定的子串,返回-1

截取字符串

substring()可以截取字符串

var line = 'My name is wakamizu!';
console.log(line.substring(11, 19)); // 从索引11开始到19(不包括19),返回'wakamizu'
console.log(line.substring(11)); // 从索引7开始到结束,返回'wakamizu!'

布尔值数据类型

布尔值和布尔代数的表示完全一致,一个布尔值只有true、false两种值,要么是true,要么是false,可以直接用true、false表示布尔值,也可以通过布尔运算计算出来

true; // 这是一个true值
false; // 这是一个false值
2 > 1; // 这是一个true值
2 >= 3; // 这是一个false值

算术运算符

运算符描述范例
求余(%)二元运算符. 返回相除之后的余数.12 % 5 返回 2。
自增(++)一元运算符. 将操作数的值加一. 如果放在操作数前面 (++x), 则返回加一后的值; 如果放在操作数后面 (x++), 则返回操作数原值,然后再将操作数加一.var x=3;console.log(++x); //4console.log(x); //4var y=3;console.log(y++); //3console.log(y); //4
自减(--)一元运算符. 将操作数的值减一. 前后缀两种用法的返回值类似自增运算符.var x=3; console.log(--x); //输入2,x=2var y=3;console.log(y--);//输出3,x=2;
一元负值符(-)一元运算符,返回操作数的负值.var x=3; console.log(-x); //输入-3
一元正值符(+)一元运算符, 如果操作数在之前不是number,试图将其转换为numberconsole.log( +'3' ); // 3console.log( '3' ); // '3'console.log(+true); // 1
指数运算符(**)计算 base(底数)的 exponent(指数)次方, 表示为baseexponent2 ** 3 returns 8.10 ** -1 returns 0.1.

位运算符

运算符使用方法描述
按位与 (AND)a & b在a,b的位表示中,每一个对应的位都为1则返回1, 否则返回0.
按位或(OR)a | b在a,b的位表示中,每一个对应的位,只要有一个为1则返回1, 否则返回0.
按位异或(XOR)a ^ b在a,b的位表示中,每一个对应的位,两个不相同则返回1,相同则返回0.
按位非(NOT)~ a反转被操作数的位。
左移(shift)a << b将a的二进制串向左移动b位,右边移入0.
算术右移a >> b把a的二进制表示向右移动b位,丢弃被移出的所有位.(译注:算术右移左边空出的位是根据最高位是0和1来进行填充的)
无符号右移(左边空出位用0填充)a >>> b把a的二进制表示向右移动b位,丢弃被移出的所有位,并把左边空出的

赋值运算符

运算符含义简写详写
赋值(Assignment)x = yx = y
加法赋值(Addition assignment)x += yx = x + y
减法赋值(Subtraction assignment)x -= yx = x - y
乘法赋值(Multiplication assignment)x *= yx = x * y
除法赋值(Division assignment)x /= yx = x / y
求余赋值(Remainder assignment)x %= yx = x % y
求幂赋值(Exponentiation assignment)x **= yx = x ** y
左移位赋值(Left shift assignment)x <<= yx = x << y
右移位赋值(Right shift assignment)x >>= yx = x >> y
无符号右移位赋值(Unsigned right shift assignment)x >>>= yx = x >>> y
按位与赋值(Bitwise AND assignment)x &= yx = x & y
按位异或赋值(Bitwise XOR assignment)x ^= yx = x ^ y
按位或赋值(Bitwise OR assignment)x |= yx = x | y

逻辑运算符

运算符范例描述
 (&&)expr1 && expr2(逻辑与) 如果expr1能被转换为false,那么返回expr1;否则,返回expr2。因此,&&用于布尔值时,当操作数都为true时返回true;否则返回false.
(||)expr1 || expr2(逻辑或) 如果expr1能被转换为true,那么返回expr1;否则,返回expr2。因此,||用于布尔值时,当任何一个操作数为true则返回true;如果操作数都是false则返回false。
 (!)!expr(逻辑非) 如果操作数能够转换为true则返回false;否则返回true。

比较运算符

运算符描述返回true的示例
等于 Equal (==)如果两边操作数相等时返回true。3 == var1
"3" == var1
3 == '3'
不等于 Not equal (!=)如果两边操作数不相等时返回truevar1 != 4
var2 != "3"
全等 Strict equal (===)两边操作数相等且类型相同时返回true。3 === var1
不全等 Strict not equal (!==)两边操作数不相等或类型不同时返回true。var1 !== "3"
3 !== '3'
大于 Greater than (>)左边的操作数大于右边的操作数返回truevar2 > var1
"12" > 2
大于等于 Greater than or equal (>=)左边的操作数大于或等于右边的操作数返回truevar2 >= var1
var1 >= 3
小于 Less than (<)左边的操作数小于右边的操作数返回truevar1 < var2
"2" < 12
小于等于 Less than or equal (<=)左边的操作数小于或等于右边的操作数返回truevar1 <= var2
var2 <= 5

null和undefined

null表示一个“空”的值,它和0以及空字符串''不同,0是一个数值,''表示长度为0的字符串,而null表示“空”。

undefined表示“未定义”,仅在判断函数参数是否传递的情况下有用

数组

数组是一组按顺序排列的集合,集合的每个值称为元素。

数组用[]表示,元素之间用,分隔。

var arr=[1,2,'a','b',null]

另一种创建数组的方法是通过Array()函数实现

new Array(1, 2, 3); // 创建了数组[1, 2, 3]

通过索引来访问数组元素:

var arr=[1,2,'a','b',null]
console.log(arr[0]); // 返回索引为0的元素,即1
console.log(arr[1]); // 返回索引为1的元素,即2
console.log(arr[5]); // 索引超出了范围,返回undefined

获取数组长度

length属性可获取数组长度:

var arr=[1,2,3,4,5,6];
console.log(arr.length);

更改数组长度

var arr=[1,2,3,4,5,6];
arr[2]=10;
console.log(arr);
//赋值时索引超过范围,会引起数组大小的变化,返回[1, 2, 10, 4, 5, 6, empty × 2, 8],数组长度为9
arr[8]=8;
console.log(arr);
//直接更改数值长度大小也会返回empty × n,数组长度为更改值
arr.length=11;
console.log(arr);

搜索指定元素位置

通过indexOf()来搜索一个指定的元素的位置

var arr=[1,2,3,4,5,6];
console.log(arr.indexOf(1)); //返回索引1
console.log(arr.indexOf(55)); //找不到元素返回-1

截取元素

通过slice()截取元素,索引从0开始,起止参数包括开始索引,不包括结束索引。

var arr=[1,2,3,4,5,6];
console.log(arr.slice(0,4)); //返回[1,2,3,4]
console.log(arr.slice(3)); //返回[4,5,6]

添加删除元素

push()向数组的末尾添加若干元素,pop()则把数组的最后一个元素删除掉,unshift()往头部添加若干元素,shift()删除第一个元素

var arr=[1,2,3,4,5,6];
arr.pop();
console.log(arr); //返回[1, 2, 3, 4, 5],数组长度是5
arr.push(88,99);
console.log(arr); //返回[1, 2, 3, 4, 5, 88, 99],数组长度是7
arr.unshift(55);
console.log(arr); //返回[55, 1, 2, 3, 4, 5, 88, 99],数组长度是8
arr.shift();
console.log(arr); //返回[1, 2, 3, 4, 5, 88, 99],数组长度是7

数组排序

sort()可以对当前数组进行排序

var arr=[1,5,7,4,8,9,3,6,2];
arr.sort()
console.log(arr); //返回[1, 2, 3, 4, 5, 6, 7, 8, 9]

反转数组

reverse()把整个数组反转

var arr=[1,2,3,4,5];
console.log(arr.reverse()); //返回[5, 4, 3, 2, 1]

修改数组

splice()可以修改数组,参数1是开始索引,参数2是删除单位,参数3起是添加元素

var arr=[1,2,3,4,5];
arr.splice(1,2,'A','B') //删除从索引1开始的两个单位,并增加元素,返回[1, 'A', 'B', 4, 5]
console.log(arr);
arr.splice(0,1); //删除从索引0开始的一个单位,返回['A', 'B', 4, 5]
console.log(arr);
arr.splice(2,0,5,6); //不删除,从索引2开始增加元素,返回['A', 'B', 5, 6, 4, 5]
console.log(arr);

连接数组

concact()可连接数组

var arr=[1,2,3,4,5];
var arr2=arr.concat([1,2,3]);
console.log(arr); //返回[1, 2, 3, 4, 5]
console.log(arr2); //返回[1, 2, 3, 4, 5, 1, 2, 3]

指定符号连接元素

join()把每个元素都用指定的字符串连接起来,然后返回连接后的字符串

var arr=[1,2,3,4,5];
console.log(arr.join('-')); //返回1-2-3-4-5

多维数组

如果数组的某个元素又是一个数组,则可以形成多维数组

var arr=[[1,2,3],['a','b','c'],'A','B','C'];
console.log(arr); //返回[Array(3), Array(3), 'A', 'B', 'C']
console.log(arr[1][0]); //返回a

对象

对象是一组由键-值组成的无序的集合数据类型。对象的键都是字符串类型,值可以是任意数据类型。如果属性名包含特殊字符,就必须用''括起来。

var master = {
    id: 5,
    host: 'wakamizu',
    user: ['tom','jerry'],
    alived: true,
    password: null
};

通过对象变量.属性名或者对象变量[属性名]访问对象属性

console.log(master.id); //返回5
console.log(master['host']); //返回wakamizu

添加/删除对象属性

master.zone='ext'; //新增zone属性
console.log(master); 
delete master.password; //删除password属性
console.log(master);

判断是否包含属性

in操作符可判断属性是否存在(来源于自身或者继承),hasOwnProperty()方法可判断属性是否仅来源于自身

console.log('id' in master);
console.log(master.hasOwnProperty('id'));

条件判断

使用if () { ... } else { ... }来进行条件判断。

var age = 18;
if (age >= 18) { // 如果age>= 18为true,则执行if语句块
    alert('成年');
} else { // 否则执行else语句块
    alert('未成年');
}

使用if () { ... } else if() {...} else {...}来进行多行条件判断

var age = 13;
if (age >= 18) {
    alert('成年');
} else if (age >= 14) {
    alert('少年');
} else {
    alert('小孩');
}

循环

for循环

通过初始条件、结束条件和递增条件来循环执行语句块

var i,x=0;
for (i=1;i<=10;i++){
	x+=i;
}
console.log(x)

for循环最常用的地方是利用索引来遍历数组

var arr = [1,2,3];
var i, x;
for (i=0; i<arr.length; i++) {
    x = arr[i];
    console.log(x);
}

for ... in循环

for ... in循环是for循环的变体,它可以把一个对象的所有属性依次循环出来

var master = {
    id: 5,
    host: 'wakamizu',
    user: ['tom','jerry'],
    alived: true,
    password: null
};

for (var key in master) {
	console.log(key); //列出对象属性
        console.log(master[key]);   //列出对象属性值
}

while循环

while循环只有一个判断条件,条件满足,就不断循环,条件不满足时则退出循环。

var i=0,n=10;
while (n > 0) {
    i+=n;
    n-=1;
}
console.log(i);

在循环内部变量n不断自减,直到变为-1时,不再满足while条件,循环退出。

do ... while循环

它和while循环的唯一区别在于,不是在每次循环开始的时候判断条件,而是在每次循环完成的时候判断条件

var i=0,n=10;
do {
    i+=n;
    n-=1;
} while (n > 0) 
console.log(i);

Map

Map是一组键值对的结构,具有极快的查找速度

var m = new Map([['wakamizu',100]],); //新建一个Map
m.set('tom',60); //添加key-value
m.set('jerry',80);
console.log(m.has('tom'));  //查看是否存在key'tom'
console.log(m.get('wakamizu'));  //获取key'wakamizu'的value
m.delete('jerry');  //删除key'jerry'
console.log(m.get('jerry'));  //返回undefined

Set

Set和Map类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在Set中,没有重复的key。

var s=new Set([1,2,3,3,3,4,4]); //创建set
console.log(s); //返回{1, 2, 3, 4}

add(key)方法可以添加元素到Set中

s.add('wakamizu');
console.log(s);

delete(key)方法可以删除元素

s.delete('wakamizu');
console.log(s);

迭代( iterable )

遍历Array可以采用下标循环,遍历Map和Set就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable类型,Array、Map和Set都属于iterable类型。

具有iterable类型的集合可以通过新的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
    console.log(x);
}
for (var x of s) { // 遍历Set
    console.log(x);
}
for (var x of m) { // 遍历Map
    console.log(x[0] + '=' + x[1]);
}

for ... of循环和for ... in循环有何区别?
for ... in循环由于历史遗留问题,它遍历的实际上是对象的属性名称。一个Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性。
for ... of循环则完全修复了这些问题,它只循环集合本身的元素。

var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x in a) {
    console.log(x); // 返回属性名'0', '1', '2', 'name'
}
for (var x of a) {
    console.log(x); // 返回元素'A', 'B', 'C'
}

更好的方式是直接使用iterable内置的forEach方法,它接收一个函数,每次迭代就自动回调该函数。

//Array
'use strict';
var a = ['A', 'B', 'C'];
a.forEach(function (element, index, array) {
    // element: 指向当前元素的值
    // index: 指向当前索引
    // array: 指向Array对象本身
    console.log(element + ', index = ' + index);
});

/*返回
A, index = 0
B, index = 1
C, index = 2
*/


//set
var s = new Set(['A', 'B', 'C']);
s.forEach(function (element, sameElement, set) {
    console.log(element);
});



//Map
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
    console.log(value);
});