javascript
1、什么是防抖和节流,他们的应用场景有哪些
防抖:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间
示例代码:
function debounce(fn,wait){
let timer;
return function(...args){
let _this=this;
if(timer){
clearTimeout(timer)
}
timer=setTimeout(() => {
fn.apply(_this,args)
}, wait);
}
}
window.onresize = debounce(function() {console.log('resize')}, 500)
应用场景:
a、登录、发短信等按钮避免用户点击太快,以致于发送了多次请求,需要防抖
b、调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位,就用到了防抖
c、文本编辑器实时保存,当无任何更改操作一秒后进行保存
节流:高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率
示例代码:
function throttle(fn,wait){
let preTime=Date.now();
return function(...args){
let _this=this;
let nowTime=Date.now();
if(nowTime-preTime>=wait){
fn.apply(_this,args)
preTime=Date.now();
}
}
}
应用场景:
a、懒加载、滚动加载、加载更多或监听滚动条位置;
b、百度搜索框,搜索联想功能;
c、防止高频点击提交,防止表单重复提交;
2、对象深度克隆的简单实现
function deepClone(object){
if(!object||typeof object !=='object') return;
let newObject=Array.isArray(object)? []:{};
for(let key in object){
if(object.hasOwnProperty(key)){
newObject[key]=
typeof object[key]==='object'? deepClone(object[key]):object[key]
}
}
return newObject;
}
3、实现一个 once 函数,传入函数参数只执行一次
function once(fun){
let tag=true;
return function(...args){
if(tag===true){
fun.apply(null,args)
tag=false
}
return undefined;
}
}
4、实现一个bind函数
Function.prototype.myBind=function(context){
if(typeof this!=='function'){
throw new TypeError('Error');
}
let args=[...arguments].slice(1), //或者Array.prototype.slice.call(arguments,1)
fn=this;
return function Fn(){
return fn.apply(this instanceof Fn? this:context,args.concat(...arguments))
}
}
5、实现一个sleep函数
/**
* promise
*/
function sleep(ms){
let temple=new Promise(resolve=>{
setTimeout(resolve,ms)
})
return temple;
}
sleep(2000).then(()=>{
console.log('开始执行')
})
/**
* async
*/
function sleep2(ms){
return new Promise(resolve=>{
setTimeout(resolve,ms);
})
}
async function test(){
let temple=await sleep2(2000)
console.log('开始执行,async')
return temple;
}
test()
/**
* generate
*/
function *sleep3(ms){
yield new Promise(resolve=>{
setTimeout(resolve,ms);
})
}
sleep3(2000).next().value.then(function(){
console.log('开始执行,generate')
})
6、手写一个简单的promise
function myPromise(constructor){
let self=this;
self.status='pending'
self.value=undefined
self.reason=undefined
function resolve(value){
//两个==='pending',保证了状态的改变是不可逆的
if(self.status==='pending'){
self.value=value;
self.status='resolved'
}
}
function reject(reason){
//两个==='pending',保证了状态的改变是不可逆的
if(self.status==='pending'){
self.reason=reason;
self.status='rejected';
}
}
//捕获构造异常
try{
constructor(resolve,reject);
}catch(e){
reject(e)
}
}
myPromise.prototype.then=function(onFullfilled,onRejected){
let self=this;
switch(self.status){
case "resolved":
onFullfilled(self.value);
break;
case "rejected":
onRejected(self.reason);
break;
default:
}
}
var p=new myPromise(function(resolve,reject){resolve(1)});
p.then(function(x){console.log(x)})
7、js实现全排列算法(给定一个字符串,输出该字符串所有排列的可能。如输入“abc”,输出“abc,acb,bca,bac,cab,cba”)
function permutate(str) {
var result = [];
if (str.length > 1) {
//遍历每一项
for (var m = 0; m < str.length; m++) {
//拿到当前的元素
var left = str[m];
//除当前元素的其他元素组合
var rest = str.slice(0, m) + str.slice(m + 1, str.length);
//上一次递归返回的全排列
var preResult = permutate(rest);
//组合在一起
for (var i = 0; i < preResult.length; i++) {
var tmp = left + preResult[i]
result.push(tmp);
}
}
} else if (str.length == 1) {
result.push(str);
}
return result;
}
console.log(permutate('abcd'))
8、使用闭包实现一个单例模式
单例模式的定义: 保证一个类仅有一个一个实例,并提供一个访问它的全局访问点。
应用场景:
单例模式能在合适的时候创建对象,并且创建唯一的一个。
代码接近于生活,很有意思。比如一个网站的登录,点击登录后弹出一个登录弹框,即使再次点击,也不会再出现一个相同的弹框。又或者一个音乐播放程序,如果用户打开了一个音乐,又想打开一个音乐,那么之前的播放界面就会自动关闭,切换到当前的播放界面。这些都是单例模式的应用场景。
要实现一个单例模式,一个经典的方式是创建一个类,类中又一个方法能创建该类的实例对象,还有一个标记,记录是否已经创了过了实例对象。如果对象已经存在,就返回第一次实例化对象的引用。
代码示例:
var Singleton = (function () {
var instance;
var CreateSingleton = function (name) {
this.name = name;
if (instance) {
return instance;
}
// 打印实例名字
this.getName();
// instance = this;
// return instance;
return instance = this;
}// 获取实例的名字
CreateSingleton.prototype.getName = function() {
console.log(this.name)
}
return CreateSingleton;
})();
// 创建实例对象 1
var a = new Singleton('a');
// 创建实例对象 2
var b = new Singleton('b');
console.log(a===b) //true