编程语言-JavaScript学习笔记

入门基础

环境搭建

VSCode + 浏览器

必备插件

HTML CSS Support

官方推荐的插件,自动补全

open in browser

快速在浏览器中查看网页

error lens

报错显示

CSS Peek

追踪样式

Auto Rename Tag

成对修改标签。VS自带的重名名好像已经具备。

工程

常用资料

MDN

MDN官方网站

核心知识

JavaScriptHTML中的一个script标签,很多地方需要遵守HTML的规范。

结构

js代码存在多种方式:内部、外部、内联。

内部方式

1
2
3
4
5
6
<body>
<!-- 内部js -->
<script>
// 具体逻辑
</script>
</body>

HTML标签是按照顺序加载进入,一般推荐写在</body>标签之前,可以尽量保障所有标签都能访问到。

外部方式

1
2
3
4
<body>
<!-- 外部js -->
<script src="js文件所在位置"></script>
</body>

值得注意的是,body标签中引入script,会忽略script标签中的代码。

内联方式

这种方式在前端框架vue中使用比较多。

1
2
3
4
<body>
<!-- 内联js -->
<button onclick="alert('逗你玩~~~')">点击我月薪过万</button>
</body>

行结尾符

C++类似使用英文;,但很多场合结尾符是可以省略的,推荐都省略掉。

常用输入输出

window下面的函数调用可以省略window

函数功能说明
window.alert弹窗输出信息
document.write文档输出信息,支持解析HTML
console.log控制台输出信息
window.prompt弹窗输入信息

注释

C++一行,单行注释使用//,多行注释使用/**/

1
2
3
4
5
// 单行注释

/*
多行注释
*/

变量

命名规则

  • 不能使用保留关键字
  • 使用下划线、字母、数字、$,不能以数字开头
  • 区分字母大小写

数字Number

js中数字不区分整型和小数

1
2
let n1 = 10
let n2 = 3.14

运算异常时,会返回NaN

布尔Boolean

1
2
let b1 = true
let b2 = false

字符串String

字面量支持反引号,可以将数字和字符串输出,类似格式化输出。

1
2
3
4
let s1 = 'hello'
let s2 = "world"
let s3 = `Pi is ${n2}`
let s4 = '3.14'

可以使用\转义符。

+可以连接两个字符串字面量或变量。

字符串转换数字

当使用+s4可以将字符串转换为数字。

使用函数parseIntparseFloat

数组Array

js中数组不要求每个元素要一致,类似其他语言的元组。

简单声明如下:

1
2
3
4
const arr1 = [1, 2, 3]
const arr2 = ['hello', 'world']
const arr3 = [1, 'hello']
const arr4 = new Array(1, 'hello')

常用数组方法

新增成员

push在数组尾部插入成员

unshift在数组头部插入成员

删除成员

pop删除数组尾部成员

shift删除数组头部成员

splice删除或替换数组指定区域的成员

修改成员

通过下标索引

访问成员

通过下标索引

对象

js中对象支持动态扩展成员及方法,所有对象都是Object。对象默认使用引用方式进行赋值,所以一般使用const进行声明即可。

简单声明

1
2
3
4
const obj1 = {
uname: 'Tik',
cnt: 0,
}

增加成员

对象.成员 = 值

删除成员

delete 对象.成员

修改成员

对象.成员 = 新值

访问成员

若成员名称符合语法

对象.成员

若名称不符合语法,比如:需要访问'number 1 - cnt'成员

对象[成员]

undefined

默认为赋值的变量都会返回undefined。运算结果一般都为undefined

null

可以运算,结果与另一个算子相关。

内置Math对象

常用方法

方法说明
random随机值
ceil向上取整
floor向下取整
max最大值
min最小值
pow幂运算
abs绝对值

声明关键词

关键词const声明常量,声明后不能改变常量本身js中常量本身存放的是对象或数组的地址,因此常量支持修改成员,例如:

1
2
const arr1 = []
arr1.push(1)

关键词let声明局部变量,同作用域不支持同名变量。

关键词var声明全局变量,无论在代码何处声明,其声明都在所有代码之前。但赋值操作还是保留原位置,推荐使用let替代声明变量。

typeof可以返回变量的类型。

运算符

算术运算符

与其他语言基本运算符一致。

特别的是对==!=做了扩充,两等只判断值是否相等。===!==不仅仅判断值是否相等,同时要判断类型是否相等。比如:

1
2
3
4
5
6
7
const str = '3.14'
const num = 3.14
console.log(`str == num : ${str == num}`)
console.log(`str === num : ${str === num}`)

// str == num : true
// str === num : false

运算优先级

优先级运算符说明
1( )
2++ -- !
3* / % + -+-优先级较低
4> >= < <=
5== != === !==
6&& ||||优先级较低
7=
8,

