前端面试套餐
css:设备像素,css像素,设备独立像素,dpr,ppi之间的区别
- 设备像素又称为物理像素
- css像素
- 在同一个设备上,css像素所代表的设备像素是可以变化的(比较调整屏幕的分辨率)
- 在不同的设备之间,每个css像素所代表的设备像素是可以变化的(连哥哥不同型号的手机)
- 设备独立像素,一个设备独立像素里可能包含1个或多个物理像素点,包含的越多则屏幕看起来越清晰
- 至于1个虚拟像素被换算成几个物理像素,这个数值我们称之为设备像素比,也就是dpr
window.screen.width/ window.screen.height
查看
- dpr,设备像素比,代表设备独立像素到设备像素的转换关系
- 通过
window.devicePixelRatio
获取
- 通过
当设备像素比为1:1时,使用1(1×1)个设备像素显示1个CSS像素
当设备像素比为2:1时,使用4(2×2)个设备像素显示1个CSS像素
当设备像素比为3:1时,使用9(3×3)个设备像素显示1个CSS像素
- ppi,每英寸像素,表示每英寸所包含的像素点数目,更确切地说法应该是像素密度。数值越高,说明屏幕能以更高密度显示图像
- 屏幕分辨率x*y,ppi=根号(x²+y²)/屏幕尺寸
- 值越大,图像越清晰
js:深拷贝浅拷贝的区别?如何实现一个深拷贝?
区别
- 浅拷贝
浅拷贝,指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝
如果属性是基本属性,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址
即浅拷贝是拷贝一层,深层次的引用类型则共享内存地址 - 浅拷贝的实现
function shallowClone(obj){
// if(Object.prototype.toString.call(obj).slice(8,-1)!='Object'){
// return new Error('the arguments must be Object!')
// }
const newObj={}
for(let prop in obj){
if(obj.hasOwnProperty(prop)){
newObj[prop]=obj[prop]
}
}
return newObj
}
- 深拷贝
深拷贝开辟一个新的栈,两个对象属性完全相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性 - 深拷贝的实现
function deepClone(obj,hash=new WeakMap()){
if(obj===null) return obj
if(Object.prototype.toString.call(obj).slice(8,-1)==='Date') return new Date(obj)
if(Object.prototype.toString.call(obj).slice(8,-1)==='RegExp') return new RegExp(obj)
if(Object.prototype.toString.call(obj).slice(8,-1)==='Object') return obj
if(hash.get(obj)) return hash.get(obj)
let cloneObj=new obj.constructor()
hash.set(obj,cloneObj)
for(let key in obj){
if(obj.hasOwnProperty(key)){
cloneObj[key]=deepClone(obj[key],hash)
}
}
return cloneObj
}
es6:如何理解ES6中的Promise?使用场景?
Promise,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强打
Promise解决异步操作的优点:
- 链式操作减低了编码难度
- 代码可读性明显增强
- 三个状态
pending
fulfilled
rejected
- 状态改变,就不会再变,专一
- then()是实例状态发生改变时的回调函数,第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数
- catch()指发生错误时的回调函数
- finally()不管Promise对象最后状态如何,都会执行的操作
- all()方法用于将多个Promise实例,包装成一个新的Promise实例
- 同时变为fulfilled,才会fulfilled传递回调函数
- 有一个rejected,便rejected
- race()是返回最快的那个实例的回调函数
- resolve() 将现有对象转为
Promise
对象
使用场景
- 将图片的加载写成一个
Promise
,一旦加载完成,Promise的状态就发生变化
const preloadImage = function (path) {
return new Promise(function (resolve, reject) {
const image = new Image();
image.onload = resolve;
image.onerror = reject;
image.src = path;
});
};
- 通过all()实现多个请求合并在一起,汇总所有请求结果,只需设置一个loading即可
function initLoad(){
// loading.show() //加载loading
Promise.all([getBannerList(),getStoreList(),getCategoryList()]).then(res=>{
console.log(res)
loading.hide() //关闭loading
}).catch(err=>{
console.log(err)
loading.hide()//关闭loading
})
}
//数据初始化
initLoad()
- 通过race设置图片请求超时
//请求某个图片资源
function requestImg(){
var p = new Promise(function(resolve, reject){
var img = new Image();
img.onload = function(){
resolve(img);
}
//img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg"; 正确的
img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg1";
});
return p;
}
//延时函数,用于给请求计时
function timeout(){
var p = new Promise(function(resolve, reject){
setTimeout(function(){
reject('图片请求超时');
}, 5000);
});
return p;
}
Promise
.race([requestImg(), timeout()])
.then(function(results){
console.log(results);
})
.catch(function(reason){
console.log(reason);
});
vue:如何理解v-show和v-if
- v-show和v-if的区别
- v-show是
display:none
,dom元素还在 - v-if是将dom元素整个添加或删除
- v-show不会触发生命周期,v-if会触发组件的生命周期
- v-if又更高的切换消耗
- v-show是
- v-show和v-if的使用场景
- v-if和v-show都能控制dom元素在页面的显示
- v-if相比v-show开销更大
- 如果需要非常频繁地切换,则使用v-show较好
- 如果在运行时条件很少改变,则使用v-if较好