# 第 71 - 80 题
# 71、实现一个字符串匹配算法,从长度为 n 的字符串 S 中,查找是否存在字符串 T,T 的长度是 m,若存在返回所在位置。
const find = (S, T) => {
if (S.length < T.length) return -1
for (let i = 0; i < S.length; i++) {
if (S.slice(i, i + T.length) === T) return i
}
return -1
}
# 72、为什么普通 for 循环的性能远远高于 forEach 的性能,请解释其中的原因
其中forEach 里操作了toObject 以及判断是否终止循环条件比for loop 复杂一点。
# 73、介绍下 BFC、IFC、GFC 和 FFC
BFC 块级格式化上下文
就是页面上的一个隔离的渲染区域,容器里面的子元素不会在布局上影响到外面的元素,反之也是如此。
IFC 内联格式化上下文
GFC 内联格式化上下文
FFC 自适应格式上下文
# 74、使用 JavaScript Proxy 实现简单的数据绑定
const obj = {
a: 1
}
new Proxy(obj, {
set: function (target, key, value) {
target[key] = value;
return true;
}
})
# 75、数组里面有10万个数据,取第一个元素和第10万个元素的时间相差多少
复杂度都是O(1);
性能差异忽略不计。
# 76、输出以下代码运行结果
// example 1
var a={}, b='123', c=123;
a[b]='b';
a[c]='c';
console.log(a[b]);
// 输出 'c'
---------------------
// example 2
var a={}, b=Symbol('123'), c=Symbol('123');
a[b]='b';
a[c]='c';
console.log(a[b]);
// 输出 'b'
---------------------
// example 3
var a={}, b={key:'123'}, c={key:'456'};
a[b]='b';
a[c]='c';
console.log(a[b]);
// 输出 'c'
# 77、算法题「旋转数组」
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例1:
输入: [1, 2, 3, 4, 5, 6, 7] 和 k = 3
输出: [5, 6, 7, 1, 2, 3, 4]
解释:
向右旋转 1 步: [7, 1, 2, 3, 4, 5, 6]
向右旋转 2 步: [6, 7, 1, 2, 3, 4, 5]
向右旋转 3 步: [5, 6, 7, 1, 2, 3, 4]
示例 2:
输入: [-1, -100, 3, 99] 和 k = 2
输出: [3, 99, -1, -100]
解释:
向右旋转 1 步: [99, -1, -100, 3]
向右旋转 2 步: [3, 99, -1, -100]
function rotateArr(arr, k) {
return [...arr.splice(-(k % arr.length)), ...arr];
}
# 78、Vue 的父组件和子组件生命周期钩子执行顺序是什么
父组建: beforeCreate -> created -> beforeMount 子组件: -> beforeCreate -> created -> beforeMount -> mounted 父组件: -> mounted 总结:从外到内,再从内到外
# 79、input 搜索如何防抖,如何处理中文输入
throttle - 节流 debounce - 防抖
function throttle(fn, delay) {
let last = 0;
return function () {
let now = Date.now();
if (now - last > delay) {
fn();
last = now;
}
}
}
function throttle(fn, delay) {
let time;
return function () {
if (time) return;
time = setTimeout(() => {
fn();
time = null;
}, delay);
}
}
function debounce(fn, delay) {
let timer;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
fn();
}, delay);
}
}
输入中文
<input
ref="input"
@input="handleInput"
@compositionstart="handleComposition"
@compositionupdate="handleComposition"
@compositionend="handleComposition"
>
执行顺序触发
简单来说就是切换中文输入法时在打拼音时(此时input内还没有填入真正的内容),
会首先触发compositionstart
然后每打一个拼音字母,触发compositionupdate,
触发input事件 (核心的就是在update中告诉input事件在输入中文,做参数控制)
最后将输入好的中文填入input中时触发compositionend。
触发compositionstart时,文本框会填入 “虚拟文本”(待确认文本),同时触发input事件;在触发compositionend时,就是填入实际内容后(已确认文本),所以这里如果不想触发input事件的话就得设置一个bool变量来控制。
function onCompositionStart(e){
e.target.composing = true;
}
function onCompositionEnd(e){
//console.log(e.target)
e.target.composing = false;
var event = document.createEvent('HTMLEvents');
event.initEvent('input');
e.target.dispatchEvent(event);
}