八股文丨手撕代码:JavaScript基础(持续更新)

手写防抖

定时器版本

// 函数防抖的实现
functiion debounce(fn,wait){
	let timer = null;
		return function(){
			let context = this,
			args = [...arguments];
		 // 如果此时存在定时器的话,则取消之前的定时器重新记时
		if(timer){
			clearTimeout(timer);
			timer = null;
		}
		// 设置定时器,使事件间隔指定事件后执行
		timer = setTimeout(()=>{
			fn.apply(context,args);
		},wait)
	}
}

手写节流

时间戳版本

// 函数节流的实现;
function throttle(fn,delay){
	let pertime = Date.now();
	return function(){
		let context = this,
			args =  [...arguments],
			nowtime = Date.now();
		 // 如果两次时间间隔超过了指定时间,则执行函数。
		if(nowtime - pertime > delay){
			pertime = Date.now();
			return fn.apply(context,args);
		}
	}
}

定时器版本

function throttle(fn,delay){
	let timer = null;
	return function(){
		let context = this,
		   args = [...arguments];
		if(!timer){
			timer = setTimeout(()=>{
				timer = null;
				fn.apply(context,args);
			},delay)
		}
	}

}

手写浅拷贝

function shallowCopy(object){
 // 只拷贝对象
	if(!object||typeof object !== "obeject"){
		return;
	}
	
  // 根据 object 的类型判断是新建一个数组还是对象
	let newObject = Array.isArray(object)?[]:{};
	// 遍历 object,并且判断是 object 的属性才拷贝
	for(let key in object){
		if(object.hasOwnProperty(key)){
			newObject[key] = object[key];
		}
	}
	return newobject;
}

手写深拷贝

function deepcopy(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' ? deepcopy(object[key]):object[key]
		}
	}
	return newobject;
}

手写instanceof方法

function myInstanceof(left,right){
	// 获取对象的原型
	let proto = Object.getPropertyOf(left);
	// 获取构造函数的 prototype 对象
	let prototype = right.prototype;
	 // 判断构造函数的 prototype 对象是否在对象的原型链上
	while(true){
		if(!proto){ return false; }
		if(proto == prototype){ return true;  }
		proto = proto.getPropertyOf(proto);
	}
}

手写new方法

function objectFactory(){
	let newobject = null,
		result = null;
	let constructor = Array.prototype.shift.call(arguments);
	// 判断参数是否是一个函数
	if(typeof constructor !== 'function'){
		console.log('type error');
		return;
	}
	 // 新建一个空对象,对象的原型为构造函数的 prototype 对象
	newobject = Object.create(constructor.prototype);
	 // 将 this 指向新建对象,并执行函数
	result = constructor.apply(newobject,arguments);
	// 判断返回对象
	let flag = result &&(typeof result ==='object'||typeof result ==='function');
	 // 判断返回结果
	return flag?result:newobject;
}
// 使用方法
objectFactory(构造函数, 初始化参数);

手写call

function.prototype.myCall = function(context){
 	// 判断调用对象
	if(typeof this !== 'function'){
		 console.error("type error");
	}
	// 获取参数
	let args = [...arguments].slice(1);
	let result = null;
	// 判断 context 是否传入,如果未传入则设置为 window
	context = context || window;
	// 将调用函数设为对象的方法
	context.fn = this;
	// 调用函数
	result = context.fn(...args);
	delete context.fn;
	return result;
}

手写apply

function.prototype.myApply = function(context){
	 // 判断调用对象是否为函数
  if (typeof this !== "function") {
    throw new TypeError("Error");
  }
	let result = null;
	 // 判断 context 是否存在,如果未传入则为 window
	context = context || window;
	 // 将函数设为对象的方法
	context.fn = this.
	 // 调用方法
	if(arguments[1]){
		result = context.fn(...arguments[1]);
	}
	else{
		result = context.fn()'
	}
	 // 将属性删除
	delete context.fn;
	return result;
}

手写bind

function.prototype.myBind = function(context){
	 // 判断调用对象是否为函数
  if (typeof this !== "function") {
    throw new TypeError("Error");
  }
  let fn = this;
  // 获取参数
  let args = [...arguments].slice(1)
  return function Fn(){
   // 根据调用方式,传入不同绑定值
		return fn.apply(
			this instanceof Fn ? this:context,
			args.concat(...arguments)
		)
	}
}

手写Object.create

function create(obj){
	function fn(){};
	fn.prototype = obj;
	return new fn();
}

手写类型判断

function getType(value){
	//判断数据是null的情况
	if(value===null){
		return value+'';
	}
	//判断数据是引用数据类型的情况
	if(typeof value ==="object"){
		//用Object.prototype.toString方法去判断
		//返回值是一个字符串,格式 "[object 类型名]"
		let valueClass=Object.prototype.toString.call(value);
		let type=valueClass.split(" ")[1].split("");
		type.pop();//把]弹出去
		return type.join("").toLowerCase();
	}else{
		// 判断数据是基本数据类型的情况和函数的情况
		return typeof value;
	}
}

手写AJAX请求

const SERVER_URL = "/server";
let xhr = new XMLHttpRequest();
// 创建 Http 请求
xhr.open("GET", SERVER_URL, true);
// 设置状态监听函数
xhr.onreadystatechange = function() {
  if (this.readyState !== 4) return;
  // 当请求成功时
  if (this.status === 200) {
    handle(this.response);
  } else {
    console.error(this.statusText);
  }
};
// 设置请求失败时的监听函数
xhr.onerror = function() {
  console.error(this.statusText);
};
// 设置请求头信息
xhr.responseType = "json";
xhr.setRequestHeader("Accept", "application/json");
// 发送 Http 请求
xhr.send(null);

手写Promise

手写Promise.then

手写Promise.all

手写Promise.race

使用Promise封装AJAX

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值