1 手写bind call apply
解 这三个都是js自带的方法,三兄弟的作用都是在函数中改变this的指向
call
Function.prototype.call = function(context){
const cxt = context || window;
cxt.func = this;
const args = Array.from(arguments).slice(1);
const res = arguments.length > 1 ? cxt.func(...args) : cxt.func();
delete cxt.func;
return res;
}
apply
Function.prototype.apply = function(context){
const cxt = context || window;
cxt.func = this;
const res = arguments[1] > 1 ? cxt.func(...arguments[1]) : cxt.func();
delete cxt.func;
return res;
}
bind
Function.prototype.bind = function(context){
const cxt = JSON.parse(JSON.stringify(context)) || window;
cxt.func = this;
const args = Array.from(arguments).slice(1);
return function(){
const allArgs = args.concat(Array.from(arguments));
return allArgs.length > 0 ? cxt.func(...allArgs) : cxt.func();
}
}
2 手写节流 防抖
不清楚节流和防抖的可以去看我前面的博文
节流
function throttle(fn,delay) {
let time = null;
return function (){
if(!time){
time = setTimeout(() =>{
time = null;
fn.apply(this, arguments);
},delay)
}
}
}
防抖
function debounce(fn) {
let timeout = null; // 创建一个标记用来存放定时器的返回值
return function () {
clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉
timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
fn.apply(this, arguments);
}, 500);
};
}
3 手写ajax
原生请求写法
var data = new FormData();
data.append("name",name);
data.append("gender",gender);
data.append("age",age);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(JSON.parse(xhr.responseText)["code"] == 200){
alert("返回成功");
}else{
alert(JSON.parse(xhr.responseText)["msg"]);
}
}
}
xhr.send(data);
4 手写深拷贝 不清楚深拷贝和浅拷贝的可以看我之前的博文
function ArrayCopy(obj = {}){
if(typeof obj !== "object" || obj === null){
return obj;
}
var agent;
if(obj instanceof Array){
agent = [];
}else{
agent = {};
}
for(let key in obj){
agent[key] = ArrayCopy(obj[key]);
}
return agent
}
5 手写对象比较
function isObject (data) {
return typeof data === 'object' && data !== null
}
function isEqual (obj1, obj2) {
if (!isObject(obj1) || !isObject(obj2)) {
return obj1 === obj2
}
if (obj1 === obj2) {
return true
}
const obj1Keys = Object.keys(obj1)
const obj2Keys = Object.keys(obj2)
if (obj1Keys.length !== obj2Keys.length) {
return false
}
for (let key in obj1) {
const res = isEqual(obj1[key], obj2[key])
if (!res) {
return false
}
}
return true
}
isEqual(obj1, obj2)
6 画出原型链图
7 手写trim考虑兼容性
if(!String.prototype.trim){
String.prototype.trim = function(){
return this.replace(/^\s+/,'').replace(/\s+$/,'')
}
}
8 手写清除浮动clearfix
clearfix:after
{
content:",";
height:0;
display:block;
visibility:hidden;
clear:both;
}