面试题(day1)
Opened this issue · 0 comments
robbiemie commented
1. css3特性中的transform:translateZ(0)有什么作用?
该属性可以利用 GPU 加速,提高浏览器的渲染性能。原理是 translateZ 的元素会单独占据一个渲染层;这样当元素发生改动时,浏览器的重绘区域减少,提升性能。
tips:
- 重排(reflow) : 对dom元素进行定位和布局
- 重绘(repaint): 绘制dom元素的样式,如颜色、背景、文字大小、边框等
动画优化技巧:
- 减少浏览器重排和重绘操作
- 不要使用 table 布局
- css 动画尽量使用 transform 和 opacity
- 避免使用 js 操作dom,实现动画
- 减少图片尺寸、优化 gpu 加载性能
参考文档:
2. 列举三种禁止浏览器缓存的头字段,并写出响应的设置值
tips:
- 缓存控制(cache-control): 是http/1.1定义的缓存策略。
- cache-control: 设置值包括:
no-store
: 没有缓存,不得缓存客户端请求和服务端响应的内容no-cache
: 缓存但重新验证,客户端会将请求带给服务端,服务端进行校验,若未过期(返回code:304),直接使用缓存内容max-age=<seconds>
: 过期机制,表示缓存的最大时长
- pragma: 是http/1.0定义的header属性。
- 缓存失效公式:
exirationTime = responseTime + freshnessLifetime - currentAge
3. 精确获取页面元素位置的方式有哪些
getBoundingClientRect()
方法:返回元素大小以及相对于视窗的位置。
返回的结果有:
- left
- top
- right
- bottom
- x
- y
- width
- height
除了 width 和 height 以外,其他属性值都是以视窗左上角来计算的。如果视窗发送滚动操作,则需要计算滚动位置,top
和left
发生了变化。此时,可以通过如下方式计算滚动后的相对位置:
// x
el.getBoundingClientRect().x + el.scrollLeft
// y
el.getBoundingClientRect().y + el.scrollTop
4. 正则从 2018-10-07T11:48:47 Asia/zh-cn
获取 [2018,10,07,11,48,47]
let str = '2018-10-07T11:48:47 Asia/zh-cn'
str.match(/\d+/g)
5. 如何判断 object 是数组类型
// 方法一
Array.isArray([]) // true
// 方法二
Object.prototype.toString.call([]) // [object Array]
编程题
1.已知数据结构users,请实现语法支持user.unique能够按照name字段去重,
并输出结构为:["a","b","v"]
var users=[{
id:1,name:"a"
},{
id:2,name:"a"
},{
id:3,name:"b"
},{
id:4,name:"v"
}]
2.已知如下对象,请基于es6的proxy方法设计一个属性拦截读取操作的例子,要求实现去访问目标对象example中不存在的属性时,抛出错误:Property "$(property)" does not exist
3.给出如下虚拟dom的数据结构,如何实现简单的虚拟dom,渲染到目标dom树
//样例数据
let demoNode = ({
tagName: 'ul',
props: {'class': 'list'},
children: [
({tagName: 'li', children: ['douyin']}),
({tagName: 'li', children: ['toutiao']})
]
});
//构建一个render函数,将demoNode对象渲染为以下dom
<ul class="list">
<li>douyin</li>
<li>toutiao</li>
</ul>
题解
1.已知数据结构users,请实现语法支持user.unique能够按照name字段去重,
并输出结构为:["a","b","v"]
var users=[{
id:1,name:"a"
},{
id:2,name:"a"
},{
id:3,name:"b"
},{
id:4,name:"v"
}]
// 解法一
// 常规解法
Array.prototype.unique = function () {
console.log(this)
if(!this || !Array.isArray(this)) return []
let uniqueMap = {}
this.forEach(item=>{
uniqueMap[item.name] = item.name
})
return Object.keys(uniqueMap)
}
// 解法二
// 使用 ES6 Map
Array.prototype.unique = function () {
console.log(this)
if(!this || !Array.isArray(this)) return []
let uniqueMap = new Map()
this.forEach(item => {
uniqueMap.set(item.name, item.name)
})
let values = []
for (let [key, value] of uniqueMap) {
values.push(key)
}
return values
}
// 解法三
// 使用 ES6 Set
Array.prototype.unique = function () {
console.log(this)
if(!this || !Array.isArray(this)) return []
let uniqueSet = new Set()
this.forEach(item => {
uniqueSet.add(item.name)
})
let values = [...uniqueSet]
return values
}
var users=[{
id:1,name:"a"
},{
id:2,name:"a"
},{
id:3,name:"b"
},{
id:4,name:"v"
}]
let value = users.unique() // ["a","b","v"]
2.已知如下对象,请基于es6的proxy方法设计一个属性拦截读取操作的例子,要求实现去访问目标对象example中不存在的属性时,抛出错误:Property "$(property)" does not exist
const man={
name:'jscoder',
age:22
}
//补全代码
const proxy = new Proxy(man, {
get(target, key) {
if(target[key]) {
return target[key]
}
return `Property "$(${key})" does not exist`
}
})
let a = proxy.name //"jscoder"
let b = proxy.age //22
let c = proxy.location //Property "$(property)" does not exist
console.log(a)
console.log(b)
console.log(c)
3.给出如下虚拟dom的数据结构,如何实现简单的虚拟dom,渲染到目标dom树
//样例数据
let demoNode = ({
tagName: 'ul',
props: {'class': 'list'},
children: [
({tagName: 'li', children: ['douyin']}),
({tagName: 'li', children: ['toutiao']})
]
});
//构建一个render函数,将demoNode对象渲染为以下dom
<ul class="list">
<li>douyin</li>
<li>toutiao</li>
</ul>
let demoNode = ({
tagName: 'ul',
props: {'class': 'list'},
children: [
({tagName: 'li', children: ['douyin']}),
({tagName: 'li', children: ['toutiao']})
]
});
function createElement (tagName,props) {
let el = document.createElement(tagName)
props && Object.keys(props).forEach(key => {
if(props[key]) {
el.setAttribute(key, props[key])
}
})
return el
}
function createTextNode(text) {
return document.createTextNode(text)
}
function searchVNode (vnode) {
if(!vnode) throw new Error("参数不能为空")
if(typeof vnode === 'string') {
return createTextNode(vnode)
}
let parentNode = createElement(vnode.tagName, vnode.props)
vnode.children.forEach( childVNode => {
let childNode = searchVNode(childVNode)
parentNode.appendChild(childNode)
})
return parentNode
}
searchVNode(demoNode)
//构建一个render函数,将demoNode对象渲染为以下dom
{/* <ul class="list">
<li>douyin</li>
<li>toutiao</li>
</ul> */}