今日面试总结
1. 如何使用css实现一个三角形(倒三角▼)?
第一种方法,将宽高设置为0,给你需要作为底边的那个方向写上颜色,在将其余两边块设置为透明
.box{
width:0;
helght:0;
border-top:100px solid red;
border-left:100px solid transparent;
border-right:100px solid transparent;
}
第二种方法,使用伪元素定位
.triangle{
width:100px;
height:100px;
postition:relative
}
.triangle:before{
content:"";
width:0;
height:0;
border-top:10px solid red;
border-left:10px solid transparent;
border-right:10px solid transparent;
postition:absolute;
top:xx;
left:xx;
}
2.什么是闭包? 包括第3问:闭包的缺点
特点
闭包的特点就是,一个函数内部返回一个函数。
好处
让外部函数能够访问内部函数的变量,缓存变量,封装私有属性和私有变量
坏处
加大内存消耗,使用不当会造成内存泄漏
4. 深拷贝和浅拷贝有什么区别
浅拷贝
因为浅拷贝的话是拷贝的变量的引用地址,改变拷贝的值,被拷贝的也会相应发生改变;
手写浅拷贝:
// Object.assign()
var obj = {
a: {
a1: { a2: 1 },
a10: { a11: 123, a111: { a1111: 123123 } }
},
b: 123,
c: "123"
}
let shallowclone = Object.assign({},obj)
深拷贝
深拷贝的话是真正的把对方的数据拷贝过来,改变任意一个值另一个值是不会发生改变的;
// JSON.stringify JSON.parse
手写深拷贝(递归):
function DeepClone(obj){
let newObj = Array.isArray(obj)?[]:{} // 防止传进来是一个数组导致结构不一致
for(let i in obj){
if(typeof obj[i] === 'object'){
newObj[i] = DeepClone(obj[i]);
}else{
newObj[i] = obj[i];
}
}
}
5.谈谈this
讲this的话就会想到指向的问题。
在全局作用域下调用一个普通函数,this指向window
通过对象.函数名调用的,this指向这个对象
箭头函数没有自己的this,他的this是由他的上下文所决定
setTimeout、setInterval,this指向window
函数作为构造函数用new关键字实例化后,this指向new出来的这个实例
6.怎么实现一个call()
手写call、apply函数
call、apply主要实现思路
一、先判断调用的是不是一个函数,如果不是直接抛出异常
二、通过传进来的新对象 (context)来调用函数
1.给context创建一个fn设置为需要调用的函数
2.结束调用之后删除fn
call
Function.prototype.myCall = function(context){
// 先判断调用myCall是不是一个函数
// 这里的this就是调用myCall的
if(typeof this !== 'function'){
throw new TypeError("Not a Function");
}
// 不传参数 默认为window
context = context||window;
// 将this保存到fn属性中
context.fn = this;
// call参数是一个一个数据
// 在获取他传进来的参数,由于我们不确定他有多少参数我们就要使用不定参数去获取
let args = Array.from(arguments).slice(1); // Array.from 将伪数组转换为数组
// 调用函数
let result = context.fn(...args);
delete context.fn;
return result
}
apply
Function.prototype.myApply = function(context){
// 一样先判断调用的是不是函数
if(typeof this !== 'function'){
throw new TypeError("Not a Function");
}
let result;
// 一样context不传值默认为window
context = context||window
// 是否传参 apply的参数是数组
if(arguments[1){
result = context.fn(...arguments[1])
}else{
result = context.fn();
}
delete context.fn;
return result
}
7.改变this指向的三种方法 (补充区别)
call、apply、bind
call和apply调用后立即执行函数fn,而bind不会,它会返回一个修改后的函数fn需要手动进行调用
call和apply的传参不同,除了第一个参数为需要指向的对象外,call的参数为参数列表而apply为数组
8.什么是http
超文本传输协议(Hypertext Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上
补充一个面试题 : 在浏览器从输入URL地址到页面渲染这个过程经历了什么?
在地址拦输入URL后
1.浏览器会先解析URL是否合法
2.URL合法后会开始查找缓存,浏览器缓存--系统缓存--路由器缓存,如果缓存中有,就直接展示页面内容
3.如果没有DNS就会解析域名,获取其中的ip地址
4.浏览器向服务器发起tcp链接,与浏览器建立tcp三次握手
5.握手成功后,在向服务器发送http请求
6.获取到服务器返回的数据,解析其中html代码,并请求html中的资源
7.浏览器再对页面进行渲染
9.http和https的区别
1.HTTPS需要用到SSL证书,一般免费证书比较少,因此需要付费
2.HTTP是超文本传输协议,信息是明文传输,HTTPS则是具有安全性的SSL加密传输协议
3.HTTP的默认端口是80端口,HTTPS的默认端口是443端口
4.HTTP的连接很简单,是无状态的。HTTPS协议是由HTTP+SSL构建的加密传输、身份认证的网络协议
10.https的缺点是什么
1.HTTPS协议握手耗时较高,会使页面的加载时间延长
2.HTTPS需要SSL证书,免费的比较少,大多需要付费
3.HTTPS连接缓存不如HTTP高效,会增加数据开销
11.如何封装一个插件(组件????)
在components文件夹下创建组件,封装组件要考虑组件的复用性和高可用性。很好的封装组件可以解决代码冗余。
封装完组件,在页面中引入并在components中进行注册。
12.vue响应式原理
1.vue是通过Object.defineProperty来实现数据劫持,将每一个属性都设置一个getter和setter方法
2.再通过发布者-订阅者模式进行依赖收集和试图更新
13.小程序怎么实现上拉加载
写在小程序中上拉加载的生命周期onReachBottom
onReachBottom(){
// 执行业务逻辑
// 比如把pages++
}
14.小程序的生命周期有哪些
页面生命周期
onReady(){} // 初次渲染完成
onShow(){} // 监听页面显示
onHide(){} // 监听页面隐藏
onLoad(){} // 页面加载 参数为上一个页面所传递过来的数据
onUnload(){} // 监听页面卸载
onPullDownRefresh(){} // 监听下拉动作 常用于下拉刷新
onReachBottom(){} // 页面滚动到底部的事件 常用于上拉加载
15.es6中promise的作用是什么
16.get和post有什么区别
get 有缓存,参数通过URL拼接进行传递,暴露信息请求不安全,URL参数长度有限制,请求参数会被完整的保存在请求的历史记录中
post 请求的参数包含在请求体中,请求更安全,对长度没有限制,post请求参数不会被保留在请求的历史记录中
17.vue中插槽有哪几种
插槽slot
vue中的插槽指的是子组件提供给父组件使用的一个占位符
用标签表示,父组件可以在这个占位符中填充任何模板代码
比如html、组件等,填充的内容会替换掉子组件的标签(替换占位符)
一、默认插槽
<slot> <slot/>
二、具名插槽
<slot name="名称"> <slot/>
三、作用域插槽
<slot :自定义 name = data中属性对象><slot/>
18.插槽分类主要用来做什么为什么要分那么多种插槽
1,具名插槽的话就是给某一个插槽取一个名字,而父组件需要通过插槽插到子组件就可以对号入座
2.作用域插槽 如果子组件无法决定他的结构就要使用作用域插槽,将他的数据自定义属性传输给父组件,父组件通过在template标签上添加slot-scoped = "子组件传过来的自定义属性名" 或者使用v-slot = "子组件传过来的自定义属性名"
19.vue组件传值父传子
父组件
<template>
<div>
<child :list="list"><child/>
<div/>
<template/>
子组件
<template>
<div>
<div/>
<template/>
<script>
export default {
data(){
return {
name:"child"
}
},
props:['list']
}
<script/>
20.讲讲vue生命周期有哪些
长话短说:创建、挂载、更新、销毁
21.路由模式有哪些?
两种模式
1.hash
2.history
补充hash和history 有什么区别
1.hash对比history history比较美观,没有#,简单实用
2.history优雅清爽,依赖于HTML5 History API