javascript面试必备知识(5)手撕js面试常见题型 以你之姓@ 2022-11-28 00:41 137阅读 0赞 **js面试必备知识,关注作者查看系列js知识体系** 导语:这一章来直接手撕web前端js面试常见题! ### 本文的目录 ### * * 1,手写深拷贝函数 * 2,利用apply手写一个bind函数,bind函数返回什么东西? * 3,settimeout和setinterval区别,怎么让settimeout执行完再进行一个操作? * 4,手写简单的jQuery,需要考虑插件和扩展性。 * 5,数组去重。 * 6,splice函数和slice函数的区别 * 7,一分钟解决瀑布流布局 ## 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,一分钟解决瀑布流布局 ## 我总结在另外一篇博文里面了,请赐教!! [一分钟解决瀑布流布局,小白也能看懂][Link 1] *感谢阅读,持续更新中。。。* [Link 1]: https://blog.csdn.net/gitchatxiaomi/article/details/108080099
还没有评论,来说两句吧...