目录
方式二: parseInt()函数和parseFloat()函数
一、什么是JavaScript?
Javascript是一个编程语言,允许用户在浏览器页面上完成复杂的事情。浏览器页面并不总是静态的,往往显示一些需要动态更新的内容,交互式地图,动画,以及视频等。一个完整的Javascript包括核心(ECMAScript5),应用程序编程接口即API (比如Dom(Document Object Model),Bom(Browser Object Model)),以及其他第三方API。
早期的js的作用是:在游览器中进行表单验证。现在的js可以做到页面的局部更新(DOM 操作),浏览器的操作(BOM操作),js解释器,IE,网景
Javascript与Html,CSS一同配合共同完成一个复杂页面的显示。
ECMAScript5 JavaScript标准
语法:变量、关键字、保留字、表达式、流程控制语句、对象、函数、数组...
DOM
Document Object Model 文档对象模型,浏览器厂商通过ES编写的控制HTML/CSS的代码
document.getElementById()...
BOM
Brower Object Model 浏览器对象模型,浏览器厂商通过ES编写的控制浏览器的代码
alert()
setTimeout()...
兼容性问题
上面我们可以看出BOM和DOM是各浏览器厂商提供,因此,会有一个兼容性的问题。但是现在,我们有了node.js来支持我们进行开发。node.js中,是不存在兼容性问题的,且node.js中没有dom/bom,因此,我们在node.js中执行任何的dom/bom都是不可行的。正是因为node.js中没有兼容性,所以,node.js是可以运行ES6。
为什么node.js没有兼容性问题?
node.js是google将浏览器中的js解释器提取出来,可以被安装到任意的服务器端来进行解释。而且,node.js中还提供了大量的基础库,此时,js就具备了服务器端的能力。既然node.js是google自己弄出来的,那么兼容性问题自然也就不存在了。
js执行流程
js的执行可以分为两种,一种是在node.js环境下执行,一种是在浏览器中执行。
node.js
在vi编辑器中编写,在node.js中执行,不可以使用DOM/BOM。
如果我们使用Vue框架以及webpack构建工具,那么他会进行一些预处理,是在本地nodejs环境执行的,编译打包过后方可在浏览器端执行。
浏览器
浏览器中执行,就是直接在浏览器中使用浏览器自带的解释器执行,需要考虑兼容性问题。可以使用DOM/BOM
二、JavaScript特点
客户端代码,客户机上执行。
Js特殊的地方在于它也可以作为服务器端代码执行,但是需要搭建Node环境
解释性语言。
被内置于浏览器中的Js解析器解析执行,执行前无需编译
弱类型语言
从上往下顺序解析执行
三、基本语法
3.1.注释
html
<!--注释 -->
css:
/*注释*/
JavaScript:
//单行注释:前面的不影响,只注释符号后面内容
/*多行注释*/
3.2.关键字保留字
我们创建的标识符不可以使用这些关键字或保留字来当作标识符名,两者的区别就是,关键字就是JavaScript中有特殊功能。保留字则会在将来有可能称为关键字
3.2.1.关键字
3.2.2.保留字
3.3.标识符
在JavaScript中,所有我们自己命名的就是标识符。比如,变量名、函数名、属性名...
3.3.1.标识符命名规则
1.标识符中可以有字母、数字、下划线、$
2.标识符不能以数字开头
3.标识符不能是关键字或保留字
4.标识符一般都采用驼峰命名法,首字母小写,每个单词开头字母大写
3.3.2.补充
JavaScript底层保存的标识符实际上是采用Unicode编码,因此,理论上,所有的utf-8中的内容都可以作为标识符
3.4.变量
注:变量是需要声明和赋值的。声明就是var a;赋值就是a = 1;两者也可以同时进行
JavaScript是一种弱类型的语言,
1.变量的数据类型在初始化的时候才确定(赋值)
2.数据类型可以改变
3.类型细分不明显,比如2和2.2同属于Number类型
java是一种强类型语言,
1.变量的类型在声明的时候就已经确定了
2.一旦确定不能更改
3.5.字面量
不可以改变的值,比如,1 2 3 4 ...
字面量可以直接使用,但是我们一般不是直接使用,而是用变量保存后使用,且保存后更方便使用
3.6.JavaScript数据类型
3.6.1.基础数据类型
变量的值保存在栈区,也就是说,变量中保存的就是值
String 字符串
在js中字符串西药使用引号括起来
1.单双引号不可混用
也就是说,单引号和单引号一一对应,双引号和双引号也必须一一对应
2.不可嵌套,但是可以互相嵌套。
也就是说,双引号中不可以在包括双引号,单引号也一样不可以
3.特殊字符替代
在字符串中,可以使用一些规定好的其他符号来代替我们要使用的特殊字符。也可以使用 \ 来进行转义。
\n 换行符
\t 制表符
\\ \
Number 数值
1.所有的数值都是Number类型
2.字符串和Number类型控制台输出相同。
字符串123和Number类型的123在控制台输出是一样的。我们可以通过typeof来进行判别
3.最大的数
JavaScript中有一个设定好的最大的数。Number.MAX_VALUE
4.Infinity
当超出js中的最大值的时候,则返回Infinity(正无穷)
5.NaN
NaN实质上是not A Number。只有Number数据类型的值可以进行运算,当我们使用其他类型的数据进行运算时,会返回NaN。 当然了,字符串的+时等同于拼接,以及默认的类型转换,并不属于这个范围内。
6.整数运算精确,浮点数则可能出错,不精确
Boolean 布尔值
1.true真false假
Null 空值
1.专门表示为空的对象
Undefined 未定义
1.仅仅声明了一个变量,但是不赋值,那么这个被声明的变量的值就是undefined
3.6.2.引用数据类型
变量的值保存在堆区,变量中保存的是引用地址,而并不是跟基本数据类型一样的值
除了基本数据类型以外的其他数据类型都是引用数据类型,比如,Object(对象)、Array(数组)、Function(函数)等......
3.6.3.基本数据类型和引用数据类型的区别
基本数据类型是直接在堆内存中存储,值和值之间是独立存在,修改一个变量不会影响其他值
引用数据类型是保存到对内存中的,每创建一个新的对象,变量保存的都是对象的内存地址,因此,我们修改其中一个的值,其他值也会跟着改变。
3.7.类型检测
3.7.1.typeof方法
需要注意的是:检测一个空对象,也就是值为null的对象,结果为Object
此时我们可以通过逻辑运算符全等号来实现,比如 a === null。
3.7.2.isNaN()函数
可以判断一个值是不是NaN
3.8.强制数据类型转换
将一个数据类型强制转换为其他数据类型,主要指的是,将其他的数据类型转换成String、Number、Boolean。
3.8.1.转换成String
方式一:toString()方法
1.该方法不影响原来的值,他会转换后的结果返回
2.null和undefined没有toString方法,因此,不可以对这两种类型使用toString
a.toString()
方式二:String()函数
1.该方法需要将被转换的值作为参数,同样会将转换结果返回
2.该方法对基本数据类型都适用
String(a)
方式三:+''
我们可以利用任何值和字符串进行+操作时,会将其转换为字符串并拼串的设定,来进行类型转换
123 + ''
3.8.2.转换成Number
方式一:Number()函数
1.该方法需要将被转换的值作为参数,同样会将转换结果返回
2.该方法对基本数据类型都适用.
分类
(1)字符串转Number
纯数字,直接转换成Number
有非数字内容,转换成NaN
空串或全为空格,转换成0
(2)布尔转Number
true,转换成1
false,转换成0
(3)null转Number
null,转换成0
(4)undefined转Number
undefined,转换成NaN
Number(a)
方式二: parseInt()函数和parseFloat()函数
1.该方法需要将被转换的值作为参数,同样会将转换结果返回
2.该方法只适用于字符串.
这种方式专门用来解决字符串问题,非字符串类型,则会先把转换成字符串再进行操作。
paeseInt()可以将字符串中的有效整数内容取出,转换成Number,从最前面的数字开始,直到第一个非数字结束。如果最前面不是整数,则返回NaN,可以利用这个函数来取整。
parseFloat()作用和paeseInt()类似,但是它取出的有效浮点数
方式三:+a或-(-a)
+(a)
-(-a)
其他进制的数字
paeseInt()当使用两个参数时,第一个参数会取整,第二个参数则是转换后的进制数。
3.8.3.转换成Boolean
方式一:Boolean()函数
1.该方法需要将被转换的值作为参数,同样会将转换结果返回
2.该方法对基本数据类型都适用.
分类
(1)数字转换Boolean
除了0和NaN以外,其余全是true
(2)字符串转换Boolean
除了空串,全是true
(3)null转换成Bool
false
(4)undefined转换成Boolbean
false
方式二:!!(a)
!!a
3.9.深拷贝浅拷贝
3.9.1.浅拷贝(地址的拷贝)
仅仅是把保存地址给出,只是可以使用,所以是在同一份数据中进行修改。
3.9.2.深拷贝(克隆)
将原来的整个数据复制一份保存,再将新数据的保存地址给出。可以对改地址保存的数值进行修改,因此是对新的自己的数据进行修改
3.10.算数运算符
1.任何值和NaN做运算结构都为NaN
2.当我们进行运算时,同等级的运算,从左往右开始运算。互不干扰
3.当对除字符串外的非Number类型值进行算数运算,会先转换为Number再运算。但是仅在加法运算中有字符串时,则会变为字符串拼接操作。当进行类型转换后,转换成NaN后,再进行运算,此时结果恒为NaN
4.任何值和一个字符串相+,则是会先转换成字符串,再进行拼串操作,并不是常规算数运算。我们也可以加一个空串来进行类型转换。
3.10.1.+
可以对两个值进行加法运算,并将结果返回。对原变量无影响
3.10.2.-
可以对两个值进行减法运算,并将结果返回。对原变量无影响
3.10.3.*
可以对两个值进行乘法运算,并将结果返回。对原变量无影响
3.10.4./
可以对两个值进行除法运算,并将结果返回。对原变量无影响
3.10.5.%
可以对两个值进行取余运算,并将结果返回。对原变量无影响
3.11.一元运算符
只需要一个参数的运算符,比如,typeof
3.11.1.正负号
+ 正号
- 负号
正负号的运算跟算数运算类似,先转换成Number,在进行运算。可以用它来进行隐式的类型转换
3.11.2自增和自减
自增
自增是变量在自身的基础上加1
++i
先将i的值+1,再用加1后的值进行当前运算。
i++
先用本来的a进行当前运算。运算结束后,将i的值+1
自减
自减是变量在自身的基础上减1
--i
先将i的值-1,再用减1后的值进行当前运算。
i--
先用本来的a进行当前运算。运算结束后,将i的值-1
3.12.赋值运算符
将符号右侧的值赋值给左侧的变量
= 等号
+= 加等
将原值进行+运算后再赋值
-= 减等
将原值进行-运算后再赋值
*=
将原值进行*运算后再赋值
/=
将原值进行/运算后再赋值
%=
将原值进行%运算后再赋值
3.13.逻辑运算符
3.13.1.布尔值的逻辑运算
这里的逻辑运算符的运算也是从左往右的,即当结果确定时,就不会再判断后面的
! 非
对一个操作数进行非运算,首先他会把值转换成Boolean类型,在进行非运算。当我们取两次反的时候,就可以将其转换为Boolean类型了。
&& 与
对符号两侧的值进行与运算,并返回结果。两个值只要有一个false,则结果为false
|| 或
对符号两侧的值进行或运算,并返回结果。两个值只要有一个true,则结果为true
3.13.2.非布尔值的逻辑运算
对于非布尔值而言,会先将其转换成Boolean值,进行运算,但是在返回结果的时候,会返回原值,并不是返回true和false
3.14.比较运算符
3.14.1.大于小于
<= 小于等于
< 小于
> 大于
>= 大于等于
对符号两边的值进行比较,如果关系成立,返回true;不成立返回false。
1.如果对非数值进行比较,那么就会将其转换为数值再比较
2.如果两边都是字符串,那么就会将其转换为Unicode编码,再进行比较。
在比较两个数字字符串时,这样的方式就不合适了,所以,我们需要把他们进行类型转换再比较。
在比较两个字母字符串时,是一位一位进行比较的,当我们的当前字符一致时,就会比较下一位,直到比出大小为止。我们可以通过比较来对字母进行排序。
3.14.2.等于和不等
== 等于
判断符号两边的值是否相等
比较基本数据类型
当使用==进行比较的时候,如果值的类型不同,他会自动将操作数转换为同一数据类型再进行比较。
注:这里的类型转换,并不是统一转换成Number类型,而是根据比较对象不同,而对应转换。
1.undefined衍生自null,因此两者做相等判断,返回true
2.NaN不和任何值相等,包括它本身。
我们可以通过isNaN()函数来判断一个值是不是NaN。
比较引用数据类型
此处比较的是引用数据类型的引用地址,我们可以先将其转换为基本数据类型,再进行比较
!= 不等
判断符号两边的值是否不相等
当使用!=进行比较的时候,如果值的类型不同,他会自动将操作数转换为同一数据类型再进行比较。
3.12.3.全等和不全等
=== 全等
先比较两个操作数的数据类型,如果数据类型不一样,直接返回false,数据类型一致时在比较值。
!== 不全等
也是先比较操作数的数据类型,如果数据类型不相同,直接返回true,数据类型不同之后再比较值,不同返回true
3.15.三元运算符
条件表达式?语句1 :语句2
当条件表达式的值为true,执行语句1;false执行语句2
3.16.流程控制语句
js中的代码是从上往下一行一行执行的,通过流程控制语句,可以控制程序的执行流程,使得程序可以根据一定的条件来执行选择好的语句
3.16.1.条件判断语句
条件判断语句,可以再执行某个语句之前进行判断,判断通过,语句执行,不通过则不执行该语句
if语句
if (条件表达式) {
执行代码
}
条件表达式值为true,代码段才会被执行;值为false,则不执行代码段。
当后面要执行的代码段只有一行时,可以省略{},但是尽量写上
if语句只能控制紧跟其后的那个语句,如果我们需要if语句控制多个代码段,就需要把他们放到一个{}中
if-else语句
if (条件表达式) {
代码段1
} else {
代码段2
}
条件表达式值为true,代码段1才会被执行;值为false,则代码段2被执行
if-else if-else语句
if (条件表达式1) {
代码段1
}else if (条件表达式2) {
代码段2
}else {
代码段3
}
条件表-达式1值为true,代码段1才会被执行;条件表达式1值为false,判断条件表达式2;条件表达式2值为true,则代码段2被执行;条件表达式2值为false,代码段3被执行。注意,此处的else if可以写多个
3.16.2.条件分支语句
switch语句
switch (a) {
case 条件1:
代码段1;
break
case 条件2:
代码段2;
break
case 条件3:
代码段3;
break
default:
代码段4
}
根据参数来判断满足哪个条件,满足条件1就执行代码段1;满足条件2就执行代码段2......如果都不满足,就执行default后的代码段4.
break语句是用来退出整个switch语句的。
3.16.3.循环语句
当我们有一段代码需要重复执行多次时, 这个时候就需要用到我们的循环语句了。
while循环
while (条件表达式) {
代码段(循环体)
}
对条件表达式进行求值判断,条件表达式的值为true,执行代码段。执行完毕后,则需要再次对条件表达式,进行判断,值为true,再次执行循环体,直到条件表达式为false时,结束循环。
注意:我们在设置好条件表达式的时候,还需要在代码段中定义一个更新表达式,否则会形成死循环的情况。
while (条件表达式) {
代码段(循环体);
更新表达式;
}
while (i < 10) {
代码段(循环体);
i++;
}
do-while循环
do {
循环体(代码段);
}while (条件表达式)
先执行循环体代码段,再对条件表达式进行求值判断,条件表达式的值为true,执行代码段。执行完毕后,则需要再次对条件表达式,进行判断,值为true,再次执行循环体,直到条件表达式为false时,结束循环。
两者之间的区别就是do-while可以保证至少执行一次循环体代码段
for循环
for (初始化表达式; 条件表达式; 更新表达式) {
循环体(代码段);
}
for (let i = 0; i < 10; i++) {
循环体(代码段);
}
在for循环中,为我们提供了专门的位置存放我们的三个表达式:初始化表达式、条件表达式、更新表达式。其中的执行逻辑和while循环是类似的。
注意:for循环的三个部分都可以省略,我们可以把初始化表达式写道for循环外部,或是将更新表达式写入循环体中。三者都不写,只写两个;;此时循环,是一个死循环,一直执行下去。
for循环的执行流程:
1.执行初始化表达式,初始化变量
2.执行条件表达式,判断是否执行循环
true,执行循环
false,终止循环
3.执行更新表达式,更新表达式执行完毕,重复第2步
forin循环
用来对数组或对象进行循环,每次循环按索引来取出数组或对象中的元素。但是该方法只能遍历我们自定义的属性,原型上的属性是不会被遍历出来的。当我们在数组中添加新的自定义属性的时候,这个新属性也会被遍历出来。
遍历数组的时候,获取到的就是数组元素的索引,我们可以通过索引来获取值
const arr = ["孙悟空","猪八戒","沙和尚","蜘蛛精","白骨精"];
for (let i in result) {
console.log(result[i])
}
遍历对象的时候,我们获取到的就是对象的键,我们可以通过键来找到我们所需要的值。
const obj = {
name: 'why',
age: 18,
height: 1.88
}
for (let key in obj) {
console.log(key)
console.log(obj[key])
}
foreach循环
IE8及以上浏览器
forEach()方法需要一个函数来作为参数。这种函数,由我们创建,但不是由我们调用,我们称之为回调函数
数组中有几个元素,该函数就会执行几次,每次执行,浏览器会将遍历到的函数作为实参传递进函数中。因此,我们可以定义形参来读取这些内容。当我们只有一个形参的时候,调用的是value。
浏览器会在回调函数中传递三个参数
第一个参数,就是当前正在遍历的参数 value
第二个参数,就是当前正在遍历的参数的索引 index
第三个参数,就是遍历的数组本身 obj
arr.forEach(function(value , index , arr){
})
forof循环
for (let i in result) {
console.log(i)
}
forof循环和forin循环都可以遍历数组,但是两者之间还是有很大区别的。
1.forof循环遍历的则是数组中元素本身,而不是其索引。
2.当我们在数组中添加了新的属性时,这个新属性不会被遍历。
3. forof不能遍历对象
3.16.4.break和continue
break
退出当前循环语句,后面的循环也不执行了,直接退出
continue
终止本次循环,直接执行下次循环。
label的使用
我们可以为我们的循环创建一个label,用来标识这个循环语句
label:
for (const resultElement of result) {
}
此时,我们就可以通过break和continue来终止特定的循环。