js面试必备知识,关注作者查看系列js知识体系
导语:这一章来直接手撕web前端js面试常见题!
1,手写深拷贝函数
function deepClone(obj ={}) {
if (typeof obj !== 'object' || obj == {}) {
return obj
}
let result
if (obj instanceof Array) {
result = []
} else {
result = {}
}
for (let key in obj) {
if (obj.hasOwmproperty(key)) {
result[key] = deepClone(obj[key])
}
}
return result
}
2,利用apply手写一个bind函数,bind函数返回什么东西?
bind函数返回的是一个函数,需要手动去执行。
//给function的显式原型添加一个bind1函数
Function.prototype.bind1 = function () {
const args = Array.prototype.slice.call(arguments) //转变成数组
const that = args.shift() //将第一项的this拿出来
const self = this //获取调用这个bind1的函数
//返回一个函数
return function () {
return self.apply(that, args)
}
}
function fun1(a, b) {
console.log('this', this)
console.log(a, b)
return 'fun1'
}
const fun2 = fun1.bind1({x: 100}, 10, 20) //劫持
const res = fun2() //手动执行
console.log(res)
3,settimeout和setinterval区别,怎么让settimeout执行完再进行一个操作?
setTimeout和setInterval都属于JS中的定时器,可以规定延迟时间再执行某个操作,不同的是setTimeout在规定时间后执行完某个操作就停止了,而setInterval则可以一直循环下去。
// 封装成一个函数(settimeout后后续操作),参数分别是执行的次数,需要settimeout的函数,延迟几秒
function settimeoutdo(num,fn,delay){
var counter = 0;
var d = jQuery.Deferred();
var doIncrease = function() {
if(counter < num){
counter++;
setTimeout(fn, delay); //执行需要settimeout的函数
setTimeout(doIncrease, delay);
} else {
d.resolve();
}
};
doIncrease();
return d.promise();
};
settimeoutdo(1,() => {console.log('123')},1000).then(function() {
console.log(456);
});
4,手写简单的jQuery,需要考虑插件和扩展性。
class jQuery {
constructor(selector) {
const result = document.querySelectorAll(selector);
const length = result.length;
for (let i = 0; i < length; i++) {
this[i] = result[i];
}
this.length = length;
this.selector = selector;
}
get(index) {
return this[index];
}
each(fn) {
for (let i = 0; i < this.length; i++) {
const elem = this[i];
fn(elem);
}
}
on(type, fn) {
return this.each((elem) => {
elem.addEventListener(type, fn, false);
});
}
}
// const $p = new jQuery('p')
// $p.get(1)
// $p.each((elem) => console.log(elem.nodeName))
// $p.on('click', () => alert('clicked'))
// 插件
jQuery.prototype.dialog = function (info) {
alert(info);
};
// const $p = new jQuery('p')
// $p.dialog('dialog')
// "造轮子"
class myJQuery extends jQuery {
constructor(selector) {
super(selector);
}
// 扩展自己的方法
addClass(className) {
this.each((elem) => elem.classList.add(className));
}
style(data) {
this.each((elem) => elem.classList.add(style));
}
}
// const $p = new myJQuery('p')
// $p.addClass('test')
5,数组去重。
//n方时间复杂度
function newarr(arr){
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); //如果arr[i]等于arr[j],splice方法删除arr[j]
j--;
}
}
}
return arr;
}
var arr = [3,4,5,4,2,5,6,8,2,3,1];
console.log(newarr(arr))
// n时间复杂度,但是占用了新的内存
function newarr(arr){
var newarr = [];
for(var i = 0; i < arr.length; i++){
if (newarr.indexOf(arr[i]) == -1){
newarr.push(arr[i])
};
}
return newarr;
}
var arr = [3,4,5,4,2,5,6,8,2,3,1];
console.log(newarr(arr))
//用set对象的特性给数组去重
let a = [3,4,5,4,2,5,6,8,2,3,1];
let b = new Set(a);
b = [...b];
console.log(b)
6,splice函数和slice函数的区别
splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。
ps:该方法会改变原始数组。
例子:arr.splice(1,1) //删除从第二个元素开始的一个元素。
slice() 方法可提取字符串或者数组的某个部分,并以新的字符串或者数组返回被提取的部分。
ps:该方法不会改变原始字符串或者数组,而且还会产生一个新的字符串或者数组。
例子:newstr = str.slice(1,10) //提取从第二个元素到10个元素到newstr,共9个元素。
7,一分钟解决瀑布流布局
我总结在另外一篇博文里面了,请赐教!!
一分钟解决瀑布流布局,小白也能看懂
感谢阅读,持续更新中。。。
转载:https://blog.csdn.net/gitchatxiaomi/article/details/108036594
查看评论