逻辑中断

原理是表达式逻辑判断时,遇到局部值时确定表达式返回值时会直接返回,此时局部值为表达式值。

或逻辑

A||B,A为真则为A,否则为B。适用于变量赋值A是表达式,B是默认值。

与逻辑

A&&B,A为假则为A,否则为B。

控制语句

与其他语言类似:if for while

函数

普通函数

支持将声明放在作用域尾部。

声明方式

function 函数名(参数列表){函数逻辑}

调用方式

匿名函数

使用方式

作为函数参数

function (参数列表) {}

作为函数变量

let fun1 = function (参数列表) {}

调用方式

(function (参数列表) {})()

(function (参数列表) {}())

箭头函数Arrow function

与普通函数不同点是,箭头函数没有自己的thisarguments动态参数,只能使用剩余参数。

基本格式:()=>{}

省略规则

  • 只有一个形参可以省略()x=>{}
  • 只有一行代码可以省略大括号,此时return需要省略
  • 只有一行返回对象时需要加()=> ({uname:uname})

可变参数

arguments,函数属性,动态参数,是伪数组

...xxx,剩余参数,是真数组

DOM

文档对象模型(DOM,Document Object Model)是一组API,用于操作网页元素。在js中以树状结构组成,通过操作各对象(树节点)的属性和HTML结构。

document

document.documentElement HTML的根节点

基本操作

对象属性

元素内容顶部到它的视口可见内容的顶部的距离

scrollTop 顶部的距离

scrollLeft 左边的距离

元素布局尺寸,包含padding border

offsetWidth 宽度

offsetHeight 高度

元素布局位置,受父级元素定位影响

offsetLeft 元素左边相对父级元素的位置

offsetTop 元素顶部相对父级元素的位置

children 返回仅元素节点的伪数组

nextElementSibling 返回下一兄弟节点

previousElementSibling 返回上以兄弟节点

对象方法

getBoundingClientRect 返回元素的大小及其相对于视口的位置

parentNode 返回父级节点

childNodes 返回所有子节点,包括文本、注释

appendChild 在子节点列表增加节点

insertBefore 在子节点列表参考节点前插入节点

cloneNode 克隆对象,默认false不克隆子节点

removeChild 删除子节点

获取对象

获取第一个元素querySelector('css选择器')

返回所有匹配的元素querySelectorAll('css选择器')

css选择器简单回忆

  • 选择指定类class='active'.active
  • 选择特定标签divdiv
  • 选择特定子级标签<div><p class='active'><i></i></p></div>: div i
  • 选择特定亲子级标签<div><p class='active'></p></div>: div>.active
  • 选择特定序号子级标签<div><p class='active'></p><p></p><p></p></div>: div p:nth-child(2)

修改对象

修改元素内容

innerText 不会解析子标签

innerHTML 会解析子标签

修改元素的对象属性

href 跳转地址

title 标题

src 图片源

修改元素样式


直接修改style属性。需要注意,使用下划线的要改为小驼峰方式,没有自动补全。

基本格式

对象.style.样式属性 = 值

优点

  • 适合小范围样式调整
  • 行内样式,权重很高

通过className操作css

基本格式

对象.className = '类名或列表(空格分隔)'

优点

  • 直接替换旧值

:thumbsup:通过classList控制css

注意,类名不能加英文.

基本格式

  • 追加,对象.classList.add('类名')
  • 删除,对象.classList.remove('类名')
  • 切换,对象.classList.toggle('类名')

优点

  • 小范围批量更改样式,旧样式不受影响

操作表单属性

基本格式

表单.value = 值

表单.type = 类型值

部分表单属性使用布尔值表示,例如:disabled checked selected

标签支持自定义属性,自定义属性在HTML中以data-自定义属性名格式最为名称。js需要获取自定义属性时,使用对象.dataset.自定义属性名

Date对象

新建

new Date()

new Date('2022-5-1 8:30')

方法

getFullYear() 获取年份

getMonth() 获取月份,0代表1月

getDate() 返回月份中的天

getDay() 获取星期,0代表星期天

getHours() 获取小时数

getMinutes() 获取分钟数

getSeconds() 获取秒数

获取毫秒时间戳

new Date().getTime()

+new Date()

Date.now()

Document对象

对象属性

document.documentElement.scrollTop = Y

对象方法

write 向文档中写入数据

createElement 创建特定元素节点

Console对象

console.log

事件

基本概念

简介

在系统内发生的动作或事情。要产生事件并完成处理,需要

  • 事件源,即dom对象
  • 事件类型
  • 事件处理函数

事件监听经历多个版本。

DOM L0

基本格式为:对象.on事件类型 = 处理函数

不支持对同一事件多次绑定。

:thumbsup:DOM L2

