cookie,localstorage,sessionstorage
cookie用来保存登陆信息,大小限制在4kb左右,每次都在http头中,localstorage只在客户端保存,不参与和服务端的通信,除非被清除否则能永久保存。sessionstorage仅在当前会话下有效,关闭页面或浏览器后被清除。
1.基本数据类型
JS有7种基本:
Undefined:未定义,Null:空对象,Boolean,Number,String,Symbol(创建后独一无二不可变,解决全局变量冲突),BigInt(处理任意精度整数的新数字基元)
ES5有6种
undefined,null,boolean,number,string(基础),object(复杂) 基础在栈存值,负载将内容存堆,堆对应的栈记录指针(堆的地址)赋值时地址引用。
2.引用数据类型
Object,Array,function
3.Symbol应用场景
用Symbol作为对象属性名(key)
然后想通过Objects.key或for in来枚举对象的属性名就不会显示,所以用JSON.stringfy把对象转成JSON字符串也无法输出,可以将不需要对外操作和访问的属性用Symbol定义。使用Object.getOwnPropertySymbols()和Reflect.ownKeys()可以获取Symbol定义的对象属性。
使用Symbol代替常量
需要定义一组常量代表业务逻辑下几个不同类型,希望常量是唯一的,一般为常量赋一个唯一的值,用Synmbol()可以直接保证常量唯一。
使用Symbol定义类的私有属性/方法
在class中,用[]括起来的属性名就是Symbol类型的,可以作为私有属性
注册和获取全局Symbol
应用涉及多个window,这些window中使用的某些Symbol是同一个,就不能用Symbol()函数,可以用Symbol.for()注册或获取一个window间全局的Symbol实例,在多个相关的window间是唯一的。
const和Symbol的区别
const表示定义后不可修改或重复定义,symbol表示定义的变量值绝不重复。
0.1+0.2===0.3是错的
js数字是浮点数,js是解释型语言,不用声明类型,用的是弱类型,浮点数是用双精度储存,0-51位是分数,52-62是指数,63位是标志位.小数转二进制用乘二取整,对0.1会产生无限循环,小数部分只有精度53位,超出部分0舍1入存在精度问题。只要存在进位就不再准确。
判断数据类型方式
1.typeof
缺陷:判断null以外基础类型,复杂类型除function都是object
2.instance of
准确判断复杂类型,不能判断基础
3.Object.prototype.toString.call()
判断所有类型,返回示例[object array]
4.constructor===
返回构造器
隐式转换类型
字符串:
toString,String,结果加引号就行,除了极小极大值是指数形式
数字转换:
undefined=NAN,null=0,boolean=1/0,string=NAN/0/-Infinity/ 纯数字 Number,parseInt,parseFloat
布尔值:
除undefined,null,false,+0/-0/NAN/""为false,其他为true
2.js原型,原型链及特点
js用构造函数新建对象,每个构造函数内部有prototype属性,该属性值是一个对象,包含可以由该构造函数的所有实例共享的属性和方法。新建对象后,对象内部有指针指向构造函数中prototype属性对应的值,该指针叫对象的原型,可以使用Object.getProtoTypeOf()获取对象的原型。访问一个对象的属性,对象内部不存在该属性,就会去它的原型对象里找该属性,该原型对象有自己的原型,就这样一直找下去,就是原型链,原型链的镜头都是Object.prototype。js对象通过引用传递,创建的新对象实例没有属于自己的原型副本,修改原型时,与之相关的对象也会继承这一改变。
instanceof
用于判断构造函数的prototype是否出现在对象的原型链的任何位置
3.延迟加载方式
等页面加载完再加载JS文件,有助于提高页面加载速度:
defer:
延迟执行引入的js,js加载时HTML仍未停止解析,二者并行,document解析完毕执行脚本,多个脚本按顺序执行。
async:
异步执行引入的JS。如果加载好就会执行,执行会阻塞文档解析,加载不会阻塞。返回一个Promise对象,可以用then添加回调函数,执行时遇到await就返回,异步操作完成后接着执行函数体后面语句。单独使用表异步函数,返回结果自动处理成promise对象,和await搭配,把异步变同步,控制执行顺序。动态创建DOM,使用setTimeout延迟方法,JS最后加载。
4.继承方式
原型链:
被所有实例对象共享,容易有修改混乱
借用构造函数
子类调用超类的构造函数,可以向超类传参,但没办法复用函数,子类也访问不了超类原型定义的方法
组合继承
结合原型链和借用构造函数。子类的原型设置为超类的实例,相当于调用2次超类的构造函数,造成子类原型有很多不必要属性
原型式继承
像函数传入对象,返回以该对象为原型的对象,至于某个对象实现简单继承
寄生式继承
创建用于封装继承过程的函数,传入对象然后复制对象的副本,对象进行扩展最后返回,扩展过曾是继承,也是对简单对象继承,但没办法函数复用
寄生式组合继承
用超类圆形的副本做子类的原型,避免不必要属性
5.JS跨域
请求url的协议,域名,端口任意一个与当前界面不同就是跨域。
JSONP
用script标签的Src属性实现跨域,将前端方法作为参数传到服务端,服务端注入参数后返回,实现通信,由于利用src,只支持get方法。 JSONP与服务端约好回调函数名,服务端接到请求返回一段JS,这段JS代码中调用了回调函数并把数据作为参数传递,网页接收到后就会执行这个回调函数。只支持跨域HTTP请求,调用失败不返回HTTP状态,安全性不太好,但兼容性好。
CORS(跨域资源共享)
用自定义HTTP头部让浏览器和服务器沟通,决定请求或相应应成功/失败,是主流方案。普通:服务端进行设置,带cookie请求,前端要设置withCredentials为true
window.postMessage
多窗口通信使用H5规范的targetWindow.postMessage(data,origin),data是需要发送的对象,origin是目标窗口的origin.window.addEventListener('message',handler,false),handler的event.data是postMessage发送的数据,event.origin是发送窗口的origin,event.source是发送消息的窗口引用。
服务器代理
内部服务器代理请求跨域url,然后返回数据
6.ES6新特性
let var const
let是块级作用域,var是函数作用域,const块级作用域,var存在变量提升,let没有,使用let命令声明变量之前,该变量都不可用,叫暂时性死区。
箭头函数
箭头函数是匿名函数,不能作构造函数,不使用new,不绑定arguments,用rest参数...解决,没有原型属性,this指其上下文的this的指向,不能改变指向,普通函数的this指向调用的对象,不绑定this会不会上下文中的this做自己的。没有上下文函数对象就指向window
ES6的class和ES5的函数
ES6的类是ES5的构造函数的一层包装,ES6类和模块的内部默认是严格模式,不存在遍历提升
7.闭包的特性和优缺点
闭包
函数嵌套函数,内部函数使用外部函数的参数和变量,参数和变量不会被垃圾回收机制回收。
优点
希望一个变量长期保存在内存中,避免全局变量污染,私有成员
缺点
常驻内存增加内存使用量,使用不当造成内存泄露
8.JS作用域
全局作用域:
代码在程序的任何地方都能被访问
函数作用域:
在固定的代码片段才能被访问
块级作用域
在if,switch,循环语句等语句块中使用,不能再语句块之外被访问:let,const
作用域链
js种函数也是对象,对象有些属性可以访问,有些只能被js引擎存取,[[scope]]就是作用域,存储了执行上下文的集合,这个集合是连是连接,这种连是连接叫作用域链
9.深拷贝
浅拷贝是把栈中的引用地址拷贝一份,修改新拷贝的值,被拷贝的对象也被修改,深拷贝会在堆内存为新对象建立空间,不会导致被拷贝对象被修改。一般用JSON实现深拷贝,因为JSON会自己构建新内存存放新对象,但是不可以对function拷贝,不支持循环引用对象的拷贝,一些类型如map,set序列化会丢失,会忽略undefined和symbol
10.浅拷贝的实现
10.Promise是什么,有哪些API
Promise是异步编程的解决方案
用法
Promise构造函数接受一个函数作为参数,2个参数分别是resolve,reject,是2个函数,由js提供不用部署。resolve把Promise对象状态从未完成变成完成(pending->resolved),异步操作成功时调用,并把异步操作结果作为参数传递出去。reject是把状态从未完成变成失败(pending->rejected),操作失败时调用并将异步操作报出的错误作为参数传递
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
Promise实例的方法
then方法定义在原型对象Promise.prototype,是为实例添加状态改变时的回调数据,参数是resolved,rejected状态的回调函数,返回的是新的实例,可以用链式写法,then后再调用then。catch方法是.then(null/undefined.rejection)的别名,指定发生错误的回调函数。Promise.all方法,将多个Promise实例包装成一个Promise实例,接受一个数组作参数,数组内不是实例,先调用resolve方法,将参数转为Promise实例,再进一步处理,all方法参数可以不是数组,但必须有Iterator接口,返回的每个成员都是Promise实例。Promise.race方法将多个Promise实例包装成新的Promise实例,resolve可以把现有对象转为Promise对象,reject方法会返回新的Promise实例,实例状态是rejected。可以用第三方库解决兼容性问题
10.Ajax基本流程
Ajax是创建交互式网页应用的网页开发技术,通过js向服务器发起http通信,根据服务器返回数据更新网页相应部分。ajax能提高页面载入速度主要是通过ajax减少重复数据的载入,也就是说在载入数据时把数据缓存在内存中,提交的url和历史url一致就不用交给服务器,也不用从服务器上获取数据,虽然降低了服务器的负载,提高了用户体验,但不能获取最新数据,所以需要禁止缓存。创建ajax的步骤:
1)
创建一个XMLHttpRequest对象
2)
在这个对象使用open方法创建http请求,open方法需要的参数是请求方法,请求地址,是否异步和用户的认证信息。
3)
发起请求前添加信息和监听函数,比如setRequestHeader为请求添加头信息。一个对象有5个状态,设置监听函数处理请求成功的结果,根据Response的数据更新页面
4)
对象的属性和监听函数设置后,调用sent向服务器发送请求,可以传入参数发送数据体。
11.前端工程化
模块化
js:利用webpack和babel模式把模块系统打包,同步加载,也可以搭乘chunk异步加载。 css:sass,less预处理器实现css拆分,但不能解决全局污染,最好使用css modules,用js管理css文件,如vue的scoped,scriptbiaoqian ,type类型选modules类型就行。 资源模块化:webpack的模块化原理使任何资源模块化和模块化处理,是目录结构清晰,资源处理继承项目依赖单一
组件化
ui拆成模板+样式+逻辑的功能单元是组件,组件化是ui层面进行的拆分,将dom和一起的逻辑组成组件再应用,封装组建后还要对组件间关系判定,关系统称为依赖。
规范化
项目目录,编码,前后端接口,git分治,commit描述等都要规划,减少联调中的麻烦
自动化
简单重复的工作给机器
12.webpack功能
原理
是把所有资源看成一个模块,页面逻辑看成整体,通过给定的入口文件,找到各个依赖文件模块,经过loader和plugins处理然后打包,输出可识别的js文件。
概念
入口Entry指示应从哪个模块着手作为构建内部依赖的开始,输出Output告诉webpack在哪里输出创建的打包文件,也可指定打包文件的名称。loader理解成Webpack的编译器,使其能处理非js文件,常用loader:css-loader,style-loader,Plugins插件用于执行范围更广的任务,一般先用npm安装,然后在配置文件引入,实例化后传给plugins数组属性
13.微任务/红任务/事件循环机制
script脚本整体式大的异步任务,先执行脚本,脚本包括同步任务和异步任务,同步任务在主线程执行,异步任务(宏/微任务)添加到任务队列,分为宏任务队列和微任务队列。同步任务队列执行完毕后,执行栈清空,执行异步任务,先取微任务执行,有新的产生就加到队列,直到微任务队列清空,然后取红任务,如果产生新的微任务,就先执行微任务队列,没有就继续执行红任务,直到所有任务执行完毕。