HTML是一种标记语言,用来结构化我们的网页内容并赋予内容含义,例如定义段落、标题和数据表,或在页面中嵌入图片和视频。

CSS 是一种样式规则语言,可将样式应用于 HTML 内容, 例如设置背景颜色和字体,在多个列中布局内容。

JavaScript 是一种脚本语言,可以用来创建动态更新的内容,控制多媒体,制作图像动画,等等。

Chapte 1. 基础语法

1.1 概述

JavaScript 是轻量级解释型语言。它是可插入 HTML 页面的编程代码,每一个浏览器都有 JavaScript 的解析引擎,故 JavaScript 不需要编译,直接就能被浏览器解析执行了(即,它是运行在浏览器中的解释型的编程语言,“编译过程发生在代码运行中,而非之前”)。

关于 解释(interpret) 与 编译(compile):

解释型语言中,代码自上而下运行,且实时返回运行结果。代码在由浏览器执行前,无需将其转化为其他形式,代码直接以 文本格式 被接收和处理。

对于编译型语言,需将其代码转化(编译)成另一种形式才能运行。比如 C/C++ 先被编译成汇编语言,然后才能由计算机运行。程序将以二进制格式(由程序源代码产生的)运行。

JavaScript 是客户端脚本语言,客户端代码是在用户的电脑上运行的代码,在浏览一个网页时,它的客户端代码就会被下载,然后由浏览器来运行并展示。

当然,流行的服务器端 web 语言也包括了 JavaScript,本文着重讨论客户端 JavaScript

JavaScript 支持面向对象程序设计,命令式编程,以及函数式编程。它提供语法来操控文本、数组、日期以及正则表达式等,不支持 I/O,比如网络、存储和图形等,但这些都可以由它的宿主环境提供支持。

关于 动态代码 与 静态代码:

“动态” 是指是指通过按需生成新内容来更新 web 页面 / 应用,使得不同环境下显示不同内容。“动态” 既适用于描述服务器端语言,在服务器上动态生成新内容,(比如从数据库中提取信息) ;也适用于 客户端 JavaScript,在用户端浏览器中动态生成新内容(比如说创建一个新的 HTML 表格,用从服务器请求到的数据填充,然后在网页中向用户展示这个表格)。

**“静态”**页面是指没有动态更新内容的页面。

JavaScript常用来完成以下任务:

  • 嵌入动态文本于HTML页面,为HTML页面添加交互行为
  • 对浏览器事件作出响应
  • 读写HTML元素
  • 在数据被提交到服务器之前验证数据
  • 检测访客的浏览器信息
  • 控制cookie,包括创建和修改等

目前,它已经由ECMA(欧洲电脑制造商协会)通过ECMAScript实现语言的标准化。

1.2 与 HTML 结合的方式

  • 内部嵌入 JS 代码:定义 <script>,标签体内容即是 JS 代码

  • 外部嵌入 JS 代码:定义 <script>,通过其 src 属性来引入外部的 js 文件。

注意:<script>,可以定义多个,同时能够定义在 html 页面的“任何地方”,但定义的位置会对执行顺序有所影响。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
document.write("Hello, World!");
</script>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>

<script>
document.write("Hello, World!");
</script>

<script src = "js/demo01.js"></script>
</head>
<body>
<script>
document.write("Hello, World!");
</script>

</body>
</html>

JS 的注释与 C/C++、Java 相同,// 单行注释、/* */ 多行注释。

1.3 变量与数据类型

变量仅仅是一个用于存储数值的容器(不是数值本身),它能够存储任何东西,包括字符串和数字,甚至是函数。

1.3.1 变量声明与初始化

使用 varlet 关键词来声明变量:

1
2
var myName;
let myAge;

变量的声明可以不使用关键字,此时声明的变量是全局变量;关于 letvar 的作用域规则,参见:https://www.runoob.com/js/js-variables.html

如果已经被声明(即已经存在),那么重复声明(即除了变量的非首次声明)会被跳过,不再执行声明的操作。

上面两个变量声明后,没有数值,是个空的容器( undefined),若需要为变量赋值进行初始化,使用等号 =

1
2
myName = 'JoyDee';
myAge = 37;

或者,可以像下面这样在声明变量的同时给其初始化:

1
2
let myName = 'JoyDee';
var myAge = 37;

1.3.2 数据类型

编程语言的类型系统分为强类型(strongly typed)和弱类型(weakly typed)两种,目前没有明确的定义,但主要用以描述编程语言对于混入不同资料类型的值进行运算时的处理方式。

JavaScript 是弱类型的,这意味着无需指定变量将包含什么数据类型,同时,变量可以被隐式地转换为另一个类型。

