摘要:前端面试题精选函数实现应用首先什么是函数,直译记忆,缓存等意思,到了计算机层面就翻译为缓存函数,缓存函数就是把计算的结果,存在函数中,当再次调用的时候就可以直接调用。
前端面试题精选 1.memorize函数实现应用
首先什么是memorize函数,memorize直译:记忆,缓存等意思,到了计算机层面就翻译为缓存函数,缓存函数就是把计算的结果,存在函数中,当再次调用的时候就可以直接调用。这种方法就是用空间来换取时间
const memorize = function(fn) {
const cache = {}
return function(...args) { // 参数值,是一个数组,数组的值是需要计算的值
const _args = JSON.stringify(args)
return cache[_args] || (cache[_args] = fn.apply(fn, args))
// 缓存函数的核心判断依据,传入的键名对应的键值为null 则调用add方法 反之从cache中拿取
}
}
const add = function(a) {
return a + 1
}
const adder = memorize(add) // memorize只调用一次 后面adder调用的都是return的函数
adder(1) // 2 cache: { "[1]": 2 }
adder(1) // 2 cache: { "[1]": 2 }
adder(2) // 3 cache: { "[1]": 2, "[2]": 3 }
2. bind,apply,call的区别和实现
javascript 权威指南上的解释是: call()、apply()可以看做是某个对象的方法,通过调用方法的形式来间接调用函数。bind()就是将某个函数绑定到某个对象上。
var obj = {
x:1
}
function foo() {
console.log(this.x)
}
foo.call(obj) //1
call()和apply()的第一个参数相同,就是指定对象,他们的根本区别就在于传入的参数。
call传入参数形式为call(obj, 1, 2, 3)
apply传入参数形式为apply(obj, [1,2,3])
bind()方法和前两者不同在于:bind()方法会返回执行上下文被改变的函数,而不会立即执行,而前两者是直接执行该函数。他的参数和call()相同.
3.数组去重 去重方法有很多种,常用必需会写的几种去重方法有1. 遍历去重 2. json键名不唯一去重 3. new Set()去重3.1 遍历去重
let arr = [1, 2, 3, 4, 5, 6, 7, 7, 7, 3, 111, 1, 3]
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] == arr[j]) {
arr.splice(j, 1)
i = i - 1
}
}
}
3.2 json键名去重
let arr = [1, 2, 3, 4, 5, 6, 7, 7, 7, 3, 111, 1, 3]
let obj = {}
let result = []
for(let i = 0 ; i < arr.length; i++) {
obj[arr[i]] = null
}
for(let key in obj) {
result.push(key)
}
3.3 new Set()去重
let arr = [1, 2, 3, 4, 5, 6, 7, 7, 7, 3, 111, 1, 3]
let newArr = new Set(arr) // 返回一个set对象
let result = []
newArr.forEach(val => {
result.push(val)
})
4.数组扁平化
数组扁平化简单来说就是把一个多维数组变为一维数组,核心思想:
1.递归 2.数值toString() + split() 3.Array.prototype.flat(depth) // Infinity代表无限扁平
递归
function flatten(arr) {
var res = [];
arr.map(item => {
if(Array.isArray(item)) {
res = res.concat(flatten(item));
} else {
res.push(item);
}
});
return res;
}
数值的扁平化toString() + split()
let arr = [1,2,3,[2,3,4],45,7,[24,[2,3]]]
function flatten(arr) {
return arr.toString().split(",").map(val => {
return Number(val)
})
}
flat()
let arr = [1,2,3,[2,3,4],45,7,[24,[2,3]]]
arr.flat(infinity)
5.debounce和throttle的实现和使用场景
去抖动和节流,二者都是随着时间推移控制执行函数的次数来达到较少资源消耗,特别在事件触发上,尤为重要。
debounce的作用是,当调用动作触发一段时间后,才会执行该动作,若在这段时间间隔内又调用此动作则将重新计算时间间隔。
简单来说就是:调用会一直刷新动作,动作是被延迟执行,直到停止调用等待了一段时间后再执行动作。看下面简单debounce实现节流例子:
function easyDebounce(method, scope) {
clearTimeout(method.tId); // onresize会一直被触发,只要在100毫秒内被连续触发计时器都会刷新直到时间大于100毫秒
method.tId= setTimeout(function(){
method.call(scope);
}, 100);
}
function resizeDiv(){
var div = document.getElementById("myDiv");
div.style.height = div.offsetWidth + "px";
}
// 节流在resize事件中最常用
window.onresize = function(){
easyDebounce(resizeDiv);
};
throttle预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新的时间周期。throttle可以基于debounce实现,只需要加上一个阀值(最小值)如果时间小于定义的阀值 则不触发动作,大于则触发并刷新周期,而且第一次必定触发。节流不实用定时器,debounce使用定时器
var throttleV2 = function(action, delay){
var statTime = 0;
return function() { // 每次resize执行的函数 闭包保证statTime可以一直使用
var currTime = +new Date();
if (currTime - statTime > delay) {
action.apply(this, arguments);
statTime = currTime ; // 每次调用完之后刷新时间
}
}
}
// example
function resizeHandler() {
console.log("resize");
}
window.onresize = throttleV2(resizeHandler, 300);
6.vue数据双向绑定
vue实现数据的双向绑定根本API是Object.defineProperty(),通过这个方法重写get,和set属性来达到数据双向绑定
详细解读一下Object.defineProperty()这个东西到底干了啥
var Book = {}
var name = "";
Object.defineProperty(Book, "name", {
set: function (value) {
name = value;
console.log("书名:" + value);
},
get: function () {
return "《" + name + "》"
}
})
Book.name = "前端学习";
console.log(Book.name);
双向绑定是用发布订阅模式实现,所以涉及到监听器Observer、订阅者Watcher、解析器Compile,以及消息订阅器dep收集watcher。
图片来自互联网:
vue scoped的实现是通过在对应的dom节点添加data-v-哈希值,并在style每个属性后面加上这串data-v-hash来实现样式的唯一性,起到一个样式作用域的效果。
但是实际应用中添加scoped也会带来一些麻烦,比如设置完scoped属性之后无法修改子组件的样式。再次有两点供大家参考:
不用scoped属性,每个组件使用良好的命名规范,每个组件的根节点取唯一的类名。
使用scoped属性,在需要操作子组件样式的时候使用‘>>>’来修改子组件的节点样式。
持续更新中~~~
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/109525.html
摘要:收集的一些前端面试题从面试题发现不足,进而查漏补缺,比通过面试更难得及各大互联网公司前端笔试面试题篇及各大互联网公司前端笔试面试题篇面试题个和个经典面试题前端开发面试题如何面试前端工程师很重要个变态题解析如何通过饿了么面试轻 收集的一些前端面试题 从面试题发现不足,进而查漏补缺,比通过面试更难得 1 BAT及各大互联网公司2014前端笔试面试题--Html,Css篇 2 BAT...
摘要:收集的一些前端面试题从面试题发现不足,进而查漏补缺,比通过面试更难得及各大互联网公司前端笔试面试题篇及各大互联网公司前端笔试面试题篇面试题个和个经典面试题前端开发面试题如何面试前端工程师很重要个变态题解析如何通过饿了么面试轻 收集的一些前端面试题 从面试题发现不足,进而查漏补缺,比通过面试更难得 1 BAT及各大互联网公司2014前端笔试面试题--Html,Css篇 2 BAT...
摘要:获取的对象范围方法获取的是最终应用在元素上的所有属性对象即使没有代码,也会把默认的祖宗八代都显示出来而只能获取元素属性中的样式。因此对于一个光秃秃的元素,方法返回对象中属性值如果有就是据我测试不同环境结果可能有差异而就是。 花了很长时间整理的前端面试资源,喜欢请大家不要吝啬star~ 别只收藏,点个赞,点个star再走哈~ 持续更新中……,可以关注下github 项目地址 https:...
阅读 2587·2021-11-24 10:27
阅读 3781·2019-08-30 15:55
阅读 3539·2019-08-30 15:53
阅读 2542·2019-08-29 17:27
阅读 1629·2019-08-26 13:47
阅读 3734·2019-08-26 10:28
阅读 1144·2019-08-23 15:59
阅读 3069·2019-08-23 15:19