前端重点⾯试题总结
after school
闭包
闭包就是可以让内部函数可以访问外部函数的变量,
特点:
1. 内部函数可以调⽤外部函数的变量
2. 局部变量会常驻在内存中,可以重复使⽤,避免了使⽤全局变量造成变量污染的问题。
3. 由于闭包可以使变量长期保存在内存中,内存消耗很⼤,所以不能滥⽤。会造成⽹页性能的问题,IE中还会造成内存泄漏
作⽤域
1. js中⾸先有⼀个最外层的作⽤域,全局作⽤域;
2. js中可以通过函数来创建⼀个独⽴作⽤域称为函数作⽤域,函数可以嵌套,所以作⽤域也可以嵌套;
3. es6中新增了块级作⽤域(⼤括号,⽐如:if{},for(){},while(){}…) es6作⽤域,只适⽤于const,let ;
原型
1. 每个函数都有⼀个prototype属性,被称为显⽰原型
2. 每个实例对象都会有_ _proto_ _属性,其被称为隐式原型
3. 每⼀个实例对象的隐式原型_ _proto_ _属性指向⾃⾝构造函数的显式原型prototype
4. 每个prototype原型都有⼀个constructor属性,指向它关联的构造函数。
5. 原型链:获取对象属性时,如果对象本⾝没有这个属性,那就会去他的原型__proto__上去找,如果还查不到,就去找原型的原型,⼀
直找到最顶层(Object.prototype)为⽌。Object.prototype对象也有__proto__属性值为null。
继承
Es5中的继承有:
1. 原型继承:⽗类的实例作为⼦类的原型
2. 借⽤构造函数继承:在⼦类中使⽤call⽅法调⽤⽗类的⽅法并将⽗类的this改成⼦类的this
3. 组合继承:既能调⽤⽗类的实例属性⼜能调⽤⽗类的原型属性
Es6有class继承
1. class就相当于Es5中的构造函数
2. class中定义⽅法是前后不能加function,全部都定义在class的prototype属性中
3. class中只能定义⽅法不能定义对象变量等
4. class默认是严格模式
5. 在⼦类中调⽤extends⽅法可以调⽤⽗类的属性,⽤eat调⽤⽗类的⽅法
promi
promi简单来说就是⼀个容器,它⾥⾯存放了⼀些异步操作的结果。他还是个对象,它可以获取到异步操作的结果,他还是个构造函数,他对外有统⼀的API,⾃⾝有all,reject,resolve等⽅法,原型上有then,catch等⽅法,他可以链式调⽤,all⽅法是等所有的异步请求都完成后⼀并回调,race⽅法是只要有⼀个异步请求完成就会进⾏回调。⾸字母⼩写是实例对象,⼤写且单数是构造函数,⼤写且christmas lights
复数是规范。他有三个状态pending初始状态,fufilled成功状态,rejected失败状态。它的状态⼀旦改变就不能在改变,只能是从初始状态改成成功或者失败的状态。他可以封装ajax,axios的get和post的封装
特朗普就职演讲(⼿写异步加载图⽚)
let imageAsync=(url)=>{
return new Promi((resolve,reject)=>{
let img = new Image();
img.src=url;
img.οnlοad=()=>{
console.log(`图⽚请求成功,此处进⾏通⽤操作`);
resolve(image);
}
img.οnerrοr=(err)=>{
console.log(`失败,此处进⾏失败的通⽤操作`);
reject(err);
}
})
}
imageAsync("你的图⽚的url").then(()=>{
console.log(`${image},此处进⾏图⽚成功的个性化操作`);
}).catch((error)=>{
console.log(`${error},此处进⾏图⽚请求失败的个性化操作`);
})
asyne
asyns 可以把普通的函数改成异步函数,调⽤都是⼀样的,返回的对象是⼀个promi对象,要放到await后⾯,等待所有的异步请求完毕后⼀起回调,所以它是⼀个阻塞式的异步函数,他可以传多个参数,是对promi的进⼀步优化,代码是从上到下执⾏的。
虚拟dom
对复杂的⽂档DOM结构,提供⼀种⽅便的⼯具,进⾏最⼩化的DOM操作
虚拟dom是利⽤js描述元素与元素的关系。
好处:是可以快速的渲染和⾼效的更新元素,提⾼浏览器的性能
双向绑定
vue.js是采⽤数据劫持结合发布者-订阅者模式的⽅式,通过Object.defineProperty()来劫持各个属性的tter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图。
(了解)
具体步骤:
第⼀步: 需要obrver的数据对象进⾏递归遍历,包括⼦属性对象的属性,都加上 tter和getter
这样的话,给这个对象的某个值赋值,就会触发tter,那么就能监听到了数据变化
第⼆步 compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页⾯视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,⼀旦数据有变动,收到通知,更新视图
第三步: Watcher订阅者是Obrver和Compile之间通信的桥梁,主要做的事情是:
crazereplaceall1、在⾃⾝实例化时往属性订阅器(dep)⾥⾯添加⾃⼰
2、⾃⾝必须有⼀个update()⽅法
vigor3、待属性变动ice()通知时,能调⽤⾃⾝的update()⽅法,并触发Compile中绑定的回调,则功成⾝退。
第四步:MVVM作为数据绑定的⼊⼝,整合Obrver、Compile和Watcher三者,通过Obrver来监听⾃⼰的model数据变化,通过Compile 来解析编译模板指令,最终利⽤Watcher搭起Obrver和Co
mpile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) ->数据model变更的双向绑定效果。
组件通信
⽗传递⼦如何传递
(1)在⽗组件的⼦组件标签上绑定⼀个属性,挂载要传输的变量
(2)在⼦组件中通过props来接受数据,props可以是数组也可以是对象,接受的数据可以直接使⽤ props: [“属性 名”] props:{属性名:数据类型}
⼦传递⽗如何传递
(1)在⽗组件的⼦组件标签上⾃定义⼀个事件,然后调⽤需要的⽅法
(2)在⼦组件的⽅法中通过 this.$emit(“事件”)来触发在⽗组件中定义的事件,数据是以参数的形式进⾏传递的
兄弟组件如何通信
(1)在src中新建⼀个Bus.js的⽂件,然后导出⼀个空的vue实例
emit(“事件名”,"参数")来来派发事件,数据是以
(2)在传输数据的⼀⽅引⼊Bus.js 然后通过it()的参 数形式来传递(3)在接受的数据的⼀⽅ 引⼊ Bus.js 然后通过 Bus.$on(“事件名”,(data)=>{data是接受的数据})
vuex
VueX是适⽤于在Vue项⽬开发时使⽤的状态管理⼯具 。如果在⼀个⼤型项⽬中频繁的使⽤组件通信来传参的话对于后期的维护和管理很不⽅便,所以vue就给我们提供了⼀个统⼀管理的⼯具VueX
有五⼤核⼼:
1. state 所有的数据都存储在state中 state是⼀个对象
2. mutations 可以直接操作state中的数据
3. actions 只能调⽤mutations的⽅法
4. getters 类似计算属性实现对state中的数据做⼀些逻辑性的操作
5. modules 将仓库分模块存储
⾃定义指令
全局: vue.directive:{"",{}}
局部:directives:{指令名:{钩⼦函数}}
bind(){} 只调⽤⼀次,指令第⼀次绑定到元素时调⽤
inrted(){} 被绑定元素插⼊⽗节点时调⽤
update(){} 被绑定元素所在的模板更新时调⽤,⽽不论绑定值是否变化
componentUpdated(){} 被绑定元素所在模板完成⼀次更新周期时调⽤
unbind(){}只调⽤⼀次, 指令与元素解绑时调⽤
指令钩⼦函数会被传⼊以下参数:
el:指令所绑定的元素,可以⽤来直接操作 DOM 在每个函数中,第⼀个参数el ,表⽰被绑定了指令的那个元素,这个 el 参数,是⼀个原⽣的JS对象,。
binding:⼀个对象,包含以下属性:
name:指令名,不包括 v- 前缀。
value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2。
oldValue:指令绑定的前⼀个值,仅在 update 和 componentUpdated 钩⼦中可⽤。⽆论值是否改变都可⽤。
expression:字符串形式的指令表达式。例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”。
arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
modifiers:⼀个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
vnode: Vue编译⽣成的虚拟节点。移步 VNode API 来了解更多详情。
oldVnode:上⼀个虚拟节点,仅在 update 和 componentUpdated 钩⼦中可⽤。enter
3.vue⾃定义指令的应⽤场景
代码复⽤和主要形式是抽象的组件
当需要对普通 DOM 元素进⾏底层操作,此时就会⽤到⾃定义指令
⾃定义组件
⾃定义组件就好⽐封装,把⼀些公共的模块抽取出来,然后写成单独的的⼯具组件或者页⾯,在需要的页⾯中就直接引⼊即可。
组件封装
我⽤vue开发的所有项⽬,都是采⽤组件化的思想开发的。⼀般我在搭建项⽬的时候,会创建⼀个views⽬录和⼀个commen⽬录和⼀个feature⽬录,views⽬录中放页⾯级的组件,commen中放公共组件(如:head(公共头组件),foot(公共底部组件)等),feature ⽬录内放功能组件(如:swiper(轮播功能组件),tabbar(切换功能组件)、list(上拉加载更多功能组件))
⾸先,组件可以提升整个项⽬的开发效率。能够把页⾯抽象成多个相对独⽴的模块,解决了我们传统项⽬开发:效率低、难维护、复⽤性低等问题。
使⽤d⽅法创建⼀个组件,然后使⽤ponent⽅法注册组件。但是我们⼀般⽤脚⼿架
开发项⽬,每个 .vue单⽂件就是⼀个组件。在另⼀组件import 导⼊,并在components中注册,⼦组件需要数据,可以在props中接受定义。⽽⼦组件修改好数据后,想把数据传递给⽗组件。可以采⽤emit⽅法。
keep-alive
是Vue的内置组件,能在组件切换过程中将状态保留在内存中,取消组件的销毁函数,防⽌重复渲染DOM。
组件使⽤keep-alive以后会新增两个⽣命周期 actived() 进⼊组件触发 deactived(),离开组件触发
⽣命周期
总共分为8个阶段。创建前/后,载⼊前/后,更新前/后,销毁前/后。
hiace
创建前/后: 在beforeCreated阶段,vue实例的挂载元素$el和数据对象 data 都为undefined,还未初始化。在 created阶段,vue实例的数据对象data有了,$el还没有。
载⼊前/后: 在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,ssage还未替换。
在mounted阶段,vue实例挂载完成,ssage成功渲染。
更新前/后: 当data变化时,会触发beforeUpdate和updated⽅法。
漂移是什么意思销毁前/后: 在destroy阶段,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在。destroyed阶段,组件销毁
跨域
vue
1. 在根⽬录创建fig.js
2. 在ports中配置devrver的内容
3.
4. 将 changeOrigin:true,//开启代理:在本地会创建⼀个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服
务端进⾏数据的交互就不会有跨域问题
ware5. JSONP原理
ajax 请求受同源策略影响,不允许进⾏跨域请求,我们利⽤ script 标签的 src 属性不受同源策略的约束,利⽤这个特性jsonp需要以下步骤:
1. 动态创建script标签``(ateElement('script'))
2. 设置src 属性,(src总要包含参数callback=fn)进⾏跨域请求
3. 将script标签 ``添加到页⾯中执⾏ (body.appendChild('script'))
4. 页⾯要提前定义好callback,进⾏页⾯操作。
6. CORS设置跨域请求
请求时,浏览器会直接发送跨域请求,并在请求头中携带Origin 的header,表明这是⼀个跨域的请求。服务器端接到请求后,会根据⾃⼰的跨域规则,通过Access-Control-Allow-Origin和Access-Control-Allow-Methods响应头,来返回验证结果。
//设置允许跨域的域名,*代表允许任意域名跨域 CORS跨域
res.tHeader("Access-Control-Allow-Origin","127.0.0.1:3003");
常见状态码
2XX——表明请求被正常处理了
1、200 OK:请求已正常处理。
2、204 No Content:请求处理成功,但没有任何资源可以返回给客户端,⼀般在只需要从客户端往服务器发送信息,⽽对客户端不需要发送新信息内容的情况下使⽤。
3、206 Partial Content:是对资源某⼀部分的请求,该状态码表⽰客户端进⾏了范围请求,⽽服务器成功执⾏了这部分的GET请求。响应报⽂中包含由Content-Range指定范围的实体内容。
3XX——表明浏览器需要执⾏某些特殊的处理以正确处理请求
4、301 Moved Permanently:资源的uri已更新,你也更新下你的书签引⽤吧。永久性重定向,请求的资源已经被分配了新的URI,以后应使⽤资源现在所指的URI。
5、302 Found:资源的URI已临时定位到其他位置了,姑且算你已经知道了这个情况了。临时性重定
向。和301相似,但302代表的资源不是永久性移动,只是临时性性质的。换句话说,已移动的资源对应的URI将来还有可能发⽣改变。
6、303 该状态码表⽰由于请求对应的资源存在着另⼀个URL,应使⽤GET⽅法定向获取请求的资源。303状态码和302状态码有着相同的功能,但303状态码明确表⽰客户端应当采⽤GET⽅法获取资源,这点与302状态码有区别。
当301,302,303响应状态码返回时,⼏乎所有的浏览器都会把POST改成GET,并删除请求报⽂内的主体,之后请求会⾃动再次发送。
7、304 Not Modified:资源已找到,但未符合条件请求。该状态码表⽰客户端发送附带条件的请求时服务端允许请求访问资源,但因发⽣请求未满⾜条件的情况后,直接返回304.。
8、307 Temporary Redirect:临时重定向。与302有相同的含义。
4XX——表明客户端是发⽣错误的原因所在。
9、400 Bad Request:服务器端⽆法理解客户端发送的请求,请求报⽂中可能存在语法错误。