JavaScript 数据类型分两种:

  • 基本数据类型:

    • number:数字,包括:整数、小数、NaN(not a number
    • string:字符串,例如 "abc""a"'abc'
    • boolean:取值仅有 truefalse
    • null:主动释放一个变量引用的对象,表示一个变量不再指向任何对象地址。
    • undefined:未定义,若一个变量没有给初始化值,则会被默认赋值为 undefined

    不同于 Java,JS 开辟变量存储空间时,并不会定义该空间将来要存储的数据类型,故更新变量值时,其数据类型是不限定的。

  • 引用数据类型:对象

    • Function
    • Array
    • Boolean
    • Date
    • Math
    • Number
    • String
    • RegExp:正则表达式对象
    • Global:全局对象

    在下面的章节会重点讨论这些对象是如何创建、使用。

使用举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
var a = 23333;
var b = NaN;
var c = false;
var obj = null;
var obj2 = undefined;
var obj3;
document.write(a + "<br>"); //23333
document.write(b + "<br>"); //NaN
document.write(c + "<br>"); //false
document.write(obj + "<br>"); //null
document.write(obj2 + "<br>"); //undefined
document.write(obj3 + "<br>"); //undefined
var num1 = 1, num2 = 3, num3 = 4;
document.write(num1 / num2 + "<br>" + num3 % num2 + "<br>"); //1
var res = "122" < 123;
document.write(res + "<br>"); //true
</script>
</head>
<body>
</body>
</html>

typeof 这一特殊的操作符,会返回所传递给它的变量的数据类型。如:

1
2
3
4
let myNumber = 'aaa'; 
typeof myNumber; // oops, this is a string
myNumber = 500;
typeof myNumber; // much better — now this is a number

注意,nulltypeof 运算后得到的返回结果为 object

1
2
var tt = null;
document.write(typeof (tt)); //object

1.4 运算符

1.4.1 一元运算符

++–-:自增/自减

+-:正负号

注意,在 JS 中,若运算数不是运算符所要求的类型,那么 JS 引擎会自动地将运算数进行类型转换。

其他类型自动转 number

  • string —> number:按照字面值转换,若字面值不是数字,则转为 NaN,如:

    1
    2
    var b = + "abc123"; //b 则转换为数字类型的 NaN
    var c = + "123"; //b 转换为(数字类型的)整数
  • boolean—>numbertrue 转为 1,false 转为 0

附:其他类型转 boolean

  • number—>boolean:0 或 NaN 为假,其他为真(区别于 Java)
  • string—>boolean:除了空字符串(""),其他均为 true
  • nullundefined 均为 false
  • 所有对象均为 true

1.4.2 算术运算符、赋值运算符(略)

1.4.3 比较运算符

><>=<======(全等于)

  • 类型相同:直接比较

    字符串间是以字典序进行比较。

  • 类型不同:先进行类型转换,再比较。如:

    1
    var res = "122" < 123; // res 值为 true

    对于 ===,是先判断类型是否一致,若不一致,则返回为 false。再者,判断数值。

1.4.4 逻辑运算符

&&||!

1.4.6 三元运算符

1
2
var a = 3, b = 4;
var c = a > b ? "a was bigger" : "b was bigger";

1.5 流程控制语句

if...else...whiledo..whilefor 等 与 Java 类似

但是,对于 switch 语句:

  • 在 Java 中,switch 语句只可接受的数据类型:byteintshortchar、枚举(Java 1.5)、String(Java 1.7)

    1
    2
    3
    4
    5
    switch(变量):
    case1:
    ...
    case2:
    ...
  • 在 JS 中,switch 语句可接受任意的原始数据类型。

案例:九九乘法表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>99乘法表</title>
<style>
td{
border: 1px solid;
}
</style>

<script>
document.write("<table align='center'>");

//1.完成基本的for循环嵌套,展示乘法表
for (var i = 1; i <= 9 ; i++) {
document.write("<tr>");
for (var j = 1; j <=i ; j++) {
document.write("<td>");
//输出 1 * 1 = 1
document.write(i + " * " + j
+ " = " + ( i*j)
+"&nbsp;&nbsp;&nbsp;");
document.write("</td>");
}
document.write("</tr>");
}

//2.完成表格嵌套
document.write("</table>");
</script>
</head>
<body>

</body>
</html>

1.6 基本对象

1.6.1 Function 函数(方法)对象

函数(方法)对象。

(一)创建方式:有两种:

1
2
3
function 方法名称(形式参数列表){
方法体
}
1
2
3
var 方法名 = function(形式参数列表){
方法体
}

(二)调用:

1
方法名称(实际参数列表);

(三)属性:

  • length:它记录 形式参数 的个数

(四)特点:

  1. 方法定义时,形参的类型、返回值类型均不用写(都是 var 变量)

  2. 方法是一个对象,若定义另一个名称相同的方法,会覆盖之前定义的方法。

  3. 在 JS 中,方法的调用 只与方法的名称有关,和参数列表无关

    1
    2
    3
    4
    5
    6
    7
    8
    function fun2(a, b){
    alert(a);
    }

    fun(3);
    fun(); //同样能够执行
    fun(1, 2);
    fun(1, 2, 3);
  4. 在方法声明中有一个隐藏的内置对象(数组)arguments,封装了所有的实际参数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /* 求任意个数的和 */
    function sum(){
    var res = 0;
    for(var i = 0; i < arguments.length; i++){
    res += arguments[i];
    }
    return res;
    }
    var a = add(1, 2, 3, 4, 5); //可以传任意多个参数

1.6.2 Array 数组对象

(一)创建方式:

1
2
3
var arr = new Array(元素列表); // 方式一
var arr = new Array(默认长度); // 方式二
var arr = [元素列表]; // 方式三

(二)属性:

  • length:数组的长度

(三)相关方法:

  • join(参数):将数组中的元素按照指定的分隔符拼接为字符串。

    1
    2
    3
    var arr = [1, "abc", true];
    document.write(arr.join() + "<br>"); //不传参数则默认用逗号分隔—— "1,abc,true"
    document.write(arr.join(--) + "<br>"); //字符串变为 "1--abc--true"
  • push():向数组的末尾添加一个或更多元素,并返回新的长度。

(四)特点:一个数组中的元素类型不限定,且长度是可变的。

1
2
3
4
var arr = [1, "abc", true];
arr[10] = "2333"
document.write(arr[10] + "<br>"); //输出 2333
document.write(arr[9] + "<br>"); //输出 undefined

1.6.3 Date 日期对象

(一)创建方式:

1
var mydate = new Date();

(二)方法:

  • toLocalString():返回当前 Date 对象对应的本地时间的字符串
  • getTime():获取毫秒值,返回当前日期对象描述的时间到 1970年1月1日零点的毫秒值之差

1.6.4 Math 数学对象

(一)创建方式:

Math 对象在使用这个对象之前对它进行定义,即可直接调用其方法。即:

1
Math.方法名();

(二)属性:

  • PI

(三)方法:

  • random():返回介于 0(包含) ~ 1(不包含) 之间的一个随机数
  • ceil():对传入的参数进行上舍入
  • floor():对传入的参数进行下舍入
  • round():对传入的参数进行四舍五入

1.6.5 RegExp 正则表达式对象

(零)正则表达式:定义字符串的组成规则

  1. 单个字符:[],例如:[a][ab][a-zA-Z0-9_]

    利用特殊符号代表的单个字符:

    • \d:单个数字字符,从 [0-9] 取值
    • \w:单个单词字符,[a-zA-Z0-9_]
  2. 量词符号:

    • ?:表示出现 0 次或 1 次
    • *:表示出现 0 次或 多次
    • +:表示出现 1 次或 多次
    • {m, n}:表示出现[m,n][m, n] 次数量,{, n} 代表最多 n 次,{m, n} 代表 最少 m 次;{x} 代表 当且仅当 x 次。
  3. 始末符号:

    • ^:开始,^n 匹配任何开头为 n 的字符串
    • $:结束,n$ 匹配任何结尾为 n 的字符串
  4. 修饰符:

    • i:执行对大小写不敏感的匹配
    • g:执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)
    • m:执行多行匹配

