Javascript Basic
JavaScript 概述
JavaScript是世界上最流行的脚本语言,简称JS
,主要用来实现网页的交互逻辑,JavaScript是一种运行在浏览器中的解释型的编程语言。
JavaScript 版本
为了让JavaScript成为全球标准,几个公司联合ECMA(European Computer Manufacturers Association)组织定制了JavaScript语言的标准,被称为ECMAScript标准,最新版ECMAScript 6标准(简称ES6)在2015年6月正式发布。
JavaScript 入门
JS主要有两种使用方式,第一种是直接写在HTML文件里面(通常写在head
里面),使用<script>...</script>
声明JS代码;第二种则是将JS代码放到一个单独的.js
文件,在HTML中通过<script src="..."></script>
引入这个文件。
0
1
2
3
4
5
6
7
8
9
10
11
12
|
<html>
<head>
<!-- 第一种方式 -->
<script>
alert('Hello World!');
</script>
<!-- 第二种方式 -->
<script src="static/js/xxx.js"></script>
</head>
<body>
...
</body>
</html>
|
基本语法
- 语句以
;
结束(非强制,建议)
- 语句块使用
{...}
- 代码严格区分大小写
注释
注释分为行注释和块注释,如下:
0
1
2
3
4
|
// 这是行注释
/*
这是块注释
*/
|
数据类型和变量
Number
JavaScript不区分整数和浮点数,统一用Number
表示:
0
1
2
3
4
5
|
123; // 整数
0.456; // 浮点数
1.234e5; // 科学计数法
-99; // 负数
NaN; // Not a Number
Infinity; // 无限大
|
Number可以直接做四则运算:
0
1
2
3
4
5
|
1 + 2; // 3
(1 + 2) * 5 / 2; // 7.5
2 / 0; // Infinity
0 / 0; // NaN
10 % 3; // 1
10.5 % 3; // 1.5
|
字符串
字符串是以单引号'
或双引号"
括起来的任意文本,比如'abc'
,"xyz"
等等,''
或""
本身只是一种表示方式,不是字符串的一部分。
布尔值
布尔值和布尔代数的表示完全一致,一个布尔值只有true
、false
两种值。
逻辑运算符
&&
运算是与运算,只有所有都为true
,&&
运算结果才是true
:
0
1
2
|
true && true; // true
true && false; // false
false && false; // false
|
||
运算是或运算,只要其中有一个为true
,||
运算结果就是true
:
0
1
2
|
true || true; // true
true || false; // true
false || false; // false
|
!
运算是非运算,它是一个单目运算符,把true
变成false
,false
变成true
:
0
1
|
! true; // false
! false; // true
|
比较运算符
JavaScript有许多比较运算符:>
、>=
、<
、<=
、==
、===
,可以通过比较运算符返回一个布尔值:
0
1
2
|
2 > 5; // false
5 >= 2; // true
7 == 7; // true
|
JavaScript还允许对任意数据类型做比较:
0
1
|
false == 0; // true
false === 0; // false
|
特别注意:
- 相等运算符
==
和===
:不要使用==
比较,坚持使用===
比较
==
会自动转换数据类型再比较,会产生意想不到的结果
===
则不会自动转换数据类型,如果数据类型不一致,则返回false
,如果一致,再比较
NaN
:NaN
这个特殊的Number
与所有其他值都不相等,包括它自己:
0
1
|
isNaN(NaN); //true
Object.is(NaN, NaN); // true
|
null和undefined
null
:表示一个空的值
undefined
:表示一个未定义的值
数组
数组是一组按顺序排列的集合,集合的每个值称为元素。JavaScript的数组可以包括任意数据类型:
0
|
[1, 2, 3.14, 'Hello', null, true];
|
数组还可以通过Array()
函数创建:
0
|
new Array(1, 2, 3); // 创建数组:[1, 2, 3]
|
数组的元素可以通过索引来访问,起始索引为0
:
0
1
2
3
|
var arr = [1, 2, 3.14, 'Hello', null, true];
arr[0]; // 1
arr[5]; // true
arr[6]; // undefined
|
对象
JavaScript的对象是一组由键-值组成的无序集合,例如:
0
1
2
3
4
5
6
7
|
var person = {
name: 'Bob',
age: 20,
tags: ['js', 'web', 'mobile'],
city: 'Beijing',
hasCar: true,
zipcode: null
};
|
JavaScript对象的键都是字符串类型,值可以是任意数据类型。
获取一个对象的属性,可以使用object.prop
的方式:
0
1
|
person.name; // 'Bob'
person.zipcode; // null
|
变量
变量是用于存储和表示数据值的一种命名存储单元。变量可以在程序执行过程中改变其值,因此称为变量。
变量在JavaScript中就是用一个变量名表示,变量名是大小写英文、数字、$
和_
的组合,且不能用数字开头。变量名也不能是JavaScript的关键字。申明一个变量用var
语句,比如:
0
1
2
3
4
|
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
|
使用等号=
对变量进行赋值。可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量,但只能用var
申明一次,例如:
0
1
|
var a = 123; // a的值是整数123
a = 'ABC'; // a变为字符串
|
字符串
JavaScript的字符串就是用''
或""
括起来的字符表示。
多行字符串
ES6标准新增了一种多行字符串的表示方法,用反引号表示:
模版字符串
要把多个字符串连接起来,可以用+
号连接:
0
1
2
|
var name = '小明';
var age = 20;
var message = '你好, ' + name + ', 你今年' + age + '岁了!';
|
ES6新增一种模板字符串,它会自动替换字符串中的变量:
0
1
2
|
var name = '小明';
var age = 20;
var message = `你好, ${name}, 你今年${age}岁了!`;
|
操作字符串
下面列举针对字符串s
的一些常用操作:
0
|
var s = 'Hello World!';
|
获取字符串长度:
获取字符串某个指定位置的字符:
0
1
2
3
|
s[0]; // 'H'
s[5]; // ' '
s[6]; // 'W'
s[12]; // undefined
|
特别注意:字符串是不可变的,如果对字符串的某个索引赋值,不会报错,也没有任何效果:
0
1
|
s[0] = 'X';
console.log(s); // 'Hello World!'
|
把一个字符串全部变为大写/小写:
0
1
2
3
4
|
// 全部变为大写
s.toUpperCase(); // 'HELLO WORLD!'
// 全部变为小写
s.toLowerCase(); // 'hello world!'
|
搜索指定字符串出现的位置:
0
1
|
s.indexOf('World'); // 6
s.indexOf('world'); // -1
|
返回指定索引区间的子串:
0
1
|
s.substring(0, 5); // 'Hello'
s.substring(6); // 'World!'
|
数组
JavaScript的Array
可以包含任意数据类型,并通过索引来访问每个元素。
获取数组的长度:
0
1
|
var arr = [1, 2, 3.14, 'Hello', null, true];
arr.length; // 6
|
给Array
的length
赋一个新的值会导致Array
大小的变化:
0
1
2
3
4
5
|
var arr = [1, 2, 3];
arr.length; // 3
arr.length = 6;
arr; // [1, 2, 3, undefined, undefined, undefined]
arr.length = 2;
arr; // [1, 2]
|
Array
可以通过索引把对应的元素修改为新的值,对Array
的索引进行赋值会直接修改这个Array
:
0
1
2
|
var arr = ['A', 'B', 'C'];
arr[1] = 99;
arr; // ['A', 99, 'C']
|
若通过索引赋值时,索引超过了范围,同样会引起Array
大小的变化:
0
1
2
|
var arr = [1, 2, 3];
arr[5] = 'x';
arr; // [1, 2, 3, undefined, undefined, 'x']
|
indexOf
Array
可以通过indexOf()
来搜索一个指定的元素的位置:
0
1
2
3
4
|
var arr = [10, 20, '30', 'xyz'];
arr.indexOf(10); // 0
arr.indexOf(20); // 1
arr.indexOf(30); // -1
arr.indexOf('30'); // 2
|
slice
slice()
截取Array
的部分元素,然后返回一个新的Array
:
0
1
2
|
var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
arr.slice(0, 3); // ['A', 'B', 'C']
arr.slice(3); // ['D', 'E', 'F', 'G']
|
若slice()
没有传递任何参数,它会截取所有元素,相当于复制一个Array
:
0
1
2
3
|
var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
var aCopy = arr.slice();
aCopy; // ['A', 'B', 'C', 'D', 'E', 'F', 'G']
aCopy === arr; // false
|
push和pop
push()
:向Array
的末尾添加若干元素
pop()
:删除Array
的最后一个元素
0
1
2
3
4
5
6
7
8
9
10
|
var arr = [1, 2];
arr.push('A', 'B'); // 4
arr; // [1, 2, 'A', 'B']
arr.pop(); // 'B'
arr; // [1, 2, 'A']
arr.pop();
arr.pop();
arr.pop();
arr; // []
arr.pop(); // undefined
arr; // []
|
unshift和shift
unshift()
:向Array
的头部添加若干元素
shift()
:删除Array
的第一个元素
0
1
2
3
4
5
6
7
8
9
10
|
var arr = [1, 2];
arr.unshift('A', 'B'); // 4
arr; // ['A', 'B', 1, 2]
arr.shift(); // 'A'
arr; // ['B', 1, 2]
arr.shift();
arr.shift();
arr.shift();
arr; // []
arr.shift(); // undefined
arr; // []
|
sort
sort()
可以对当前Array
按照默认顺序进行排序,直接修改当前Array
的元素位置:
0
1
2
|
var arr = ['B', 'C', 'A'];
arr.sort();
arr; // ['A', 'B', 'C']
|
reverse
reverse()
可以将Array
反转:
0
1
2
|
var arr = ['one', 'two', 'three'];
arr.reverse();
arr; // ['three', 'two', 'one']
|
splice
splice()
方法可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素:
0
1
2
3
4
5
6
|
var arr = ['A', 'B', 'C', 'D', 'E', 'F'];
arr.splice(2, 3, 'X', 'Y'); // ['C', 'D', 'E']
arr; // ['A', 'B', 'X', 'Y', 'F']
arr.splice(2, 2); // ['X', 'Y']
arr; // ['A', 'B', 'F']
arr.splice(2, 0, 'X', 'Y'); // []
arr; // ['A', 'B', 'X', 'Y', 'F']
|
concat
concat()
方法用于拼接Array
,并返回一个新的Array
:
0
1
2
3
|
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
里:
0
1
|
var arr = ['A', 'B', 'C'];
arr.concat(1, 2, [3, 4]); // ['A', 'B', 'C', 1, 2, 3, 4]
|
join
join()
方法将当前Array
的每个元素用指定的字符串连接起来,返回连接后的字符串:
0
1
|
var arr = ['A', 'B', 'C', 1, 2, 3];
arr.join('-'); // 'A-B-C-1-2-3'
|
若Array
的元素不是字符串,将自动转换为字符串后再连接。
多维数组
若数组的某个元素是Array
,则可以形成多维数组:
0
|
var arr = [[1, 2, 3], [400, 500, 600], '-'];
|
对象
JavaScript的对象是一种无序的集合数据类型,它由若干键值对组成。
0
1
2
3
4
5
6
7
|
var xiaoming = {
name: '小明',
birth: 1990,
school: 'No.1 Middle School',
height: 1.70,
weight: 65,
score: null
};
|
JavaScript用一个{...}
表示一个对象,键值对以xxx: xxx
形式申明,用,
隔开。
访问属性是通过.
操作符完成的,要求属性名必须是一个有效的变量名。如果属性名包含特殊字符,就必须用''
括起来:
0
1
2
3
4
5
6
|
xiaoming.name; // '小明'
xiaoming.birth; // 1990
var xiaohong = {
name: '小红',
'middle-school': 'No.1 Middle School.'
}
|
非有效变量的属性无法使用.
操作符,必须用['xxx']
来访问:
0
1
2
|
xiaohong['middle-school']; // 'No.1 Middle School'
xiaohong['name']; // '小红'
xiaohong.name; // '小红'
|
访问对象中不存在的属性返回undefined
:
0
1
2
3
4
|
var xiaoming = {
name: '小明'
};
xiaoming.age; // undefined
|
JavaScript的对象是动态类型,可以自由地增删属性:
0
1
2
3
4
5
6
7
8
9
10
|
var xiaoming = {
name: '小明'
};
xiaoming.age; // undefined
xiaoming.age = 18;
xiaoming.age; // 18
delete xiaoming.age;
xiaoming.age; // undefined
delete xiaoming['name'];
xiaoming.name; // undefined
delete xiaoming.school;
|
删除对象中不存在的属性不会报错。
判断对象是否拥有某个熟悉可以使用in
操作符:
0
1
2
3
4
5
6
7
8
9
|
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
判断一个属性存在,这个属性不一定是该对象的,它可能是继承得到的;判断一个属性是否是对象自身拥有的,而不是继承得到的,可以用hasOwnProperty()
方法:
0
1
2
3
4
5
6
|
var xiaoming = {
name: '小明'
};
'toString' in xiaoming; // true
xiaoming.hasOwnProperty('name'); // true
xiaoming.hasOwnProperty('toString'); // false
|
条件判断
JavaScript使用if () { ... } else { ... }
来进行条件判断,其中else
语句是可选的,若语句块只包含一条语句,则可以省略{}
:
0
1
2
3
4
5
|
var age = 20;
if (age >= 18) {
alert('adult');
} else {
alert('teenager');
}
|
多行条件判断
如果有多个判断条件,则可以使用多个if...else...
的组合:
0
1
2
3
4
5
6
7
|
var age = 3;
if (age >= 18) {
alert('adult');
} else if (age >= 6) {
alert('teenager');
} else {
alert('kid');
}
|
PS:if...else...
语句的执行特点是二选一,在多个if...else...
语句中,如果某个条件成立,则后续就不再继续判断了。
循环
JavaScript的循环有总体分为两种,for
循环和while
循环。
for
通过初始条件、结束条件和递增条件来循环执行语句块:
0
1
2
3
4
5
|
var x = 0;
var i;
for (i = 1; i <= 10000; i ++) {
x = x + i;
}
x; // 50005000
|
i=1
这是初始条件,将变量i
置为1
;
i<=10000
这是判断条件,满足时就继续循环,不满足就退出循环;
i++
这是每次循环后的递增条件,由于每次循环后变量i都会加1
,因此它终将在若干次循环后不满足判断条件i<=10000
而退出循环。
PS:for
循环的3个条件都是可以省略的,如果没有退出循环的判断条件,就必须使用break
语句退出循环,否则就是死循环:
0
1
2
3
4
5
6
|
var x = 0;
for (;;) { // 无限循环
if (x > 100) {
break; // 通过break退出循环
}
x ++;
}
|
for ... in
for ... in
循环可以把一个对象的所有属性依次循环出来:
0
1
2
3
4
5
6
7
|
var o = {
name: 'Jack',
age: 20,
city: 'Beijing'
};
for (var key in o) {
console.log(key); // 'name', 'age', 'city'
}
|
Array
也是对象,Array
索引被视为对象的属性,for ... in
循环可以得到Array
的索引:
0
1
2
3
4
|
var a = ['A', 'B', 'C'];
for (var i in a) {
console.log(i); // '0', '1', '2'
console.log(a[i]); // 'A', 'B', 'C'
}
|
PS:for ... in
对Array
的循环得到的是String
而不是Number
while
while
循环只有一个判断条件,在不满足条件时退出循环:
0
1
2
3
4
5
6
|
var x = 0;
var n = 99;
while (n > 0) {
x = x + n;
n = n - 2;
}
x; // 2500
|
do ... while
do { ... } while()
循环只有一个判断条件,在不满足条件时退出循环:
0
1
2
3
4
|
var n = 0;
do {
n = n + 1;
} while (n < 100);
n; // 100
|
PS:do { ... } while()
循环至少执行一次,for
循环和while
循环可能一次都不执行
Map和Set
JavaScript在ES6中引入了新的数据结构Map
和Set
Map
Map
是一组键值对的结构,具有极快的查找速度:
0
1
|
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95
|
Map
需要一个二维数组来初始化,也可以初始化一个空Map
;Map
具有以下方法:
0
1
2
3
4
5
|
var m = new Map(); // 空Map
m.set('Adam', 67); // 添加
m.has('Adam'); // 是否存在key:true
m.get('Adam'); // 67
m.delete('Adam'); // 删除key 'Adam'
m.get('Adam'); // undefined
|
当向同一个Map
多次添加同一个key
时,新值会覆盖旧值。
Set
Set
是一组key
的集合,不存储value
且key
不能重复。
Set
需要一个数组来初始化,也可以初始化一个空Set
:
0
1
|
var s1 = new Set(); // 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3
|
通过add(key)
方法向Set
中添加元素:
0
1
2
3
|
s.add(4);
s; // Set {1, 2, 3, 4}
s.add(4);
s; // Set {1, 2, 3, 4}
|
通过delete(key)
方法可以删除Set
中的元素:
0
1
2
3
|
var s = new Set([1, 2, 3]);
s; // Set {1, 2, 3}
s.delete(3);
s; // Set {1, 2}
|
iterable
为了统一集合类型,ES6引入了iterable
类型,Array
、Map
和Set
都属于iterable
类型。
for ... of
具有iterable
类型的集合可以通过新的for ... of
循环来遍历:
0
1
2
3
4
5
6
7
8
9
10
11
|
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]);
}
|
PS:for ... of
循环和for ... in
循环的区别在于前者只遍历集合的元素,而后者遍历集合的属性。
iterable.forEach()
forEach()
方法是iterable
集合的遍历方法,它的入参是一个函数,每次迭代自动回调该函数:
0
1
2
3
4
5
6
|
var a = ['A', 'B', 'C'];
a.forEach(function (element, index, array) {
// element: 指向当前元素的值
// index: 指向当前索引
// array: 指向Array对象本身
console.log(element + ', index = ' + index);
});
|
Set
没有索引,因此回调函数的前两个参数都是元素本身:
0
1
2
3
|
var s = new Set(['A', 'B', 'C']);
s.forEach(function (element, sameElement, set) {
console.log(element);
});
|
Map
的回调函数参数依次为value
、key
和map
本身:
0
1
2
3
|
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
console.log(value);
});
|
JavaScript的函数调用不要求参数必须一致,可以忽略部分参数:
0
1
2
3
|
var a = ['A', 'B', 'C'];
a.forEach(function (element) {
console.log(element);
});
|
原文链接:JavaScript教程
这个系列的帖子
相关文章