js基础知识笔记记录
js基本常识
-
var num=100。num是变量名 严格区分大小写:美元、字母、_、数字。不能使用数字开头。
-
- alert(num)//在浏览器弹窗显示num变量的值。
- console.log(num) //在控制台打印num的值。
- document.write(num) //最直接在页面输出num的值。
数据类型转换
- Number()类型转换 :转化为数值类型。
- parseInt() :把转换的结果从头开始查看,当遇到不是数字时就停止转换。
- parseFloat() 同上,但是这个可以转化到小数点之后。
- 转化为字符串String()。
- toString
var n=100
console.log(n)
//类型检测typeof
var result=typeof n
console.log(result)
对象数据类型
对象包含属性和方法,js中一切皆可对象
// obj是对象,obj.a是属性,100是属性值
var obj={a:100,
b:true,
c:'hello world'
}
//增的两种方法
obj.name='小灰狼'
obj['age']=18
//删
delete obj.name
数组常用的方法
- arr.push(**)在最后添加元素,返回值是数组长度
- **arr.pop()**删除末尾的值,返回值是删除的值
- arr.unshift(**)把数据添加到数组的最前面,返回值是数组的长度
- **arr.shift()**删除数组最前一个数据,返回值是被删除的数据
- **arr.reverse()**将数组反转,返回值是反转后的数据
- arr.splice(开始索引,多少个,在删除的位置插入的数据)从0开始。删除数组中若干数据,并选择是否插入新的数据。返回值以新数组的形式返回被删除的元素
*** arr.sort(函数)** 数组排序。返回值是排序结果。sort() 方法比较两个值时,将值发送给比较函数,根据返回的(负、零、正)值对值进行排序 - arr.join(**) 将数组用连接符连接成为一个字符串。返回值是连接好的字符串
- arr.concat(**)将其他数组和数组拼接在一起。返回值是合并好的数组
- **arr.slice(开始索引,结束索引)**默认开始为0,长度为lenth。作用截取数组中的某些数据。返回值以新数组的形式返回截取出来的数据。slice()包含前面的数据,不包含后面的数据
- arr.indexOf(数据) 作用:查找数据在数组中的索引位置。返回值:有该数据,返回第一次出现的索引位置,如果没有,则返回-1
- forEach(function(item,index,arr){}) 作用:遍历数组 返回值:无
- map(function(item,index,arr){})作用:映射函数。返回值:映射后的函数
- filter(function(item,index,az){}) 过滤数组。返回值:过滤后的数组
- every(function(item,index,az){}) 作用:判断是不是每一项都满足条件。返回值是布尔值
- some(function(item,index,az){}) 作用:判断是不是有某一项满足条件。返回值是布尔值
字符串常用方法
- 字符串.chartAt(索引) 作用:获取对应索引位置的字符。返回值:对应索引位置的字符
- 字符串.tolowerCase() 把大写全部转化为小写
- 字符串.toUpperCase()把小写全部转化为大写
- 字符串.replace(换下内容,换上内容)
- 字符串.trim() 作用:去除字符串首尾的空格。返回值:去除空格后的字符串
- 字符串.split(分隔符) 作用:按照分隔符将字符串切割成为一个数组。返回值:切割后的数组
- 7.substr(开始索引,多少个)
- 8.substring(开始索引,结束索引)
- 9.slice(开始索引,结束索引)。三个都是截取字符串。返回值:截取出来的字符串(包前不包后)
数字常用方法
1.Math.random() 作用:获取0-1之间的随机小数,包含0但不包含1
2.Math.round(数字) 作用:对数字进行四舍五入。
3.Math.ceil(数字) 作用:对数字进行向上取整
4.Math.floor(数字) 作用:对数字进行向下取整
5.Math.pow(底数,指数) 作用:对数字进行取幂运算
6.Math.sqrt(数字) 作用:对数字进行二次方运算
7.Math.abs(数字) 作用:对数字进行绝对值运算
8.Math.max(*,**,**,...) 作用:获取若干数字的最大值
9.Math.min(*,**,**,...) 作用:获取若干数字的最小值
10.Math.PI 作用:获取到近似π的值
时间常用方法
var time=new Date()
var time =new Date(年,月,日,时,分,秒) 0表示1月,11表示12月
console.log(time)
获取时间的方法
时间对象.getFullYear() 获取到时间对象中的年份信息
.getMonth() 获取月份信息
.getDate() 获取时间的日期信息
.getHours() 获取小时信息
.getMinutes() 获取分钟信息
.getSeconds() 获取秒信息
.getDay() 获取时间对象中的星期信息 0表示周日,1-6表示周一到周六
.getTime() 获取时间戳信息
设置时间的方法
时间对象.setFullYear(对应的数字) 设置时间对象中的年份信息
.setMonth(对应的数字) 设置月份信息
.setDate(对应的数字) 设置时间的日期信息
.setHours(对应的数字) 设置小时信息
.setMinutes(对应的数字) 设置分钟信息
.setSeconds(对应的数字) 设置秒信息
.setTime(对应的数字) 设置时间戳信息
BOM操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
width: 3000px;
height: 3000px;
}
</style>
</head>
<body>
<button id="on">开启</button>
<button id="off">关闭</button>
<button id="go">走你</button>
<script>
//1.获取浏览器窗口尺寸
//获取可视窗口宽度:window.innerWidth
//获取可视窗口高度:window.innerHeight
var w=window.innerWidth
var h=window.innerHeight
console.log(w)
console.log(h)
//2.浏览器的弹出层
//提示框:window.alert('提示信息')
//询问框:window.confirm('提示信息')
//输入框:window.prompt('提示信息')
//3.开启和关闭标签页
//开启:window.open('地址')
//关闭:window.close()
on.onclick=function(){
window.open('http://www.baidu.com')
}
off.onclick=function(){
window.close()
}
//4.浏览器常见事件
//资源加载完毕:window.οnlοad=function(){}
//可是尺寸改变:window.οnresize=function(){}
//滚动条位置改变:window.οnscrοll=function(){}
//5.浏览器的历史纪录操作
//回退页面:window.history.back()
//前进页面:window.histroy.forward()
//6.浏览器卷去的尺寸
//卷去的高度:document.documentElement.scrollTop 。有<!DOCTYPE html>时使用这个
// document.body.scrollTop 。没有<!DOCTYPE html>时使用
window.onscroll=function(){
//console.log(document.documentElement.scrollTop)
var height=document.documentElement.scrollTop || document.body.scrollTop
console.log(height)
}
//卷去的高度:document.documentElement.scrollLeft 。有<!DOCTYPE html>时使用这个
// document.body.scrollLeft 。没有<!DOCTYPE html>时使用
window.onscroll=function(){
var width1=document.documentElement.scrollLeft || document.body.scrollLeft
console.log(width1)
}
//7.浏览器滚动到:window.scrollTo(浏览器卷去的宽度,浏览器卷去的高度) 瞬移
// 或者慢慢滚动window.scrollTo({ left:**, top:**,behavior:'smooth'})
go.onclick=function(){
//indow.scrollTo(300,400)
window.scrollTo({ left:300, top:500 ,behavior:'smooth'})
}
</script>
</body>
</html>
- 定时器
<script>
//间隔定时器:setInterval(函数,时间) 函数:每次要执行的内容。时间:单位是毫秒
var time1= setInterval(function(){
console.log('间隔定时器')
},1000)
//延时定时器:setTimeout(函数,时间)
var time2= setTimeout(function(){
console.log('延时定时器')
},3000)
//定时器的返回值。作用:方便关闭定时器
/*console.log('time1',time1)
console.log('time2',time2)*/
//关闭定时器
// 语法一:clearInterval(要关闭的定时器返回值)
// 语法二:clearTimeout(要关闭的定时器返回值)
g.onclick=function(){
clearTimeout(time1)
clearTimeout(time2)
}
</script>
DOM操作
<body>
<div>000</div>
<div class="box"></div>
<div class="box con"></div>
<div class="b" id="c"></div>
<script>
//1.根据id document.getElementById('id名称')。没有对应元素null
var ele=document.getElementById('c');
console.log(ele);
/*2.根据元素的类名 document.getElementsByClassName('元素类名')
作用:获取文档流中所有类名对应的元素。返回值:是一个伪数组*/
var eles= document.getElementsByClassName('box')
console.log(eles)
/*3.根据元素的标签名 document.getElementsByTagName('标签名')
作用:获取文档流中所有标签名对应的元素。
*/
var a=document.getElementsByTagName('div')
console.log(a)
/*4.根据选择器获取一个 document.querySelector('选择器')
作用:获取文档流中满足选择器规则的第一个元素
返回值:如果有选择器对应的元素,获取到第一个,没有则null
*/
var b=document.querySelector('.box')//或('div'),('#c')
console.log(b)
//5.根据选择器获取一组 document.querySelectorAll('选择器')
var c=document.querySelectorAll('.box')//或('div'),('#c')
console.log(c)
</script>
</body>
<div>
<p>div内部的p标签</p>
</div>
<script>
/*创建节点 语法一:document.createElement('标签名称') 作用:创建一个指定标签元素。返回值:一个创建好的元素节点
*/
//创建div
var div = document.createElement('div')
console.log(div)
/*插入节点 语法一:父节点.appendChild(子节点) 作用:把子节点放在父节点的内部,并且放在最后的位置
语法二:父节点.insertBefore(要插入的子节点,哪一个子节点前面) 作用:把子节点放在父节点的内部,并且放在指定某一个子节点的前面
*/
var span = document.createElement('span')
span.innerText = '这是创建出来的span标签'
console.log(span)
var div = document.querySelector('div')
var p = document.querySelector('p')
// div.appendChild(span)
//创建的span放在了p的前面
div.insertBefore(span, p)
/*删除节点 语法一:父节点.removeChild(子节点) 作用:从父节点内删除某一个子节点
语法二:节点.remove() 作用:把自己删除
div.removeChild(span)
p.remove()
*/
/*替换节点 父节点.replaceChild(换上节点,换下节点) 作用:在父节点内,使用换上节点替换掉换下节点
var i=document.createElement('i')
i.innerText='替换节点的i'
div.replaceChild(i, p)
*/
//克隆节点 节点.cloneNode(是否克隆后代节点false或者true) 作用:把该节点复制一份一摸一样的内容
var clone1 = div.cloneNode(false)
var clone2 = div.cloneNode(true)
console.log('不克隆后代节点',clone1)
console.log('克隆后代节点',clone2)
/*获取元素尺寸: 语法一:元素.offsetHeight
元素.offsetWidth 获取:元素 内容+padding + border 区域的尺寸
语法二:元素.clientHeight
元素.clientWidth 获取:元素 内容 + padding 区域的尺寸
*/
事件
/* 事件绑定三要素:1.事件源:和谁做好约定
2.事件类型:约定一个什么行为
3.事件处理函数:当用户出发该行为的时候,执行什么代码
语法:事件源.on事件类型=事件处理函数
事件类型
*/
var div=document.querySelector('div')
div.onclick=function(){
console.log('你好啊')
}
/* 鼠标事件
1.offsetX和offsetY 相对于触发事件的元素
2.client和clientY 相对于浏览器可视窗口的文字
3.pageX和pageY 相对于页面文档流
键盘事件
键盘编码 事件对象.keyCode
*/
原型
原型解决的问题:当需要给实例对象添加方法,直接书写在函数体内,这一行为并不好,原型就是解决这个问题的
不好的原因:当我们把方法写在构造函数体内。每次创建实例的时候,都会创建一个函数数据类型,多个函数方法一模一样,因此占据了多分存储空间
解决问题:原型
- 原型-prototype
- 定义:每一个构造函数天生自带一个属性,叫prototype,是一个对象数据类型。
- 每一个对象天生自带一个属性
__proto__
,指向所属构造函数的prototype。 - 因此我们可以在prototype中添加他们共同的属性。
- 我们可以吧需要添加给实例的方法,放在后遭函数的原型prototype上,这样就可以有实例直接访问
function Person(){}
Person.peototype.a=100
Person.peototype.b=200
console.log(Person.prototype)
// 创建一个实例对象
var p1 = new Person()
console.log(p1.__proto__ === Person.prototype)
console.log(p1.__proto__)
// 当你访问p1的a成员,如果person没有,就会自动到自己的__proto__上查找,又因为__proto__ === Person.prototype
console.log(p1,a)
原型链
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kdT4bBA7-1646898017321)(…/0.零碎知识/img/原型链.png)]
- 实例对象身上的__proto__指向谁?
- 执行所属的构造函数的prototype
- p1所属的构造函数是Person
- p1.__proto__指向Person.prototype
- Person.prototype的__proto__指向谁?
- Person.prototype是一个对象数据类型(object)
- JS内所有的object数据类型都属于object这个内置构造函数
- 索引Person.prototype的
__proto__
指向object.prototype
- Person的__proto__指向谁?
- Person是一个函数,函数本身也是一个对象,就会有
__proto__
- 在js内,所有的含糊都属于内置构造函数Function的实例
3.Person.__proto__
指向Function.prototype
- Person是一个函数,函数本身也是一个对象,就会有
- object.prototype的__proto__指向谁?
- Object.prototype在js内叫做顶级原型,没有
__proto__
- Object.prototype在js内叫做顶级原型,没有
- Object的__proto__指向谁?
Object.__proto__
指向Function.prototype
- Function.prototype的__proto__指向谁?
- Function.prototype的
__proto__
指向Object.prototype
- Function.prototype的
- Function的__proto__指向谁?
- Function的
__proto__
指向谁自己
- Function的
Function自己是自己的构造函数,自己是自己的实例
原型链:用__proto__串联起来的对象链状结构
对象访问机制:当需要访问成员的时候,首先在自己身上查找,如果没有就自动去__proto__上查找
const let var
- const:用来定义常量
- let与var区别是:let的作用域{}
- var的作用域被规定为一个函数作用域,而let则被规定为块作用域
箭头函数
箭头函数的特殊之处
- 箭头函数某些时候可以省略 ()
=> 当你的形参只有一个的时候, 可以不写 () - 箭头函数某些时候可以省略 {}
=> 当你的代码只有一句话的时候, 可以不写 {}
=> 并且会自动把这一句话的结果当做函数的返回值 - 箭头函数内没有 arguments
arguments 是一个对应于传递给函数的参数的类数组对象。 - 箭头函数内没有 this
=> 箭头函数内的 this 就是外部作用域的 this
jQuery筛选器
/*
当引入jQuery文件以后 使用$或者jQuery都可
*/
console.log($)
console.log(jQuery)
//注意:不管使用任何选择器,获取到的元素都是一个元素的集合
//$('**')
//id选择器
console.log($('#box'))
//类名选择器
console.log($('.a'))
//标签名选择器
console.log($('li'))
//结构选择器
console.log($('li:nth-child(odd)'))
console.log($('li:nth-child(even)'))
console.log('****************************')
/*
筛选器
*/
//1.first
console.log($('li').first())
//2.last
console.log($('li').last())
//3.eq(索引) 索引是从0开始,以此+1
console.log($('li').eq(3))
//4.next() nextAll()
console.log($('span').next())
//6.prev() prevAll()
console.log($('span').prev())
console.log($('span').prevAll())
//8.parent() 拿到的是父元素
console.log(8, $('span').parent())
//9.parents() 获取的是该元素的所有父级元素,逐层获取,直到html标签为止
console.log($('span').parents())
//10.siglings() 拿到该元素的所有兄弟元素
console.log($('span').siblings())
//11.find(选择器) 找到该元素的所有后代元素中满足选择器要求的元素
console.log($('ul').find('i'))
js 面试视频
如何理解this关键字?
- 全局环境输出this? 指向全局对象
- 全局函数输出this? 指向全局对象
- 对象的方法输出this? 指向调用这个方法的对象
- Dom事件输出this?指向Dom对象
- 构造函数中this?指向new创建的对象
- new关键字做了什么? 用来创建对象
- j箭头函数中this?
- 普通函数:谁调用指向谁,箭头函数:在哪里定义指向谁
- 箭头函数外指向谁就指向谁。
- 箭头函数中没有this
call/apply/bind基本语法
- call:是一种方法,函数的方法
- call可以调用函数,call可以改变函数中的this,让this指向call()括号里面。
- 区别:他们都是绑定 this 的,但是
- bind 返回函数
- call/apply 直接执行函数
function fun(){
console.log(this.name)
}
let cat={
name:'喵喵'
}
fun.call(cat)// 这是函数的中this指向cat
let dog={
name:'汪汪',
sayName(){
console.log('我是'+this.name)
},
eat(food1,food2){
console.log(我喜欢吃'+food1+food2)
}
}
dog.eat.call(cat,'鱼','肉')// 这是猫调用狗的属性
dog.eat.apply(cat,['鱼','肉'])// apply
let fun = dog.eat.bind(cat,'鱼','肉')
fun()
/*-------------------*/
function Animal(){
this.eat = function(){
console.log('吃东西')
}
}
function Cat(){
Animal.call(this)
}
let cat=new Cat();
cat.eat()// 输出的是吃东西
同步异步
同步是按照顺序执行
异步有:计时器(setTimeout,setInterval),ajax,读取文件
同步程序执行完成后执行异步程序
单线程
js是单线程,一个任务完成之后才能执行另一个任务
process.nextTick和setImmediate方法
nextTick执行事件是同步代码执行之后,异步代码执行之前。setImmediate是当前事件循环执行之后才执行
事件循环
事件循环是同步放在运行栈,异步放在任务队列,然后循环执行,当前时间段先执行同步,再执行异步,如果当前时间段有nextTick就在同步执行之后再执行nextTick,然后执行异步,比如异步当前时间段没有就执行setImmediate。这是事件循环。
异步程序的宏任务和微任务
宏任务:计时器、ajax、读取文件
微任务:promise.then
执行顺序
1. 同步程序
2. nextTick
3. 微任务
4. 宏任务
5. setImmediate
promise async
let p=new Promise((resolve)=>{
resolve('hello world')
})
p.then((data)=>{
console.log(data)
})
/*------------*/
async function fun(){
return 1
}
等同于function fun(){
return new Promise((resolve)=>{
resolve(1)
})
}
fun()//显示的是promise{1}
fun().then((data)=>{
console.log(data)
})
async的返回值是promise。可以结合await,让异步的代码看起来像是同步的。await后面的代码是异步的,前面的代码是同步的。
闭包
闭包:函数嵌套函数,内部函数就是闭包
正常情况下,函数执行完成,内部变量就会被销毁,释放内存空间。但是闭包内部函数没有执行完成,外部函数变量就不会被销毁
应用:封装一段代码
function outerFun(){
let a = 10
function innerFun(){
console.log(a)
}
return innerFun
}
let fun = outerFun()
fun()
对象拷贝
js内存结构
- 原始类型:数值number、字符串string、布尔boolean、null、undefined、symbol。存放在栈内存中。。。naN是一个数值类型,但不是一个具体的数字
- 引用类型:object对象 。存储在堆内存中l
console.log(true+1)
2,其他类型(除字符串类型)和数字类型运算都会变成数值类型- 字符串和其他数据类型相加都会变成字符串
console.log('name'+true)
nametrue - 引用数据类型:object、array、function(统称为object)
null和undefined的区别?
- null和undefined都表示无。作者在设计的时候借鉴Java代码,先设计的null,但是有缺点,所以就添加了undefined。
- null是对象,还会被隐式转化为0,不容易发现错误。因此undefined引入。undefined转化为数值为naN。
拷贝对象
拷贝一个对象:让两个变量指向两个对象
浅拷贝:如果是原始类型,可以拷贝,如果是引用类型则无法拷贝。
深度拷贝:如果只是原始类型就直接拷贝,如果有引用类型,就深度拷贝
function copy(obj){
let newObj={}
for(let i in obj){
if(obj[i] instanceof Object){
newObj[i]=copy(obj[i])
}else{
newObj[i] = obj[i]
}
}
return newObj
}
使用json进行拷贝
前后端交互使用。json就是js的对象,使用双引号“name”:“小明”
function copy(obj){
let str = JSON.stringify(obj)// 方法将 JavaScript 对象转换为字符串
let newObj = JSON.parse(str)// 要被解析成 JavaScript 值的字符串
return newObj
}
防抖
防抖:用户触发事件过于频繁,只要最后一次事件的操作
let inp =document.querySelector('input')
let t =null
inp.oninput = function(){
if(t!==null){
clearTimeout(t)
}
t=setTimeout(()=>{
console.log(this.value)
},500)
}
- 但是上面的代码直接写在程序里面不利于维护,因此要进行闭包操作,也就是封装函数
let inp =document.querySelector('input')
inp.oninput = debounce(function()=>{
console.log(this.value)
},500)
//封装
function debounce(fn,delay){
let t =null
return function(){
f(t!==null){
clearTimeout(t)
}
t=setTimeout(()=>{
fn.call(this)// 如果不加call,则封装里面的this指向调用的input,而上面的this没有被调用,指向window,加this是为了让this指向fn。
},delay)
}
}
节流
节流:控制执行次数
节流的作用:控制高频事件执行的次数
let flag = true
window.onscroll = function(){
if(flag){
setTimeout(()=>{
console.log('nihao')
flag = true
},500)
}
flag=false
}
延时加载的js有哪些方法?
- 通过动态创建方式
- setTimeout()
- async:
<script async src="./01.js"></script>
- defer:
<script defer src="./01.js"></script>
- 两个的区别:defer是顺次执行js脚本。先html的同时加载js,然后等html执行后再执行js
- async是谁先加载完谁先执行,先加载html,遇到js同时加载js,然后执行js,然后继续html
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1bYt3AFw-1646898017328)(./img/async+defer.jpg)]
和=有什么不同?
- ==:比较的是值,两者比较的时候会转化为基本类型,如果值一样为true。隐式转化都是通过valueof转换。
- ===:除了比较值,还比较数据类型,只要类型不相同就不相等。
js对象注意点?
- 对象是通过new构建出来的,所以对象不相等,除了引用之外。
数组去重
- new Set
- indefOf
- sort
cookie/session/localStorage/sessionStorage
http协议:简单,快捷,无连接,无状态,多个请求之间是没有关联的、独立的。
Cookie
- Cookie不是缓存
- 什么是Cookie?
- Cookie是在服务器产生的,存储在客户端的一小段文本信息,格式是字典,键值对。
- Cookie的分类?
- 会话级:保存在内存中,当浏览器关闭就会丢失
- 持久级:存储在硬盘中,只有当失效时间到了才会被清除
- Cookie如何实现鉴权
- 当客户端第一次访问服务器的时候,服务器就会生成Cookie,然后通过响应头的方式在Set-Cookie传输到客户端,客户端从第2-n次请求都会自动带上这些Cookie。
- Cookie的缺点:Cookie保存在客户端,对于一些敏感的信息,比如用户名密码,身份信息等,不安全。
session鉴权
- 当用户第一次访问服务器的时候,然后在服务器端保存一个sessionid,这个sessionid是经过加密的,然后通过cookie把这个sessionid保存在客户端,然后去请求服务器的时候只发送sessionid。
token鉴权
- 当一个用户登录后,就给他发送一个token令牌,下一次用户再次请求的时候,只需要带上这个令牌。
session和cookie
- 特征:
- session和cookie都是由服务器生成的,都是存储特定的值
- session是存储在服务器的,而cookie是返回给客户端的。
- 生命周期
- cookie和session都有生命周期。
- cookie的生命周期受两个因素影响:
- cookie自身的存活时间:是服务器生成cookie时去设定的。
- 客户端是否保留cookie,只对客户端自身有影响,对其他封包工具是没有影响的
- session的声明周期也是受两个因素影响:
- 服务器对session对象的保存的最大时间的设置
- 客户端进程是否关闭。客户端进程关闭只对客户端自身有影响,对其他封包工具没有影响。
sessionStorage(临时存储)和localStorage(本地存储)
- LocalStorage和SessionStorage之间的主要区别在于浏览器窗口和选项卡之间的数据共享方式不同。
- cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
- sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持。
- localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据。
- localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据。
- sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的
异步的过程
- 异步是用来解决DOM冲突(单线程)
- 一异步解决的方案:事件轮询
- 因为js是单线程的,所以按照顺序执行,如果遇到异步操作,异步程序会在webapi中执行,然后js代码继续向下执行,当webapi中的代码执行完成后会传到一个队列中等待js的执行,js执行完同步代码后会到对列中去执行已经完成的异步操作,这就是事件轮询
- 事件轮询的核心是:回调函数
- 回调函数:参数为函数形式的函数是回调函数,参数是回调函数
- 回调函数有:同步回调函数、异步回调函数