JS基础
下面是个人从零学习js的简易笔记
Window方法
控制台输出
console.log()
console.error()
console.warn()警告
console.group()
console.groupEnd()分组输出
alert()
document.write()
prompt() 弹出输入框
open(地址) 打开某网页
close()
confirm(‘’) 内容选择框 确定是true,取消是false
数据类型****
number string boolean undefined null
检测方法****
typeof typeof()检测引用数据类型和null只会返回object
n1=Object.prototype.toString.call(x)
n2=n1.split(‘’).[1].slice(0,-1) 准确检测数据类型
转换方法****
String()
.toString() 不包括undefined null
+(隐式转换)
Number()undefined转换为nan
算术运算符(隐式转换)
Boolean()
! !!(隐式转换)
数字方法****
parseInt()针对数字取整
parseFloat()可以识别一位小数
.toFixed(x) 保留x位小数
IsNaN(x) x是否是nan,返回true或者false
分支语句****
switch{
case 值:执行函数语句
break //防止switch穿透
default ://不满足的执行函数语句
}
断点调试****
debugger;;进入
循环****
while循环用在循环次数不确定的情况下
for是确定
break可以跳出循环结构
continue可以跳出本次循环,执行下次循环
函数
四要素:
函数名、函数体、函数参数(实参、形参)、返回值
js代码运行三阶段:
1、预编译:检查基本语法错误
2、预解析:变量提升到作用域顶部
3、执行阶段:从上往下执行代码
作用域链:****
有var变量时重名以局部为主,不会改变全局
没有会一层层向上寻找
arguments对象****
函数调用时在函数内部产生,将函数传入实参以类数组方式接收
函数的闭包****
指可以在一个函数内访问到另一个函数的私有变量,利用了函数执行空间不销毁的原理,即不会被垃圾回收机制gc回收。
函数a返回函数b,函数b被c接收,函数b持续访问a中的私有变量。
优点:1、可以在函数外访问到内部私有变量
2、保护私有变量,不污染全局
3、可以缓存数据,提升代码性能
缺点;容易造成内存泄漏 (将变量赋值为null)
应用:节流、防抖、柯里化
函数柯里化****
将接受多个参数的函数分解成接受单个参数的函数,返回接受余下参数且返回结果的新函数的技术
优点:1、函数复用
2、参数延迟绑定
3、灵活函数组合
4、进行部分应用
函数继承****
原型继承:将子类的原型设为父类new出来的对象
构造函数继承:在子类构造函数中调用父构造函数,只继承属性,原型的东西不继承。Father.call(this,a,b)
组合继承:上面两个结合
寄生式继承
数组****
静态方法****
Array.is Array()是否为数组
Array.from()类数组转换为数组
Array.of()传入的参数转换为数组
动态方法****
.push() 后+
.pop() 后-1
.unshift() 前+
.shift() 前-
.sort() 排序
.reserve() 反向排序
arr.concat(arr1,arr2) 拼接数组
indexOf() 搜索
lastIndexOf()
.toString() 数组整体转为字符串
.join() 通过指定字符将数组拼接成字符串
.slice(start,end) 截取数组指定部分,不包含结束位置
.splice(start,删除的个数) 删除数组指定部分
.forEach((item,索引,数组本身)=>{ }) 遍历
.filter(()=>{}) 过滤
.map(()=>{}) 映射
.find(()=>{}) return返回数组中第一项符合条件的元素
对象****
增查改:对象.key=value
删:delete 对象.key
可以用for in遍历
当key值是变量时,用[]来包含key,不用.
原型方法:****
Object.assign(target,a,b,c)合并多个对象
Object.create(对象) 传入对象,返回空对象,原型为传入对象
对象.hasOwnProperty(key) 检查是否存在key(不包括原型链内)true或false
Object.defineProperty(obj,prop,描述符)
对象属性劫持,用于响应数据到视图层的变化,语法只对被劫持的属性有用,
缺点在于劫持数组时容易造成性能问题
描述符:
configurable:true能直接改变,false不能
enumberable:能否被枚举
value:改变的任意js值
writable:true时可通过赋值运算符改变value
get(){}访问对象成员时调用方法
set(val){}设置对象时调用的方法,val可以接受到被赋的值
Math对象****
Math.PI 圆周率
Math.ceil()向上取整
Math.floor()向下取整
Math.round()四舍五入取整
Math.min()传入的参数取最小
Math.max()传入的参数取最大
Math.pow(num,n)计算num的幂次方
Math.sqrt()根号
Math.abs()绝对值
Math.random()0-1之间的随机数
字符串****
字符串算字符数组,可以按数组方法操作
字符串比较按ascii码进行比较
字符串方法(不会改变原字符)****
.charAt()返回指定索引字符
.charCodeAt()返回指定索引字符的Unicode编码
.indexOf()
.lastIndexOf() 同数组
.toLowerCase()
.toUpperCase()
.substr(开始索引,长度) 对字符串提取
.substring(开始索引,结束索引) 字符串提取
.slice(开始索引,结束索引) 截取字符串
.split() 通过指定字符分割字符串
.replace(‘xx’,’yy’) yy替换xx,只能替换一次
.repeat(num) 复制字符串num次并拼接在一起返回
.trim() 两端删除空白字符
Date
new Date(2000 9 12 02:02:02)
.getFullYear()
.getMonth()
.getDate() 日期
.getDay() 星期几
.getHours()
.getMinutes()
.getSeconds()
.getTime() 时间戳
换成set可以设置时间参数
间隔定时器和延时定时器****
间隔定时器****
setInterval(function(){ 执行的代码 },时间戳)
clearIterval(返回值)参数需要停止的间隔定时器返回值,只是不开启下次,下面代码仍然会执行
延时定时器****
setTimeout(function(){ },时间戳)等待指定时间执行
clearTimeout()
DOM操作****
获取元素****
doucument.getElementByID(‘’)通过id名获取对象 。。。
Doucument.querySelector(‘#box等等’) 获取第一个元素对象,返回对象
Doucument.querySelector(‘#box等等’) 获取元素对象集合,返回类数组
可以用后代选择符一类的选择符
创建、添加、删除、克隆元素****
document.creatElemnt(‘元素名称’)
x.appendChild(插入元素)
x.insertBefore(a,b)把a插入到x里面的b前面
x.removeChild()
x.cloneNode()不传参只克隆自身,传true会加上他的子元素
x.replaceChild(a,b)用b替换a
操作元素(标签)属性****
直接语法:元素对象.属性 class属性要用className(字符串)或者classlist(类数组)
不能获取自定义属性,但这样设置的自定义属性可以获取,设置的自定义属性看不见
x.disabled/x.checked=true/false 可以获取表单控件是否被禁用或选择
完整语法:
x.getAttribute() 直接获取class和自定义属性
x.setAttribute()
x.removeAttribute()
操作元素内容****
元素.innerHTML=XXX 获取、设置元素内容,可以解析标签
元素.innerText=XXX 获取、设置元素文本信息,不能解析标签
元素.value=XXX 针对表单元素
操作元素css样式****
X.style.width=*** 只能获取、设置行内样式,多个单词css属性要写成JS格式(把-去掉,第二个及之后的单词首字母大写)
X.style.cssText=’***’ 获取、设置所有行内样式。
getComputedStyle(元素对象,null/false)[‘css属性’] 获取非行内样式,高版本浏览器
元素.currentStyle[‘css属性名’]
低版本浏览器
Dom节点操作(元素操作)****
元素节点、属性节点、文本节点
nodeType 1 2 3
nodeName 大写标签名 属性名 #text
nodeValue null 属性值 文本内容
方法
x.childNodes 空白子节点和元素子节点
x.children 元素子节点
x.firstChild
x.firstElementChild
x.lastChild
x.lastElementChild
都返回类数组
x.previousElementSibling 前一个兄弟子元素
x.nextElementSibling 后一个兄弟子元素
x.parentNode 父节点
x.attributes 属性节点 返回数组
获取元素布局大小(只获取,不能改)****
x.clientWidth 宽+padding
x.offsetWidth 宽+padding+border
获取元素偏移量****
x.offsetTop/Left
往上找父元素如有定位按父元素计算偏移量,直到body停止
固定定位按浏览器窗口定义
获取浏览器宽高****
document.documentElement.clientWidth/Height
window.innerWidth/Height
前者获得可用的宽高(不包括滚动条)
后者是整体宽高
获取设置浏览器滚动条距离****
Document.documentElement.scrollTOP/Left 滚动条距顶部和左边的距离
设置直接赋值
Event事件类型****
事件源、事件类型、事件处理函数
鼠标事件
onclick ondblclick
onmousedown onmouseup
onmouseover onmouseout
onmousemove
oncontextmenu 右键单击
键盘事件****
只能和document和表单控件绑定
onkeydown
onkeyup
获得键盘按键编码的兼容:e.keycode或者e.which
判断是否有组合按键:e.ctrlkey altkey shiftkey 对应值为true
表单事件****
onsubmit 提交事件
onreset 重置事件
onfocus 获焦事件
onblur 失焦事件
oninput 输入事件
浏览器事件****
默认window
onload 页面加载完后触发
onscroll 浏览器滚动触发
onresize 浏览器窗口改变触发
DOM 0级和2级事件****
DOM 0级事件****
语法:元素对象.事件类型=事件处理函数
同一节点只能绑定同一事件一次,多个前面的会覆盖后面的
取消为赋值为null
DOM 2级事件****
语法:
对象.addEventListener(事件类型(不加on),事件处理函数(移除时要加函数名),true(捕获)/false(默认冒泡))
同一节点可以绑定同一事件多次,按顺序执行
移除:对象.removeEventListener(参数同上)
低版本浏览器
对象.attacEvent(事件类型,函数)
对象.detachEvent(事件类型,函数名)
事件流****
指有层级关系的元素,子元素触发事件,父元素也会触发相同的事件。
三个阶段:捕获阶段、目标阶段、冒泡阶段
事件对象相关****
获取对象兼容:e=ev||window.event
阻止事件对象冒泡:e.stopPropagation或者e.cancleBubble=true
事件委托****
将子元素触发的事件委托给父元素触发。(动态添加的元素触发不了事件)
优点:1、精确控制函数2、节省性能,操作方便3、在处理异步问题时可不用考虑先后问题
e.target或者e.srcElement获得目标
判断nodename是否与对应元素名称相等
鼠标位置****
screenx/y 相对于屏幕
offsetx/y 元素边框内 闪回可以用point-event:none
clientx/y 浏览器窗口
pagex/y 网页
浏览器默认行为****
右键菜单、图片拖拽、a标签跳转
阻止:e.preventDefault或者e.returnValue=false
改变doc注释****
选中函数名+参数
ctrl+shift+p
输入genjsdoc并选择
this
this是关键字,是一个指向,全局指向window,函数中指向调用者
window:全局、普通函数、定时器、自执行函数
方法所属对象:对象方法
事件处理函数:事件源
改变this指向
.call(a,b,c)
.apply(a,[b,c,d])
.bind(a,b,c) 不会立即执行,而是返回一个改变了this的函数
ES6****
let、const****
不存在变量提升,不允许重复声明,会被所在作用域限制范围(具有暂时性死区)
let声明变量,可改变,不用立即赋值。const相反
箭头函数****
只能定义赋值型函数
自身没有this也不能改变this,在里面使用的this指向函数所在环境的this
自身没有arguments,要接收使用...运算符
形参只有一个可以不写括号,函数体只有一行可不写{},会自动return
函数参数默认值****
形参=num
对象简写****
value有变量储值可以直接写入
方法可以省略 :function
模板字符串****
可以换行,${变量}
展开运算符...****
对于对象数组以参数序列的方式展开
用于合并数组,函数传递参数,转换类数组为真数组
解构赋值****
快速取出数组对象成员
[a,b,c=10]=arr
{key}=obj
symbol****
新增数据类型,表示独一无二的值,只和自身一样
Set、Map数据结构
new Set()新增引用数据类型,成员值是唯一的,可以利用来数组去重
map是新增引用数据类型,类似对象,他的key值可以是任意数据类型
for...of循环****
新增循环,遍历具有iterator接口的对象(数组、set、map)
不能遍历对象
循环数组变量代表数组值
class类
本质还是构造函数
动态成员:类实例化才能用的成员,里面的constructor相当于构造函数,
在外面增加直接定义,属性不能直接传参赋值
静态成员:和函数一起生成,通过类名访问,定义时在前面加上 static
继承****
优点:减少重复性逻辑编写,复用代码逻辑
语法:class x extends y{
constructor(a,b,c){
super(a,b,c) 相当于调用父元素构造器
}}
Proxy****
弥补不能劫持数组的缺点,是构造函数
语法:
proxy=new Proxy(对象,{get(对象,形参(劫持属性)){return 对象[形参]}})
访问函数被劫持属性时调用的函数,返回值为属性值
set(obj,prop,val){obj[prop]=val return true表示设置成功}
修改劫持属性时调用的函数,
禁止修改在set里面throw new Error()
禁止删除deleteProperty(throw new Error())
数据绑定****
在set设置函数接受改变的属性值
Promise****
通过链式调用的方式解决回调函数的回调地狱问题
状态:pending、fullfilled、rejected
状态确定后无法更改
x=new Promise((resolve,reject)=>{})
前一个是成功调用,后一个失败
x.then(函数)形参会接受到resolve的传来的参数
x.catch(函数)形参会接受到reject的传来的参数
x.finally(函数)无论成功失败都调用这个函数
这三个是原型上的方法
静态方法****
Promise.resolve()调用成功回调
Promise.reject()失败回调
Promise.all(数组)发送多个请求,全部成功才算成功,调用then
Promise.any(数组)全失败才调用catch
Promise.race(数组)无论成败,取最快的返回结果调用then
Promise.allSettled(数组)无论成败结果都调用then,返回数组,里面是对象和传送的参数
async/await****
将函数定义成异步函数,配合await使用(后面必须是promise对象)
async function xx(){
let a=await promise对象
a接受结果,取代then的回调过程
}
Fetch
基于promise方式处理,是异步操作请求
fetch(地址,对象).then(res=>res.Json()// 需要return,变换为json文件).then(data=>{}//data为请求的数据)
第二个参数
method:get/post
headers:{‘content-type’:’application/json’}
body:{key:value} post方法使用
模块化
使用时script标签要加type=’module’
export default 变量或对象(只能导出一次)
import xxx from 路径
export let x=abc 可以导出多个
import {x} from 路径
import * as x from 路径 接受所有这样导出的文件
spa单页面路由****
只有一张页面的应用,所有的交互更新都在一张页面上完成
优点:
1、用户体验好,快,更新不需要重新加载页面
2、具有桌面应用的即时性、网站的可移植性和可访问性
3、前后端分离,分工明确
缺点:
首屏加载过慢可以用路由懒加载处理
不利于搜索引擎的抓取
Location.hash 获取和设置锚点
onhashchange事件 hash值改变时触发事件
组件化-模块化方法****
配置组件,设置函数并exports出来
配置路由表,导入组件
主js文件设置onhashchange函数,获取hash值并去除#
导入的路由表内如有符合的hash值则调用相应函数
设置重定向即为默认渲染
路由懒加载方法****
路由表内函数写入导入组件
同样判断hash值,在主js文件中调用函数得到promise对象,调用then方法
然后res调用default方法
面向对象编程****
封装、多态、继承
自定义函数创造对象
new person() 中this指向实例对象,不传参可以省略括号
原型****
本质是一个对象,可以存储属性和方法,减少内存的消耗
原型链****
new对象发生了什么****
1、开辟空间,创造对象
2、绑定this指向创造的实例
3、执行构造函数的代码,添加成员
4、将实例的constructor指向构造函数
5、实例的__proto__指向构造函数的原型
6、如没新的返回值,返回new构建的对象
正则****
检测字符串是否满足某种规则
new RegExp() 或者 / /
中文可以转成unicode编码
元字符****
. 匹配非换行的任意字符
\ 可以反转有无意义
\s 空白字符
\S 非空白字符
\d 数字
\D 非数字
\w 数字、字母、下划线
\W 非数字。。。。
边界符****
^ 开头
$ 结尾
限定符****
- 前一个重复0~无穷
- 1~无穷
?0~1次
{n} 重复n次
{n,} 至少重复n次
{n,m} 重复n~m次
特殊符号****
[ ] 字符合集,写在其中的任意一个都可以,算一个字符
- 范围
[^ ] 写在其中的任意一个都不可以
| 或者
()限定一组元素
修饰符****
i 忽略大小写
g 全局匹配
方法
正则.test(字符串) 满足正则表达式的规则
正则.exec(字符串) 捕获字符串符号满足正则的内容
字符串.search(正则) 搜索第一个满足正则的地方,返回索引
字符串.match(正则) 无g和exec一样,有g返回一个数组(符合规则的每一项)
字符串.replace(正则,替换的字符) 加g全部替换,不加换一个
Json数据格式****
本质是字符串
正反序列化
JSON.parse()json转为js对象
JSON.stringify()js对象转为json
json文件不用加单引号包括
BOM操作****
屏幕对象 screen****
Screen.width/height 屏幕宽高
Screen.availWidth/Height 有效宽高(除任务栏)
浏览器信息对象 navigator****
appname
appversion
platform
cookieEnabled
userAgent 获取是什么浏览器
地址栏对象 location****
location.href= 地址栏信息 可以设置跳转
.reload() 刷新网页
.search ?及之后的内容地址栏地址的参数信息
浏览器历史对象 history****
.length 历史记录个数
.forward()
.back()
.go(num)
深浅拷贝****
浅拷贝指在拷贝对象时只拷贝对象的第一层,对象深层的只拷贝引用地址
方法:for...in 展开运算符 数组原型方法:slice concat Object.assign
深拷贝会创造新对象并递归复制所有原始对象和嵌套对象数组,两者相互独立
方法:Json的正反序列化 缺点:1、函数和正则等特殊值无法复制 2、无法处理循环引用的情况 3、性能不好
第三方lodash实现
递归创建
事件轮询机制****
事件队列、消息循环、事件循环
内存出入栈:先进后出
事件队列:先进先出
设计模式****
单例模式****
1、确保一个类只有一个实例
2、提供全局访问点访问实例
3、延迟实例化
4、允许对实例操作
es5逻辑是创建自执行函数,定义一个私有变量,返回另一个函数,并把要的到的结果保存在变量中,如果实例在函数中已经存在,则不计算,返回存在的结果,若不存在则保存后并返回。
es6逻辑是创建class类,定义静态属性存储实例,如果存在则返回,不存在则存储并返回。也可以定义一个函数用来更新dom。
观察者、发布订阅模式****
后者比前者多一个事件处理中心,可以对发布者和订阅者解耦合,前者点对点,后者一对多。
定义构造函数,用变量存储订阅者和回调函数,定义三个方法分别为订阅、发布、删除。
AJAX
前后端交互技术,快速创建动态网页技术,可以实现局部更新,异步操作。
核心;XMLHttpRequest对象
优劣:
1、不需要插件,原生JS即可使用
2、只更新局部,不要刷新网页
3、它是异步无阻塞
1、流程多,编写麻烦
请求方式get和post的区别****
1、post比get更安全,但响应会更慢
2、post可以传递任意类型数据且没有字数限制,get只能传递字符串,长度被浏览器限制
3、get会被浏览器主动缓存,post不会
4、get请求通过?拼接到请求地址后,再拼接参数=值,多个以&连接。
5、post携带参数放在send里面并转为Json数据,格式与get一样,还要设置请求头setRequestHeader(‘content-type’,’application/json’)
语法
1、xhr=new XMLHttpRequest()
2、xhr.open(方式,请求地址,true异同)
3、监听ajax状态
xhr.onreadystatechange=function(){
readyState为4且status为200视为请求成功
获得responseText(请求的数据)
}
或者
xhr.onload=function(){
status为200请求成功
操作responseText
}
xhr.onerror=函数
请求失败
4、xhr.send()发送请求
通信协议****
http事务****
1、域名解析
2、发起http三次握手
3、建立tcp连接,发起http请求
4、服务器响应http请求,浏览器得到html代码
5、解析代码,请求代码资源并渲染
6、断开连接
三次握手****
1、建立连接时,客户端发送syn报文(包)(同步序列号)到服务器,并进入SYN_SEND状态,等待服务器确认
2、服务器收到syn报文,必须确认客户端的syn报文,同时自己也发送一个SYN报文,即SYN+ACK(确认序列),此时服务器进入SYN_RECV状态
3、客户端收到服务器的SYN+ACK报文,向服务器发送确认报文ACK,此包发送完毕,客户端)和服务器进入ESTABLISHED状态,完成三次握手。
常见http状态码****
200 成功
304 资源重定向
404 无法找到请求的资源
cookie和h5本地存储****
document.cookie 设置、查看、删除都用这个,删除就是设置过期时间到过去
cookie 大小约为4kb,数量为50条,会话级别但可以设置过期时间,可以在同域名页面共享
localstorage 大小约为4m,周期为永久,可以在同源页面共享
sessionstorage 大小约为4m,周期为会话,只能在当前页面查看
方法
Localstorage/sessionstorage.setItem(key,value)
.getItem(key)
.removeItem(key)
.clear()
跨域****
浏览器同源策略是浏览器的安全策略,同协议、同域名、同端口有一个不满足既是跨域。 localhost=127.0.0.1
解决方法:
1、浏览器插件
2、后端设置允许跨域 ‘Access-Control-Allow-Origin’:’*’
3、jsonp解决
src属性不受同源策略影响,需要后端加上回调函数cb=函数
4、proxy代理
EventLoop事件循环****
同步任务会进入主线程,异步任务会进入任务队列,在执行完主线程后会执行任务队列任务推进主线程进行,这样的不断循环就是事件循环。
微任务:promise
宏任务:定时器、script代码