(二)正则对象的创建

1
2
var reg = new RegExp("正则表达式"); //方式一
var reg = /正则表达式/;

(三)正则对象的相关方法

  • test(待检验的字符串):验证指定的字符串是否符合正则表达式定义的规范

    1
    2
    3
    4
    var reg = /^w{6, 12}$/;
    var reg2 = new RegExp("^\\w{6, 12}$"); //字符串方式定义的话,要注意转义字符,为了让\w不带转义,需要用\\w
    var username = "Luffy";
    var flag = reg.test(username); //返回 true

    检验是否为中文名称组成:

    1
    2
    3
    4
    function ischina(str) {
    var reg=/^[\u4E00-\u9FA5]{2,4}$/; /*定义验证表达式*/
    return reg.test(str); /*进行验证*/
    }

1.6.6 Global 全局对象

Global 中封装的方法不需要创建对象,即能够直接调用。即直接 方法名()

(一)相关方法:

  • encodeURI():URL 编码,编码后,它输出符号的 UTF-8 (可能取决于网页的charset 属性)形式,并且在每个字节前加上 %

  • decodeURI():URL 解码

  • encodeURIComponent():URL 编码,但编码的字符更多,; / ? : @ & = + $ , #,这些在 encodeURI()中不被编码的符号,在该方法中会统统会被编码。

  • decodeURIComponent():URL 解码

    1
    2
    3
    4
    5
    var tmpstr = encodeURI("你是什么王来着?");
    var tmpstr2 = encodeURIComponent("你是什么王来着?");
    //输出为%E4%BD%A0%E6%98%AF%E4%BB%80%E4%B9%88%E7%8E%8B%E6%9D%A5%E7%9D%80?
    document.write(tmpstr + "<br>" + tmpstr2);
    //输出为%E4%BD%A0%E6%98%AF%E4%BB%80%E4%B9%88%E7%8E%8B%E6%9D%A5%E7%9D%80%3F
  • parseInt():将字符串转为数字。

    该方法调用的过程中,会逐一地判断每个字符是否为数字,直到不是数字为止,将前面的数字部分转为 number

  • isNaN():判断一个值 是否 为 NaN

    由于 NaN “六亲不认”,但凡用 NaN 与 其他值 进行== 比较都会返回 false

  • eval():传入字符串,并将该字符串作为 JS 代码来执行。

1.6.7 Number 对象、String 对象、Boolean 对象(略)