基本格式:对象.addEventLisener('事件类型', 处理函数)

支持对同一事件多次绑定,推荐使用。

事件流

指事件完整执行的流动路径。

addEventListener第三个参数为是否在捕获阶段触发,默认为false为冒泡阶段。

事件流主要两个阶段:

  • 捕获阶段,Document->Element html->Element body->Element div
  • 冒泡阶段,Element div->Element body->Element html->Document

阻止事件流(事件冒泡)

事件对象.stopPropagation()

事件委托

减少注册次数,提高程序性能。

利用冒泡的特点来完成。

通过父级元素来处理多个子级元素的事件。

基本操作

事件绑定

基本格式:对象.addEventLisener('事件类型', 处理函数)

其中,事件类型见下面的章节。

处理函数可以带参数,第一个参数为Event对象,一般参数命名为evente

Event对象重要属性

  • target 实际出发事件的对象
  • type 事件类型
  • clientX/Y 光标相对浏览器的位置
  • offsetX/Y 光标相对DOM对象的位置
  • key 用户按下键盘值(‘Enter’ ‘a’ ‘A’)

普通处理函数中,this会指向target

事件解绑

L0 对象.on事件类型 = null

L2 对象.removeEventListener(事件类型,回调函数,关键参数)

需要注意的是,L2绑定的方式不支持匿名解绑。

事件类型

鼠标事件

  • click 鼠标点击:thumbsup:
  • mouseenter 鼠标进入,没有冒泡效果:thumbsup:
  • mouseleave 鼠标离开,没有冒泡效果:thumbsup:
  • mouseover 鼠标划过,有冒泡效果
  • mouseout 鼠标离开,有冒泡效果

焦点事件

  • focus 获得焦点
  • blur 失去焦点

键盘事件

  • Keydown 按键按下
  • Keyup 按键抬起

文本事件

  • input 用户输入
  • change 内容发生变化

多媒体事件

  • timeupdate 音视频当前播放位置变化
  • loadeddata 音视频当前播放帧加载完毕

页面事件

  • load 等待特定资源加载完毕
  • DOMContentLoaded 等待HTML节点加载完成
  • resize 当页面尺寸发生变化时

触摸屏事件

  • touchstart 触摸开始
  • touchmove 触摸后并发生移动
  • touchend 触摸结束

BOM

基本结构

window对象作为根节点,包含如下节点对象:

  • navigator
  • location
  • document
  • history
  • screen

Window对象

对象属性

window.scrollTo(X,Y)

定时器

时间到时触发回调函数,并自动开启下次定时

setInterval 开启定时器

clearInterval 关闭定时器

输入

弹出输入框

prompt(消息,默认值)

输出

弹出警告框

alert(消息)

定时器-延时函数

时间到后出发回调函数,不会自动开启下次定时

  • setTimeout 设置定时器
  • clearTimeout 删除定时器

本地存储

数据存储在用户浏览器中。设置、读取方便、甚至页面刷新不丢失数据。容量较大,sessionStoragelocalStorage大约可以存储5M大小的数据。

所有方法都支持KV方式存储。

localStorage

数据生命周期没有过期时间,直到用户主动清理。

实例方法

setItem 存储值

getItem 读取值

sessionStorage

用法同localStorage,生命周期与浏览器窗口一致。同一页面数据共享。

复杂数据类型处理

核心是将对象转换为json字符串

JSON.stringify 将对象序列化为json字符串

JSON.parsejson字符串反序列化为对象

Location对象

对象属性

href 直接跳转到指定的网页 search 返回地址中?开始的参数 hash 返回#开始的哈希值

对象方法

reload 刷新页面

对象属性

userAgent 检测浏览器信息,可以用于检测客户端平台

History对象

对象方法

back 网页后退 forward 网页前进 go 网页前进或后退

JS执行机制

最大特点为单线程。所有任务需要排队执行。任务可以分为两种:

  • 同步任务。在主线程上执行,形成执行栈。
  • 异步任务。js的异步任务是通过回调实现的。

执行流程:

  • 先执行执行栈的同步任务。
  • 异步任务放入任务队列中。
  • 执行栈中的所有同步任务执行完,会依次读取任务队列的异步任务,异步任务结束等待状态,进入执行栈,开始执行。

这种机制被称为事件循环(event loop)

特殊技巧

第三方推荐

swiper

触摸滑动插件swiper官网

正则表达式

语法

对象声明:const 变量名 = /表达式/

对象方法

test 返回是否匹配

exec 返回匹配的数组

字符串.replace 是字符串的方法,替换匹配文本

元字符

边界符:^ $

量词:* + ? {n} {n,} {m,n}

字符类:[abc] [a-z] [^abc] .

