1.JS的语法结构
- 单线程
为什么JS是单线程的?
因为JS运行在浏览器中,是单线程的,每个window一个JS线程,既然是单线程的,在某个特定的时刻只有特定的代码能够被执行,并阻塞其它的代码。而浏览器是事件驱动的(Event driven),浏览器中很多行为是异步(Asynchronized)的,会创建事件并放入执行队列中。javascript引擎是单线程处理它的任务队列,你可以理解成就是普通函数和回调函数构成的队列。当异步事件发生时,如mouse click, a timer firing, or an XMLHttpRequest completing(鼠标点击事件发生、定时器触发事件发生、XMLHttpRequest完成回调触发等),将他们放入执行队列,等待当前代码执行完成。
- 异步
异步任务就是不进入主线程,而是进入到任务队列里面的任务,当主线程所有的任务执行完毕后,任务队列会通知主线程请求执行任务,该任务才会进入主线程执行。
执行的过程是:
- 先执行栈中的同步任务
- 当遇到异步任务时,将其放在异步任务处理区中,之后继续执行下面的同步任务。
- 当异步任务在异步处理区中被触发,JS会按照触发的先后顺序将其放在任务队列里面等待被调用。
- 等都执行栈中的同步任务执行完毕,系统就会按照次序读取任务队列中额异步任务,于是被读取的异步任务结束等待状态,进入到执行栈开始执行。
//同步任务
function sum(a,b){
return a+b;
}
const result = sum(1,2)
console.log(result)//输出结果是3
//异步任务
function getMsg(){
setTimeout(fonction(){
return {msg:'Hi'}
},2000)
}
const msg = getMsg()
console.log(msg)//输出结果是undefined
为什么是undefined?
因为当代码执行到定时器时,会将异步代码放在任务队列中,之后还会继续执行同步代码。
定时器被放在任务队列里面,之后继续执行getMsg()函数,这个时候getMsg()函数里面的异步函数还没有被触发,异步函数并没有阻塞线程,代码继续执行,getMsg()函数默认返回一个undefined.
回调函数
用来获取异步API返回值,通过在函数形参中拿到的回调函数引用地址,可以调用回调函数并传递参数给回调函数的形参。
- 解释性语言
- 弱类型
弱类型语言:数据类型可以被忽略的语言,一个变量可以赋不同数据类型的语言,允许变量的类型的隐式转换,允许强制类型转换,如字符串和数值可以自动转换(前提时字符串中必须含有数字)
var sum=200
var sum1='1'
var sum2=sum1+sum;
console.log(sum2);//输出的结果是2001.
此处的“+”号被当成是连接符号
2.JS引入方式
1.行内引入
<开始标签 on +事件类型=“JS代码”></结束标签>
常用事件(使用时在前面加on)
blur | 失去焦点 |
change | 下拉列表选项中项改变或者文本框内容改变 |
click | 鼠标点击 |
keydown | 键盘落下 |
mouseout | 鼠标离开 |
2.内部引入
在head和body中,定义script标签,在script标签中写JS代码
3.外部引入
定义外部文件(.js结尾)
<script type="text/javascript" src="文件名.js"></script>
注意此种script标签中间不要有内容,
3.声明变量
var | 存在变量提升,可以多次赋值,可以多次声明,无自身作用域(相当于全局变量) |
let | 无变量提升,不可以多次声明,可多次赋值,有自身作用域 一般用于循环遍历计数 |
const | 无变量提升,不可以多次声明,不可以多次赋值且定义一定要赋值有自身作用域。 一般用于写在全局作用域作常量。 |
变量提升:是指在变量的作用域内,不管变量在何处声明,都会被提升到作用域的顶部,但是变狼初始化的顺序不变。变量提升实际的实现方法是JS的变量和函数的声明会在编译阶段放入内存。
4.算术运算符
全等于===不全等于!==
比较值的类型和数据的大小,
等于==
只比较值的数据大小。
console.log(10=="10")//true;
console.log(10==="10")//false;
5.数据之间的运算
number (int/float)string boolean null underfined object(对象) symbol(标识符),Array(数组),function;
underfined
和null一样,他是一种特殊的数据类型,表示没有被赋值,当一个变量没有被定义时,它的值就是undefined,表示它没有被赋值。简单说就是一个已经声明了但是未初始化的变量会默认赋值为“undefined"。
undefined不可删除、不可重新定义、不可枚举;
undefined不是JS的关键字和保留字,在全局作用域中不重新赋值,但是在局部作用域中,可以将undefined作为变量名重新赋值,但是不建议这么做。
1.Number类型与Boolean类型运算
console.log(5/false)//输出结果为infinity
在Number类型下true代表1,false代表0;
infinity
ECMAScript中的最小数值存在number.MIN_VALUE 中,这个值一般是5e-124,最大值存在number.MAX_VALUE中,这个值一般是1.7976931348623157e+308;如果计算结果超出了JS的数值范围,则这个数值自动转换成特殊的Infinity,正值为Infinity,负值为-infinity。(表示无穷大或者无穷小)
Infinity属于Number类型,typeof Infinity的返回结果是Number。
JS规定,1/0=Infinity;0作除数,结果为Infinity。
Infinity/Infinity=NaN;
Infinity-Infinity=NaN;
Infinity*0=NaN;
Infinity/0=Infinity;
2.Numnber和undefined类型运算
输出的结果都是NaN。
3.Number和Null类型运算
Null类型数据转换成0,进行数值运算。
4.Number和String类型比较
字符串为纯数字串,转换为Number类型进行比较,字符串中包括字母,输出的结果都是false。
console.log(9=="9");
console.log(9=="9a");
//true
//false
5.String和Boolean以及Null类型运算
若字符串中有非数字字符串,“+”为连接操作,其余输出NaN。(-、*、/、%)
若字符串是纯数字字符串,”+“为连接操作,其余为数值运算。(-、*、/、%)
console.log("5"*true)//结果是5
console.log("5a"*true)//结果是NaN.
console.log("5a"-true)//NaN
console.log("5"-true)//4
console.log(("5"+true)//5true
console.log("5"+true);//5true
6.String和undefined运算
对于所有的字符串,“+”为连接操作,其他都输出NaN.
7.String和Boolean以及Null类型比较运算
若字符串是纯数字字符串,转换为数值后进行比较
若字符串中有非数字字符串,输出结果为false。
8.String和undefined类型比较运算
console.log("undefined"==undefined);
//false
输出结果是false.
6.数组
push() | 在末尾添加元素 |
pop() | 删除最后一个元素返回该元素的值 |
shift() | 删除第一个元素返回会该元素的值 |
unshift() | 在数组的头部添加元素,返回该数组的长度 |
sort() | 对数组进行排序 |
reverse() | 将数组元素的位置颠倒,并返回该数组,(第一个变成最后一个) |
splice(start,deleteCount,intem1) | start 代表要删除项目的位置,使用负值可以从数组结尾处规定位置。 deleteCount代表要删除的项目数量,如果设置成0,则不会删除元素 intem1代表着向数组中添加新的元素 返回值是包含被删除项目的新数组 |
slice(begin,end) | 返回一个新的数组,从原数组中复制begin~end的元素到新数组中。 |
join() | 将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串,如果数组只有一个项目,那么将返回该项目而不适用分隔符,(默认使用“,”,如果是“”,则所有元素之间没有分隔符。 |
concat() | 合并两个或多个数组,不改变现有数组,而是返回一个新数组。 |
7.字符串
charAt() | 方法可返回字符串中指定位置的字符 |
concat() | 犯法用于连接两个或多个字符串 |
indexOf() | 可返回某个指定的字符串值在字符串中更首次出现的位置没找到返回-1 |
includes() | 方法用于判断字符串是否包括指定的子字符串。 |
match() | 可在字符串内检索指定的值,或找到一个或者多个正则表达式的匹配,返回数组 |
search() | 用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,返回与指定查找的字符串或者正则表达式相匹配的String对象起始位置。 |
substring() | 方法用于提取字符串中介于两个指定下标之间的字符 |
split() | 方法用于把一个字符串分割成字符串数组 |
8.对象
引用型数据,是多个数据和方法的集合。
1.内建对象——其实就是指JS中本身自带的对象
- Array对象:提供一个数组的模型来存储大量有序的数据
- Math对象:可以处理所有的数学运算
- Date对象:可以处理日期和时间的存储、转化和表达
- String对象:可以处理所有字符串的操作
2.宿主对象
BOM DOM
3.自定义对象
自己创建的对象
4.定义对象
使用字面量,可以创建对象时,直接指定对象中的属性
对象字面量的属性名可以加引号,可以不加,但是如果要使用一些特殊的名字,则必须加引号
5.构造函数创建对象
使用new关键字调用的函数,是构造函数。
使用typeof检查一个对象时,会返回object。
6.操作对象
访问属性:使用点访问符
给对象添加属性:对象.属性=属性值
删除对象属性:delete对象.属性;
对象属性检测:“属性名” in 对象,有返回true。
var person={
name:"Bob",
age:20,
city:"北京",
hasCar:true//切记此处用逗号隔开。
};
console.log(person.name);
console.log(person.hasCar);
//输出结果
//Bob
//true
7.增强for循环
作用:遍历对象
for(var 变量 in 对象){ }
对象中有几个属性,循环体就会执行几次。每次执行时,会将对象中的一个属性名赋值给变量。
//遍历对象
var add={st:"XJ",fg:"2002012445",xh:"70"};
for(var i in add){
console.log(i);//得到数组中属性名、方法名
console.log(add[i]);//得到对应的属性值
}
//输出结果为
//st
//XJ
//fg
//2002012445
//xh
//70
//遍历对象(构造函数)
function ad(){
var st,xh,fg;
}
var a = new ad();
a.st="XJ";
a.xh="70";
a.fg="2022014789";
for(var k in a){
console.log(k);
console.log(a[k]);
}
//输出结果为
//st
//XJ
//xh
//70
//fg
//2022014789
//遍历数组
var str=[st = "XJ",xh = "70",fg = "202201456789"];
for(var j in str){
console.log(j);//得到数组中属性的索引号为0、1、2
console.log(str[j]);//得到属性值,方法值等
}
//输出结果为
//0
//XJ
//1
//70
//2
//202201456789
9.匿名函数
- 匿名函数自执行:声明后不需要调用就直接执行
- 函数表达式:把函数存到变量,或将函数存到数组的对应位置里等,调用时通过变量或数组对应位置进行调用,调用时需要写括号。
10.异步任务
1.回调函数
定时器
setInterval(隔一段时间执行)
setTimeout(执行一次)
setInterval(function(){
console.log("隔10毫秒执行一次。");
},10);
clearInterval();
setTimeout(function(){console.log("只能执行一次。")},10);
clearTimeout();