第一章 JavaScript简介
1.1、JavaScript的起源
JavaScript诞生于1995年,它的出现主要是用于处理网页中的前端验证。所谓的前端验证,就是指检查用户输入的内容是否符合一定的规则。比如:用户名的长度,密码的长度,邮箱的格式等。但是,有的同学可能会有疑问,这些验证,后端不也可以进行验证吗?确实,后端程序的确可以进行这些验证,但你要清楚,在1995年那个年代,网速是非常慢的,向后端发送一个请求,浏览器很久才能得到响应,那这无疑是一种非常不好的用户体验。
为了解决前端验证的问题,当时的浏览器巨头NetScape(网景)公司就开发出一种脚本语言,起初命名为LiveScript,后来由于SUN公司的介入更名为了JavaScript。但是你要清楚,Java和JavaScript是没有什么关系的,只不过当时Java非常流行,为了蹭热度,才将LiveScript更名为JavaScript,它们的关系就像雷锋和雷峰塔的关系一样,没啥关系。
但是,浏览器开发商不止网景一家,还有一个大家都知道的公司,微软公司,它们的主打产品是IE(Internet Explorer)浏览器,当网景公司的Netscape Navigator浏览器推出JavaScript语言时,微软就急了啊,好家伙,人网景都推出了专门用于前端验证的语言,不仅大大减少了后端程序的压力,还提高了用户的体验。我微软这么大的公司不也得整一个,在1996年,微软公司在其最新的IE3浏览器中引入了自己对JavaScript的实现JScript。
于是在市面上存在两个版本的JavaScript,一个网景公司的JavaScript和微软的JScript,虽然当时浏览器的巨头是网景,但是网景的浏览器是收费的,虽然微软的IE浏览器在全球的市场份额远远不及网景,但是微软的拳头产品是Windows操作系统,每一个操作系统都自带一个IE浏览器并且免费,那么,未来的发展大家可能也想到了,网景让微软给干倒闭了,1998年11月,网景被美国在线(AOL)收购。
老大哥就是老大哥,为了抢先获得规则制定权,网景最先将JavaScript作为草案提交给欧洲计算机制造商协会,也就是ECMA组织,希望能将JavaScript做成行业标准,最终在网景、SUN以及微软等公司的参与下,由一众程序员和相关组织人员组成的第39技术委员会也就是TC39发布了ECMA-262标准,这个标准定义了名为ECMAScript的全新脚本语言,为啥又来了个ECMAScript?
因为Java是SUN的商标,SUN授权了NetScape可以叫JavaScript,但是ECMA没有SUN的授权就不能叫JavaScript,哪怕NetScape成员特别希望ECMA把它叫做JavaScript,但是ECMA也有成员并不希望这个标准就叫JavaScript,总之经过几轮磋商和博弈,ECMAScript这个名字就定下来。
我们可以简单看一下历史事件发展表:
1.2、JavaScript的组成
ECMAScript是一个标准,而这个标准需要由各个厂商去实现,不同的浏览器厂商对该标准会有不同的实现。
我们已经知道ECMAScript是JavaScript标准,所以一般情况下这两个词我们认为是一个意思。但是实际上JavaScript的含义却要更大一些。一个完整的JavaScript实现应该由以下三个部分构成:
由此我们也知道了我们所要学习的内容就是这三部分,它们具体的含义后边章节会具体介绍。
1.3、JavaScript的特点
解释型语言
JavaScript是一门解释型语言,所谓解释型值语言是指不需要被编译为机器码在执行,而是直接执行。由于少了编译这一步骤,所以解释型语言开发起来尤为轻松,但是解释型语言运行较慢也是它的劣势。不过解释型语言中使用了JIT技术,使得运行速度得以改善。
动态语言
JavaScript是一门动态语言,所谓的动态语言可以暂时理解为在语言中的一切内容都是不确定的。比如一个变量,这一时刻是个整型,下一时刻可能会变成字符串了。当然这个问题我们以后再谈。不过在补充一句动态语言相比静态语言性能上要差一些,不过由于JavaScript中应用的JIT技术,所以JavaScript可能是运行速度最快的动态语言了。
类似于 C 和 Java 的语法结构
JavaScript的语法结构与C和Java很像,向for、if、while等语句和Java的基本上是一模一样的。所以有过C和Java基础的同学学习起来会轻松很多。不过JavaScript和与Java的关系也仅仅是看起来像而已。
基于原型的面向对象
JavaScript是一门面向对象的语言。啥是对象?下次聊。
Java也是一门面向对象的语言,但是与Java不同JavaScript是基于原型的面向对象。啥是原型?下次聊。
严格区分大小写
JavaScript是严格区分大小写的,也就是abc和Abc会被解析器认为是两个不同的东西。
1.4、JavaScript的使用
1.4.1、标签引用
在HTML中在
<script> alert("Hello,World!"); </script>
1.4.2、文件引用
在一个单独的js文件中也可以编写JavaScript代码,然后在HTML文件中使用script标签进行引用,以下是一个简单演示。
main.html
<script src="main.js"></script>
main.js
alert("Hello,World!");
1.5、JavaScript的输出
1.5.1、页面输出
如何使用JavaScript向页面输出一句话,请参考以下代码。
<script> document.write("Hello,World!"); </script>
1.5.2、控制台输出
如何使用JavaScript向控制台输出一句话,请参考以下代码。
注意:页面按F12弹出控制台
<script> console.log("输出一条日志");//最常用 console.info("输出一条信息"); console.warn("输出一条警告"); console.error("输出一条错误"); </script>
1.5.3、弹出窗口输出
如何使用JavaScript向弹出窗口输出一句话,请参考以下代码。
<script> alert("Hello,World!"); </script>
1.6、JavaScript的注释
注释中的内容不会被解析器解析执行,但是会在源码中显示,我们一般会使用注释对程序中的内容进行解释。
JS中的注释和Java的的一致,分为两种:
- 单行注释:// 注释内容
- 多行注释:/* /* 注释内容 */
1.6.1、单行注释
<script> // 这是注释内容 console.log("Hello,World!"); </script>
1.6.2、多行注释
<script> /** * 这是注释内容 */ console.log("Hello,World!"); </script>
第二章 JavaScript基础语法
2.1、标识符
所谓标识符,就是指给变量、函数、属性或函数的参数起名字。
标识符可以是按照下列格式规则组合起来的一或多个字符:
- 第一个字符必须是一个字母、下划线( _ )或一个美元符号( $ )。
- 其它字符可以是字母、下划线、美元符号或数字。
- 按照惯例,ECMAScript 标识符采用驼峰命名法。
- 标识符不能是关键字和保留字符。
关键字:
保留字符:
其它不建议使用的标识符:
单个单词的标识符举例:
name、age、gender、hobby
多个单词的标识符举例:
studentName、studentAge、studentGender、studentHobby
2.2、字面量和变量
2.2.1、字面量
字面量实际上就是一些固定的值,比如:1、2 、3、true、false、null、NaN、“hello”,字面量都是不可以改变的,由于字面量不是很方便使用,所以在JavaScript中很少直接使用字面量,使用的而是变量。
2.2.2、变量
变量的作用是给某一个值或对象标注名称。比如我们的程序中有一个值123,这个值我们是需要反复使用的,这个时候 我们最好将123这个值赋值给一个变量,然后通过变量去使用123这个值。
变量的声明: 使用var关键字声明一个变量。
var a;
变量的赋值: 使用=为变量赋值。
a = 123;
声明和赋值同时进行:
var a = 123;
2.3、数据类型
2.3.1、类型分类
数据类型决定了一个数据的特征,比如:123和”123”,直观上看这两个数据都是123,但实际上前者是对于不同的数据类型我们在进行操作时会有很大的不同。
JavaScript中一共有5种基本数据类型:
字符串型(String)
数值型(Number)
布尔型(Boolean)
undefined型(Undefined)
null型(Null)
这5种之外的类型都称为Object,所以总的来看JavaScript中共有六种数据类型。
2.3.2、typeof运算符
使用typeof操作符可以用来检查一个变量的数据类型。
使用方式:
typeof 数据
示例代码:
console.log(typeof 123); console.log(typeof "Hello,World!"); console.log(typeof true); console.log(typeof undefined); console.log(typeof null);
运行结果:
2.3.3、String
String用于表示一个字符序列,即字符串。字符串需要使用 单引号 或 双引号 括起来。
转义字符:
注意:使用typeof运算符检查字符串时,会返回"string"。
2.3.4、Number
Number 类型用来表示整数和浮点数,最常用的功能就是用来表示10进制的整数和浮点数。
Number表示的数字大小是有限的,如果超过了这个范围,则会返回 ±Infinity。
最大值:+1.7976931348623157e+308
最小值:-1.7976931348623157e+308
0以上的最小值:5e-324
特殊的数字:
Infinity:正无穷
-Infinity:负无穷
NaN:非法数字(Not A Number)
其它的进制:
二进制:0b 开头表示二进制,但是,并不是所有的浏览器都支持
八进制:0 开头表示八进制
十六进制:0x 开头表示十六进制
注意:使用typeof检查一个Number类型的数据时(包括NaN 和 Infinity),会返回"number"。
2.3.5、Boolean
布尔型也被称为逻辑值类型或者真假值类型。
布尔型只能够取真(true)和假(false)两种数值。除此以外, 其它的值都不被支持。
2.3.6、Undefined
Undefined 类型只有一个值,即特殊的 undefined。
在使用 var 声明变量但未对其加以初始化时,这个变量的值就是 undefined。
注意:使用typeof对没有初始化和没有声明的变量,会返回“undefined”。
2.3.7、Null
Null 类型是第二个只有一个值的数据类型,这个特殊的值是 null。
undefined值实际上是由null值衍生出来的,所以如果比较undefined和null是否相等,会返回true。
注意:从语义上看null表示的是一个空的对象,所以使用typeof检查null会返回一个Object。
2.4、强制类型转换
强制类型转换指将一个数据类型强制转换为其它的数据类型。一般是指,将其它的数据类型转换为String、Number、Boolean。
2.4.1、转换为String类型
将其它数值转换为字符串有三种方式:toString()、String()、 拼串。
方式一:调用被转换数据类型的toString()方法,该方法不会影响到原变量,它会将转换的结果返回,但是注意:null和undefined这两个值没有toString()方法,如果调用它们的方法,会报错。
var a = 123; a = a.toString(); console.log(a); console.log(typeof a);
方式二:调用String()函数,并将被转换的数据作为参数传递给函数,使用String()函数做强制类型转换时,对于Number和Boolean实际上就是调用的toString()方法,但是对于null和undefined,就不会调用toString()方法,它会将 null 直接转换为 “null”,将 undefined 直接转换为 “undefined”。
var a = 123; a = String(a); console.log(a); console.log(typeof a); var b = undefined; b = String(b); console.log(b); console.log(typeof b); var c = null; c = String(c); console.log(c); console.log(typeof c);
方式三:为任意的数据类型 +""
var a = 123; a = a + ""; console.log(a); console.log(typeof a);
2.4.2、转换为Number类型
有三个函数可以把非数值转换为数值:Number()、parseInt() 和parseFloat()。Number()可以用来转换任意类型的数据,而后两者只能用于转换字符串。parseInt()只会将字符串转换为整数,而parseFloat()可以将字符串转换为浮点数。
方式一:使用Number()函数
字符串 --> 数字
如果是纯数字的字符串,则直接将其转换为数字
如果字符串中有非数字的内容,则转换为NaN
如果字符串是一个空串或者是一个全是空格的字符串,则转换为0
布尔 --> 数字
true 转成 1
false 转成 0
null --> 数字
null 转成 0
undefined --> 数字
undefined 转成 NaN
方式二:这种方式专门用来对付字符串,parseInt() 把一个字符串转换为一个整数
var a = "123"; a = parseInt(a); console.log(a); console.log(typeof a);
方式三:这种方式专门用来对付字符串,parseFloat() 把一个字符串转换为一个浮点数
var a = "123.456"; a = parseFloat(a); console.log(a); console.log(typeof a);
注意:如果对非String使用parseInt()或parseFloat(),它会先将其转换为String然后在操作
2.4.3、转换为Boolean类型
将其它的数据类型转换为Boolean,只能使用Boolean()函数。
使用Boolean()函数
数字 —> 布尔
除了0和NaN,其余的都是true
字符串 —> 布尔
除了空串,其余的都是true
null和undefined都会转换为false
对象也会转换为true
2.5、运算符
运算符也叫操作符,通过运算符可以对一个或多个值进行运算并获取运算结果。
比如:typeof就是运算符,可以来获得一个值的类型,它会将该值的类型以字符串的形式返回(number string boolean undefined object)
2.5.1、算术运算符
算术运算符用于表达式计算。
y=5,下面的表格解释了这些算术运算符:
2.5.2、关系运算符
关系运算符在逻辑语句中使用,以测定变量或值是否相等。
x=5,下面的表格解释了比较运算符:
2.5.3、赋值运算符
赋值运算符用于给 JavaScript 变量赋值。
x=10 和 y=5,下面的表格解释了赋值运算符:
2.5.4、逻辑运算符
逻辑运算符用于测定变量或值之间的逻辑。
给定 x=6 以及 y=3,下表了逻辑运算符:
关于逻辑运算符我们可以具体探讨一下:
&& 与:&&可以对符号两侧的值进行与运算并返回结果,运算规则如下:
两个值中只要有一个值为false,就返回false,只有两个值都为true时,才会返回true
JS中的“与”属于短路的与,如果第一个值为false,则不会检查第二个值
非布尔值时:如果两个都为true,则返回第二个值,如果两个值中有false,则返回靠前的false的值
|| 或:||可以对符号两侧的值进行或运算并返回结果,运算规则如下:
两个值中只要有一个true,就返回true,只有两个值都为false,才会返回false
JS中的“或”属于短路的或,如果第一个值为true,则不会检查第二个值
非布尔值时:如果两个都为false ,则返回第二个值,如果两个值中有true,则返回靠前的true的值
! 非:!可以用来对一个值进行非运算,所谓非运算就是对一个布尔值进行取反操作,true变false,false变true,运算规则如下:
如果对一个值进行两次取反,它不会变化
非布尔值时:先会将其转换为布尔值,然后再取反,所以我们可以利用该特点,来将一个其它的数据类型转换为布尔值,可以为一个任意数据类型取两次反,来将其转换为布尔值,原理和Boolean()函数一样
2.5.5、比较运算符
比较运算符用来比较两个值是否相等,如果相等会返回true,否则返回false。
使用==来做相等运算
当使用==来比较两个值时,如果值的类型不同,则会自动进行类型转换,将其转换为相同的类型,然后在比较
使用!=来做不相等运算
不相等用来判断两个值是否不相等,如果不相等返回true,否则返回false,不相等也会对变量进行自动的类型转换,如果转换后相等它也会返回false
使用===来做全等运算
用来判断两个值是否全等,它和相等类似,不同的是它不会做自动的类型转换,如果两个值的类型不同,直接返回false
使用!==来做不全等运算
用来判断两个值是否不全等,它和不等类似,不同的是它不会做自动的类型转换,如果两个值的类型不同,直接返回true
2.5.6、条件运算符
JavaScript 还包含了基于某些条件对变量进行赋值的条件运算符。
语法:variablename=(condition)?value1:value2;
举例:result=(age<18)?"年龄太小":"年龄合适";
执行流程:如果condition为true,则执行语句1,并返回执行结果,如果为false,则执行语句2,并返回执行结果。
2.5.7、逗号运算符
使用逗号可以在一条语句中执行多次操作。
比如:var num1=1, num2=2, num3=3;
使用逗号运算符分隔的语句会从左到右顺 序依次执行。
2.6、运算符优先级
运算符优先级由上到下依次减小,对于同级运算符,采用从左向右依次执行的方法。
2.7、代码块
2.7.1、语句
前边我所说表达式和运算符等内容可以理解成是我们一 门语言中的单词,短语。而语句(statement)就是我们这个语言中一句一句完 整的话了。语句是一个程序的基本单位,JavaScript的程序就是由一条一条语句构成的,每一条语句使用;结尾。
JavaScript中的语句默认是由上至下顺序执行的,但是我们也可以通过一些流程控制语句来控制语句的执行顺序。
2.7.2、代码块
代码块是在大括号 {} 中所写的语句,以此将多条语句的集合视为一条语句来使用。
例如:
{ var a = 123; a++; alert(a); }
我们一般使用代码块将需要一起执行的语句进行分组,需要注意的是,代码块结尾不需要加 分号。
2.8、条件语句
条件语句是通过判断指定表达式的值来决定执行还是跳过某些语句,最基本的条件语句:
if…else
switch…case
2.8.1、if…else
if…else语句是一种最基本的控制语句,它让JavaScript可以有条件的执行语句。
第一种形式:
if(expression) statement
var age = 16; if (age < 18) { console.log("未成年"); }
第二种形式:
if(expression) statement else statement
var age = 16; if (age < 18) { console.log("未成年"); } else { console.log("已成年"); }
第三种形式:
if(expression1) statement else if(expression2) statement else statement
var age = 18; if (age < 18) { console.log("小于18岁了"); } else if (age == 18) { console.log("已经18岁了"); } else { console.log("大于18岁了") }
2.8.2、switch…case
switch…case是另一种流程控制语句。
switch语句更适用于多条分支使用同一条语句的情况。
语法格式
switch (语句) { case 表达式1: 语句... case 表达式2: 语句... default: 语句... }
注意:需要注意的是一旦符合case的条件程序会一直运行到结束,所以我们一般会在case中添加break作为语句的结束。
案例演示1:根据today的数值,输出今天是星期几。
var today = 1; switch (today) { case 1: console.log("星期一"); break; case 2: console.log("星期二"); break; case 3: console.log("星期三"); break; case 4: console.log("星期四"); break; case 5: console.log("星期五"); break; case 6: console.log("星期六"); break; case 7: console.log("星期日"); break; default: console.log("输入错误"); }
案例演示2:根据month的数值,输出对应月份的天数,2月默认28天。
var month = 10; switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: console.log("31天"); break; case 4: case 6: case 9: case 11: console.log("30天"); break; case 2: console.log("28天"); break; default: console.log("输入错误"); }