预定义:\d [0-9] \D [^0-9] \w [A-Za-z0-9_] \W [^A-Za-z0-9_] \s [\t\r\n\v\f] \S [^\t\r\n\v\f]

修饰符

使用格式:/表达式/修饰符

i 不区分大小写

g 全局匹配

参考资料

MDN 正则表达式

在线测试工具

进阶用法

作用域

局部 外部无法访问 var声明的是全局变量

作用域链 优先在当前作用域查找 逐级查找父级作用域直到全局

GC

垃圾回收机制(GC,Garbage Collection)

计数方式 复杂对象都有计数,计数为0则会被回收 无法解决嵌套引用(循环引用) 标记清除法 “无法到达的对象”

闭包

​ 一个函数对周围状态的引用捆绑在一起 ​ 简单理解 ​ 闭包=内层函数+外层函数的变量 ​ 可能会引起内存泄漏

展开符号

​ let arr = [1,2,3] console.log(…arr) ​ 求最值 Math.max(…arr) Math.min(…arr) ​ 合并数组 arr = […arr1, …arr2]

解构赋值

​ 数组解构 ​ 目标是简洁语法和快速为变量赋值 ​ 将数组的单元值快速批量赋值给变量的简洁语法 const [max,min,avg]=[5,1,3] ​ let [a, b] = [1, 2]; [b, a] = [a, b] ​ 剩余参数 const [a,…b] = [1,2,3] ​ 可以设置默认值 const [a=0,b=0]=[] ​ 忽略部分值 const [a,,c] = [1,2,3] ​ 多维数组 const [a,b,[c,d]]=[1,2,[3,4]] ​ 对象解构 ​ const { uname, age } = { uname: ‘pink’, age: 18 } ​ 被赋值的变量与属性名称需要一致 ​ 重命名 const { uname: username, age: userage } = { uname: ‘pink9’, age: 19} ​ 多级对象 const {name,family:{mother,father}}={name:‘佩奇’, family:{mother:‘猪妈妈’,father:‘猪爸爸’}}

拷贝

​ 浅拷贝 ​ 深拷贝 ​ 递归实现 ​ lodash/cloneDeep实现 ​ JSON字符串转换

异常处理

​ 抛异常 throw new Error(‘参数不能为空’) ​ 异常捕获 try{}catch(err){} ​ 异常时也会执行 finally{} ​ 自动启动调试停止处 debugger

改变this

​ 直接调用 fn.call(new_this, arg_list…) ​ 直接调用,参数是数组 fn.apply(new_this [,arg_list…]) ​ 先绑定返回新的函数 fn.bind(new_this)

防抖

​ 原理 ​ 规定时间内,每次触发都会取消上次执行,只执行最后一次动作 ​ 场景 ​搜索框智能搜索 ​ 输入框输入检测 ​ loadash提供防抖处理 ​ 使用setTimeout实现

节流-throttle

​ 原理 ​ 规定时间内,每次触发都会检测上次执行是否完成,只有完成后才会执行新的动作 ​场景 ​ 高频事件 ​ 鼠标移动 ​ 页面尺寸缩放 ​ 滚动条变化 ​ 多媒体播放进度更新 ​ loadash提供节流处理 ​ 使用setTimeout实现

面向对象

对象

​ 创建 ​ 字面量 const obj = {name:’‘} ​ const obj = new Object({name:’‘}) ​ 构造函数 function Good(name){ this.name = name } const obj = new Good(’’) ​ 属性 ​ Good.count = 5 静态属性 ​ 方法 ​ Good.print = function(){…} 静态方法

内置对象

​ Object ​ Object.keys 返回对象所有属性键 ​ Object.values 返回对象所有值 ​Object.assign 对象拷贝(与克隆不一样,没有的值不会覆盖) ​ Array ​ forEach 遍历数组 ​ filter 过滤数组 ​ map 迭代数组 ​ reduce 累加器 ​ 其他常用 ​ join ​ find ​ every ​ some ​ concat ​ sort ​ splice ​ reverse ​ findIndex ​ Array.from 伪数组转为真数组 ​ Number ​ toFixed 设置保留小数位的长度

面向对象

​ 简介 ​ 每个构造函数有prototype原型对象 ​ prototype默认会有constructor属性,指向构造函数 ​ 所有对象实例都有一个属性__proto__指向prototype ​ 浏览器中显示为[[Prototype]] ​ 构造函数和原型对象中的this都指向实例化对象 ​ 手动赋值prototype ​ Star.prototype={ constructor: Star, sing:… dance:… } ​ 继承 ​ 原型继承 Man.prototype = new Person() Man.prototype.constructor = Man ​ 原型链 ​ 原型对象会指向父级? ​ 顶级对象是Object ​ 当访问属性或方法时,优先查找本地,没有再到父级中查找,直到为null ​ instanceof