# 数据类型
- 为什么会有数据类型?
为了将大量的数据类型进行分类管理。
- 什么是数据,数据的作用?
数据使用来记录用户的所有行为。
作用:用来描述实际内容,页面信息,用户行为等。
# 数据分类
- 原始类型 (基本数据类型)
number 数字时候使用
string 任何内容都可以通过字符串表示
boolean 只有两种结果的时候使用
undefined 数据存在,但没有任何值得时候
null 数据不存在得时候
- 引用类型 (复杂数据类型)
object 描述一个内容,具有多个属性的时候
array 集合 多个相同类型放在一个地方
function api 工具,作用:处理数据
- 什么时候会使用数据?
使用运算的时候会使用数据
- 原始数据类型 是存放在栈里面 里面直接开辟一个空间存放的是值
- 复杂数据类型 首先在栈里面存放地址,然后这个地址指向堆里面的数据
# 函数参数对象
- 函数参数为一个对象,并修改时候会产生什么问题?
更改形参保存的指针
为了避免问题:开发时候尽量不要直接修改形参赋值,可以通过重新声明赋值变量方式修改
# 验证数据类型和原理
- typeof判断null为什么是对象(typeof原理)?
因为是根据底层变量机制码进行验证的,变量的机器码是以1~3位数存储其类型信息。
000 对象
null 为0
typeof在判断null误认为是对象
- js变量在底层中是什么形式存储的?
以变量的机器码1~3为数字存储类型的信息
000:对象
010:浮点数
110:布尔
100:字符串
1:整数
特殊的是undefined、null
undefined -2^30的整数
null 为 0
- 一般使用typeof可以验证除了null以外的原始类型数据
- instanceof原理
instanceof主要实现原理就是只要右边的变量的属性prototype,在左边变量的原型链上即可。
instanceof在查找过程中会遍历,左边变量的原型原型链,直到找到右边变量的prototype,如果没有找到则返回false,找到返回true。
- instanceof作用
instanceof是用来判断对象的具体类型,作用:就是判断一个实例是否属于某个类型
instanceof也可以判断一个实例是否是其父类或者组类的实例
# 变量
- 什么是变量
由let、var、const、function、class、import等关键字声明的量,为变量
- 作用是什么
变量的作用就是储存数据
- 变量在js底层中以什么样式存在的
1:内存中,在栈内存中,key值形式
2:变量赋值,以机器码1~3位的方式存储其保存的数据类型
- let const var区别是什么
var 声明的变量提升,let const没有变量提升
let const在同一个作用域中,命名不能重复,会形成暂时性死区,会产生块级作用域
- 为什么const赋值为数组或者对象,可以被修改
因为const赋值时存放数组或者对象的指针,修改时数组或者对象本身
同理也不能修改const常量赋值的指针
- 什么是全局作用域,和局部作用域?
整个script标签和单独的一个js文件都是全局作用域
在函数内部就是局部作用域
- 全局变量和局部变量
全局变量只有在浏览器关闭的时候才会并销毁,比较占用内存
局部变量当程序执行完毕就会销毁,比较节约内存
- 什么是作用域?什么是作用域链
作用域指的是声明变量使用的范围
作用域链指的是,执行上下文中secoped的层层嵌套,形成的作用域链
- 谈谈你对作用域链的理解?
1:作用域链的作用:决定了变量的访问权限
2:当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级(词法层面上的父级)执行上下文的变量对象中查找,一直找到全局上下文的变量对象,也就是全局对象。
# 函数
- 什么是函数
函数执行特定任务的代码块
- 为什么要使用函数
提高代码的复用率,便于阅读和交流
- arguments是函数内置对象,在不确定实参的参数到底有多少的时候,就可以使用来获取实参。
# 上下文栈
- js执行特点
一段一段执行的
- 段时如何定义的?
js引擎在代码底层执行之前:
1:创建一个执行上下文的栈
2:程序执行时:
2.1 创建执行上下文对象
2.2 将执行上下文对象推入到执行栈中
2.3 如果时同步代码,则执行
如果时异步代码,就会被挂起,到异步消息队列中,然后按照消息队列的排列方式依次执行
3:全局下:创建全局上下文实例
4:当遇到函数执行时候:
4.1 会创建函数的上下文实例,上下文内容:([[scoped]],arguments,this )//函数存储的参数都在arguments
4.2 将上下文推送到执行栈中
4.3 函数执行完毕时,从执行栈中移除上下文,并销毁
5:关闭浏览器时候,全局上下文销毁,执行栈销毁
- 同步代码和异步代码
同步代码:有顺序的,按顺序执行,速度快
异步代码:执行慢的代码,可以编写在任意的位置。
- js如何实现解析执行的?
将上下文添加到执行栈中,开始执行代码
- 执行栈中如何执行代码呢
1:会将所有的变为任务队列
任务:
微任务 proomise.then
宏任务 script setTimeout
2:执行script中所有同步代码,将异步代码排列到队列中
3:执行完同步代码之后执行微任务的异步代码。按照浏览器事件循环机制(EventLop)
换句话:抛开script不看,先执行所有同步代码,在执行微任务,在执行宏任务
- 什么是异步程序?
所谓的异步程序都是针对我们的代码,在执行栈中执行时的一个特点区分为同步和异步
异步:会挂起变成变成异步消息队列
- 什么是异步消息队列?
异步消息队列是将我们的程序执行排成队,同步的和异步的,又区分为宏任务和微任务
# 闭包
- 什么是闭包?
当函数可以**记住**并**访问**所在词法作用域时,就产生了闭包。即使函数在当前词法作用域外执行
## 词法作用域和静态作用域
javascript用的就是词法作用域
- 作用域
> 用于设置访问变量的权限
> 作用域也决定的变量的使用规则
- 词法作用域(静态作用域)
> 词法作用域指的是函数在**声明**的时候就确定了变量的访问权限
- 动态作用域
> 变量的访问权限,在**函数执行**阶段决定的
bash就是动态作用域
- 什么时候会使用闭包?
凡是开发天天用
- 闭包特点
1:防止变量污染
2:闭包中变量没有被销毁
3:从表面上看,函数外部可以访问内部变量,实际上都是因为作用域作用域链的特点实现的
闭包缺点:内存泄露,是因为低版本浏览器,性能差会存在内存泄露现代浏览器性能很好,几乎不存在这个问题
- 性能优化
1:使用立即执行函数
2:使用标记清除法,变量赋值null,零引用。利用的时js垃圾回收制特点
- 预设问题:
什么是垃圾回收机制(浏览器内核不同,垃圾回收机制不同)
闭包问题:还有一个观点,由于垃圾回收机制不同,导致闭包内存泄的问题。
# 原型
- js对象都有原型,原型有什么特点
所有实例对象都快可以访问它的构造的原型
- 什么是原型链
js对象都有原型,原型也有原型,这样的一个结构就是原型链
- 函数的原型 prototype
- 对象的原型 __proto__
- 每个原型上都有construtor,指向该对象的构造函数
- 每个原型上都有constructor,指向该对象的构造函数
- 实例对象的原型与构造函数的原型都是同一个
# class类
- class 关键字
- 作用:构建实例对象
- 类执行时候,执行construtor 构造器函数用于创建和初始化在类中创建的对象
- static 创建类的私有属性
- extends 类的继承
- 有继承就必须有 super 作用实参给父类中的construtor函数形参赋值
- 哪些属性可以继承?
1:constructor中 this.key 和 原型属性
实例属性和原型属性可以继承
类的静态属性不可以继承
- 继承:子类实例对象中也有父类中的所有实例属性和原型属性
# this的判断规则
- 第一步:看this在哪里?
1:如果是全局下 this为window
2:如果写在 function函数中,请看第二步
3:如果写在箭头函数中,就看在作用域链中,最近的this是谁
- 第二步:看函数是由谁触发的?
1:new this为实例的对象
2:bin call apply this 为实参一
3:事件 this为触发事件的dom
4:普通对象 this为函数执行时,点左边的对象
- 触发函数几种方式
1:new
2:bind call apply
3:事件触发
4:普通对象
# replace
> 可以把字符串中的旧字符替换成新字符串
> 函数执行次数:与匹配结果个数有关
> 第一个参数可以是正则表达式
> 第二个参数可以是函数,函数里面参数:
$ 正则表达式匹配到的字符串片段
$1 索引
$2 整个字符串片段
# 函数柯里化
- 柯里化(currying),把接收多个参数的原函数变为接收一个单一的参数(原函数的第一个参数) 的函数,并返回新函数,新函数能够接收剩余的参数,最后返回与原函数一样的结果
# 浏览器存储
- localStorage 持久化存储,通过api才能三处。大小4mb
- sessionStorage 临时存储,浏览器关闭。自动三处大小 4mb
- cookies 大小 4kb 持久化存储 有过期时间。
- indexDB 相当于浏览器数据库;有几百兆,tree.js可以用到
## location.href 跳转页面
- localStorage.setItem 存储 参数一:键名 参数二:键名对应的值
- localStorage.getItem 获取 参数:键名
- localStorage.removeItem 删除存储 参数:键名
# Promise实例对象
- 网络请求,哪里的代码是异步代码?
1:发请求:是同步的
2:处理相应结果的函数是异步的
- Promise
1:Promise实例对象是同步的,执行快
2:Promise的参数,是同步的,执行快
异步的:then的回调
- 为什么会有promise?
为了避免使用回调函数解决异步问题,层层嵌套情况
- Promise 是实例对象上有哪些内容?
[[PromiseState]] 表示promise实例的状态
[[PromiseResult]] 表示promise实例的结果,作用:记录任务完成结果值
- romise的实例的状态值有哪些呢?
1:prending 表示任务正在进行中
2:fulfilled 表示任务完成
3:rejected 表示任务失败
- 为什么[[PromiseResult]] 为undefined?
因为任务进行中是没有结果得,只有任务完成才有结果,所以为undefined表示没有结果
- 如何修改[[PromiseState]] 的赋值?
1:执行Promise 的回参函数resolve reject
- 怎么给[[PromiseResult]] 进行赋值?
第一种:resolve() 的实参,给[[PromiseResult]]的赋值
- 如何获取属性的赋值?
注意:[[PromiseState]] 赋值读取没有任何意义,不读取了。
重点:[[PromiseResult]] 的赋值的读取。
- Promise实例对象参数
let p = new Promise((resolve,reject)=>{}
resolve reject作用:修改promise实例的状态。
resolve 将pending 变已接收
reject 将pending 变为已拒绝 报错
- .then
返回值也是promise实例
作用:.then前的方法执行完后在执行then内部的程序,这样就避免了,数据没有获取到的问题
# async await
## async await 将异步问题同步化
- async函数
1:默认返回值promise实例对象
- await
只能在async函数中书写
await后需要的是promise实例对象
await作用:读取promise实例对象上的结果,换句话获取[[PromiseResult]] 的值
await作用:临时阻塞代码执行效果,需要等await结束后才能继续执行
# 模块化
## commonjs
- require()
作用:1:在node.js平台中,导入模块(导入js脚本)
2:执行被导入的脚本。当导入的脚本中所有同步代码执行完,并且require输出返回值
意味着:require() 函数执行结束
返回值:默认对象 或者 module.exports的赋值
- module.exports
导出:导出内容可以被其他js文件 通过require导入并访问
## AMD
- AMD需要依赖于require.js才能实现模块化
- require() 导入模块
参一:依赖集合,参二:回调函数
- define()
作用定义模块,默认文件名就是模块名
回参:require()函数,作用可以导入其他模块
return 导出模块中的内容
## UMD
## es6 module
- import
1:导入模块 import A from './moduleA.js'
2:声明变量 A
3:给 A 变量赋值 moduleA.js 中由 export.default 导出内容
4: 同步加载模块,先停止当前index.js的解析,执行子模块中代码,当子模块中同步代码执行完毕,在继续解析index.js
5: import 默认会提升到当前模块作用域的做顶端 (import 写在脚本的最上方)
- from
根据路径查找 js文件
找到后的js脚本会执行
- export default 导出
## 预编译
- js引擎运行js分为两步:预编译 代码执行
- 预编译 js引擎会把js 里面所有的var 还有 function 提升到当前作用域的最前面
- 代码执行 按照代码书写的顺序从上往下执行
- 预编译分为 变量预编译(变量提升) 和 函数预编译(函数提升)
- 变量提升就是把所有的变量声明提升到当前的作用于最前面 不提升赋值操作
javascript笔记
于 2023-01-05 15:23:54 首次发布