前言
JavaScript 是一种轻量级的脚本语言,所谓脚本语言就是指它不具备开发操作系统的能力,而只是用来编写控制其他大型应用程序的脚本。 JavaScript 是一种嵌入式语言,本身提供的核心语法不算很多,可用于 html 和 web ,更可广泛应用于服务器,PC等设备
类似于 C 语言,一行一行的执行,每一行就是一条语句
优点
- 操控浏览器的能力
- 广泛的使用领域
- 易学
与ECMAScript 的关系
ECMAScript 和 JavaScript 的关系,前者式后者的规格。后者是前者的一种实现
将js引入到html文件中
嵌入到文件中
需要在 <body> 标签之内嵌入
1 | <body> |
引入独立js文件
要在 script 标签内定义 type 和 src 属性
1 | <script type="text/javascript" src="./语法.js"></script> |
type表示引入文件类型src文件的路径
引入网络来源文件
1 | <script src="https://..."></script> |
其中的 src 就是引入的 js 文件的网址,不需要指定 type 类型
语法
标识符
标识符指的是用来识别各种值的合法名称,最常见的标识符就是变量名,标识符是由字母,dollar符号,下划线和数字组成,不能以数字开头,中文是合法的标识符,可做变量名,不推荐
保留关键字
在 js 中的保留关键字不能用作标识符
变量
可以被赋值的标识符,类似于 C 语言
注释
js 中代码的注释不会被引擎解释,有两种写法
- 行注释
// - 块注释
/*...*/ - 嵌入在
html中的注释<!--...-->
输出
有多种输出方式
alert(content)弹窗输出document.write(content)文件写入console.log(content)终端输出
数据类型
- 原始数据类型
- 数值
- 字符串
- 布尔值
- 特殊值
- undefined
- null
- 合成类型
- 对象
- 新增类型
- Symbol
- BigInt
运算符
- typeof运算符 可以检测数据类型,对于数据类型中,
null和undefined都可以表示没有,将一个变量做这两种赋值是没有区别的 +-*/%++--=+=-=*=/=%=<><=>======严格相等!=!==严格不相等!&&||
条件语句
ifif...else if...elseswitch...case...default
三目运算符
1 | (condition) ? a : b; |
循环语句
forwhile()
跳出循环的语句 break 中断循环, continue 终止此次循环,开启下次循环
字符串
由零个或多个放在双引号或者单引号之中的字符,单引号字符串内部可以使用双引号,双引号字符串内部可以使用单引号。对于双引号内部使用双引号和单引号内部使用单引号,必须使用转义 \' 和 \"
常用方法
length属性,返回字符串的长度charAt()返回指定位置的字符concat()用于连接两个字符串,返回一个新的字符串,不改变原字符串,可以接收多个字符串,如果参数不是字符串会将其转为字符串然后连接substring()截取字符串,两个参数,第一个表示开始位置,第二个表示结束位置,不包括结束位置,默认是到末尾,会自动调换两和位置的顺序,保证小的在前,会把负数转为 0substr()截取字符串,两个参数,第一个表示开始位置(从0开始),第二个表示截取长度,到结束为止。第一个参数为 0 意味着倒着计算字符的为止,第二个参数小于等于 0 返回空字符串indexOf()用于确定一个字符串在另一个字符串中第一次出现的为止,返回结果是匹配开始的为止,如果返回-1表示没有匹配项,还可以接受第二个参数,表示从该位置向后匹配trim()去除字符串两端的空格,返回新的字符串,不改变源字符串,去除的不仅仅是空格,还有换行,回车和制表符split()按照某个字符来分割,就是以某个字符作为分割符,从字符串中找到该字符时将该字符作为分割符把字符串分割,如果分割字符为空,则返回源字符的每一个字符
数组
是按照次序排列的一组值,每个值位置都有编号,整个数组用方括号表示,位置排列从 0 开始,这个数组是一个通用的数组,任何数据都可以被放入数组中
length属性,返回数组的长度- 遍历,可以使用
for循环,或者是while循环,使用for(... in ...)进行循环 Array.isArray()返回一个布尔值,表示参数是否为数组,可以弥补typeof运算符的不足,这个方法不是数组的内部元素push()用于在数组的末端添加一个或多个元素,并且返回添加新元素后的数组长度,该方法会改变原数组pop()用于删除数组的最后一个元素,并且返回该元素shift()用于删除数组的第一个元素,并且返回该元素,会改变原数组unshift()用于向元素第一个位置添加元素,并且返回该数组的长度,会改变原数组,可以接收多个参数,这些参数都会添加到目标数组头部join()指定参数作为分割符,将所有数组成员连接成为一个字符串,默认为逗号,对于数组中的数组,就使用逗号进行分割,如果数组成员时undefined或者null或者空位,会被转为空字符串concat()用于多个数组的合并,将新数组的成员添加到原数组候补,并且返回一个新数组,原数组不变,也支持其它类型的值reverse()用于颠倒原数组,返回改变后的数组,但是会改变原数组indexOf()返回给定元素在数组中第一次出现的位置,如果没有出现则返回-1,可接受第二个参数,表示开始查找的位置
函数
是一块能反复调用的代码块,使用 function 命令声明代码区块,就是一个函数 function 命令后面就是函数名,函数名之后是一对圆括号,里面是传入函数的参数,函数体放在打括号内,类似于C语言,但在小括号内的参数不需要添加参数类型
函数声明时,只需要将函数名和形参声明即可.
对象
对象就是键值对,是一种无序的符合数据集合,声明类似于 python 中的字典
对象的每一个键名又称为属性,它的键值可以是任何数据类型
如果一个属性的值为函数,通常把这个属性称为方法,可以像调用函数一样调用
如果属性值还是一个对象,就形成了链式引用
math对象
是 JS 的原生对象,提供各种数学功能
Math.abs()返回绝对值Math.max()返回最大值Math.min()返回最小值Math.floor()返回小于参数值的最大整数Math.ceil()返回大于参数值的最小整数Math.random()返回 0 到 1 之间的一个伪随机,可能等于 0,但一定小于 1
Date对象
date 是 JavaScript 原生的时间库,以1970年1月1日0点作为时间的零点,可以表示的时间范围是前后各一亿天
Date.now()返回当前时间距离时间零点的毫秒数- 时间戳,就是距离时间零点的秒数
Date.getTime()返回实例距离时间零点毫秒数Date.getDate()返回实例对象对应每个月的几号Date.getDay()返回实例星期几,周日为Date.getYear()返回距离1900的年数Date.getFullYear()返回四位的年份Date.getMonth()返回月份Date.getHours()返回小时Date.getMilliseconds()返回毫秒Date.getMinutes()返回分钟Date.getSeconds()返回秒
js错误
- 使用
try语句测试代码块的错误 - 使用
catch语句处理错误 - 使用
throw创建自定义错误,相当于是抛出错误 - 使用
finally语句在最后,无论上述是否触发错误,都会执行的语句
1 | try{ |
let声明
let 声明的变量旨在当前代码块内有效
const声明
const 声明的变量一旦声明,常量的值就不能改变
变量提升
就是有时候会在变量声明之前使用,这时候不会报错,而变量的值为 undefined
dom
dom是 JavaScript 操作网页的接口,是文档对象模型。作用是将网页转为一个 JavaScript 对象,从而使用脚本进行各种操作,比如对元素的增删改等
浏览器会根据 dom 模型,将结构化文档 html 解析成一系列的节点,再由这些节点组成一个树状结构 dom tree 。所有的节点和最终的树状结构都有对外的接口。
dom 就是一个接口规范,可以用各种语言实现,但是 dom 是 JavaScript 最常见的任务
节点
dom 的最小组成单位为节点,文档的树形结构是不同的节点组成的,每个节点相当于是文档树的一片叶子,类型有 7 种,如下
Document文档树的顶层节点DocumentTypedoctype标签Element网页各种 html 标签Attribute网页元素的属性Text标签之间或标签包含的文本Comment注释DocumentFragment文档的片段
节点树
一个文档的所有节点,按照所在的层级,可以抽象成一种树状结构。浏览器原生提供 document 节点,代表整个文档。除了根节点,其他节点都有如下三种层级关系
- 父节点关系:直接的上级节点
- 子节点关系:直接的下级节点
- 同级节点关系:拥有同一个父节点的节点
Node.nodeType
| Node类型 | Named Constant |
|---|---|
| 1 | ELEMENT_NODE |
| 2 | ATTRIBUTE_NODE |
| 3 | TEXT_NODE |
| 4 | CDATA_SECTION_NODE |
| 5 | ENTITY_REFERENCE_NODE |
| 6 | ENTITY_NODE |
| 7 | PROCESSING_INSTRUCTION_NODE |
| 8 | COMMENT_NODE |
| 9 | DOCUMENT_NODE |
| 10 | DOCUMENT_TYPE_NODE |
| 11 | DOCUMENT_FRAGMENT_NODE |
| 12 | NOTATION_NODE |
不同节点的 nodeType 属性值和对应的常量如下
Document9DocumentType1Element2Attribute3DocumentFragment11
document 获取元素
getElementsByTagName()通过搜索 html 标签名返回符合条件的元素,返回值是一个类似数组对象的,如果没有匹配的元素,返回空集getElementsByClassName()通过类名搜索,返回包含该类名的元素,元素的变化也会实时返回在结果中,参数可以是多个,通过空格分隔getElementsByName()用于选择拥有name属性的 html 元素,返回一个类似数组的对象getElementById()匹配指定 id 属性的元素节点,如果没有发现节点,返回 nullquerySelector()接受一个css选择器作为参数返回匹配该选择器的元素节点,如果有多个返回第一个querySelectorAll()接受一个css选择器作为参数返回匹配该选择器的元素节点,返回一个数组
document 创建元素
createElement()生成元素节点,并且返回该节点,参数是元素类型createNextNode()用于生成文本节点,并且返回该节点,参数是文本节点的内容createAttribute()生成一个新的属性节点,并且返回该节点
element 对象属性
element 对象对应于网页的 html 元素,每一个 html 元素都会被转化为一个 element 节点对象
id属性返回指定元素的id属性,该属性可读写className用于读写该元素节点的class属性,值是一个字符串,中间用空格隔开classList有如下方法add()增加一个classremove()移除一个classcontain()检查当前元素是否包含某个classtoggle()将某个class移入或移除当前元素
innerHTML返回一个字符串,等于该元素包含的所有html代码,该属性可读写,用来设置节点的内容,能改写所有元素节点的内容,包括<html>和<body>元素innerText与上述类似,不同的是该方法会直接渲染为字符串
element 获取元素位置
clientHeight获取元素高度,包括padding但是不包括border和margin,只对块级元素生效,如果有水平滚动条,需要减去水平滚动条的高度clientWidth获取元宽度,同上scrollHeight元素总高度,同上,但是包括溢出的不可见的内容scrollWidth元素总宽度,同上scrollLeft元素水平滚动条向右滚动的像素效果scrollTop元素水平滚动条向下滚动的像素效果offsetHeight元素的 CSS 垂直高度,包括元素本身的高度,padding和borderoffsetWidth元素的 CSS 垂直高度,同上offsetLeft元素到定位父级左边界的间距offsetTop元素到定位父级上边界的间距
CSS 操作
操作 CSS 样式最简单的办法就是,对 html 元素的 style 属性进行操作,有三种操作方式
- 使用
setAttribute设置属性style的参数 - 使用元素节点的
style属性进行设置 - 使用元素节点的
style属性设置该属性的cssText进行设置样式
事件处理程序
html事件处理,类似于按钮点击特效果dom0级事件处理,其中html和js是分离的,但是无法添加多个事件dom2级事件处理,其中html和js是分离的,可以添加多个事件
鼠标事件
鼠标事件指的是与鼠标相关的事件,具体
click按下鼠标触发dblclick在同一个元素上双击鼠标触发mousedown按下鼠标时触发mouseup释放鼠标时触发mousemove鼠标在节点内部移动时触发,鼠标持续移动,该事件会持续触发mouseseenter当鼠标进入一个节点时触发,进入子结点不会触发mouseleave当鼠标离开一个节点时触发,离开父结点不会触发这个事件mouseover鼠标进入一个节点时触发,进入子结点会再次触发mouseout鼠标离开一个节点时触发,离开父结点也会触发wheel滚动鼠标滚轮时触发
事件对象
一个事件发生以后,会产生一个事件对象,作为参数传给监听函数
属性
Event.Target返回事件当前所在的节点Event.type返回一个字符串,表示事件类型,事件类型是在生成事件时产生,该属性只读
方法
Event.preventDefault()取消浏览器对当前事件的默认行为Event.stopPropagation()阻止事件在dom中继续传播,防止再次触发在别的节点上的监听函数,但是不包括在当前节点上的其它事件的监听函数,例如对于父子元素都有点击事件,当点击子元素时,父元素也会触发点击事件,这个方法能阻止子元素点击事件的扩散,以至于不会触发父元素的点击事件
键盘事件
用户击打键盘触发主要有三个事件
keydown按下键盘时触发keypress按下有值的键时触发,也就是按下ctrl,alt等无值的键不会触发,对于有值的键,先触发keydown再触发keypresskeyup松开键盘时触发的事件
event对象
keyCode 表示你所按下的按键的代码
表单事件
是使用表单元素以及输入框元素可以监听的一系列事件
input当<input>,<select>和<textarea>的值发生变化时触发,对于复选框<input type=checkbox>或单选框<input type=radio>,当用户改变选项时,也会触发这个事件,每按下一次按键就会触发一次select当<select>事件在<input>和<textarea>中选中文本时触发Change当<input>,<select>和<textarea>的值发生变化时触发,但是只有当全部修改完之后才会触发reset这是发生在表单对像上的,当表单重置时触发submit这是发生在表单对象上的,当表单数据向服务器提交时触发,发生对象是<form>元素,而不是<button>元素
事件代理
由于事件会在冒泡阶段传递给父结点,因此可以把子结点的监听函数定义在父结点,由父结点的监听函数统一处理多个子元素的事件,这种方法就是代理
定时器setTimeout
js 中提供定时执行代码的功能,叫做定时器,主要由 setTimeout 和 setInterval 两个函数完成,它们向任务队列中添加定时任务
setTimeout用来指定某个函数或者某段代码,在多少毫秒之后运行,返回一个整数,表示定时器的编号,以后可以取消定时器,接收两个参数,第一个参数是将要推迟执行的函数名或者一段代码,第二个参数是推迟执行的毫秒数,只执行一次。还有就是如果回调函数是对象的方法,那么该函数使得方法内部this关键字指向全局环境,而不是定义时所在的那个对象setInterval这个函数与上述定时器的函数几乎一致,唯一不同之处在于这个函数的定时器是循环执行无数次clearTimeout(id)取消定时器,参数就是上述的定时器编号
防抖
防抖严格来说应该属于性能优化事件,对于高频的信息,处理不当会导致浏览器卡死,例如一个滚动条监听的例子
1 |
|
一次滚动能产生好多条消息,执行频率太高了,会导致网页卡顿,有一种解决方式就是在第一次触发时,不立即执行函数,而是给一个期望值的定时器去执行,然后如果在这个期望值内没有发生触发滚动条件,那就执行函数,如果在这段时间内再次触发事件,那之前的计时取消,从新开始计时,从而保证短时间内多次触发只执行一次函数
节流
节流也属于是性能优化的功能,对于上述的防抖,就会导致在规定的时间段内,不断触发滚动事件,只要不停止触发,理论上就永远不会输出当前距离顶部的位置
节流就是在某次触发之后,函数执行一次之后,在短时间内不会再次触发,过了一段事件之后才生效
对于防抖的常用场景
- 搜索框
input要支持实时搜索可以使用节流方案,或者实现输入间隔大于某个值之后就当作输入完成,然后开始搜索 - 页面
resize事件,用于需要做页面适配的时候,根据最终呈现的情况进行dom渲染就可以了,一般会使用防抖,因为只需要判断最后一次的变化情况就可