JS中一些重要的api实现分析

发布时间:2021-11-06 11:34:49 作者:iii
来源:亿速云 阅读:183

本篇内容主要讲解“JS中一些重要的api实现分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JS中一些重要的api实现分析”吧!

一、用ES5实现数组的map方法

核心要点:

1.回调函数的参数有哪些,返回值如何处理。

2.不修改原来的数组。

Array.prototype.MyMap = function(fn, context){  
var arr = Array.prototype.slice.call(this);//由于是ES5所以就不用...展开符了
  var mappedArr = [];
    for (var i = 0; i < arr.length; i++ ){ 
       if(!arr.hasOwnProperty(i))continue;
           mappedArr.push(fn.call(context, arr[i], i, this));
             }
               return mappedArr;
               }

二、用ES5实现数组的reduce方法

核心要点:

1、初始值不传怎么处理

2、回调函数的参数有哪些,返回值如何处理。

Array.prototype.myReduce = function(fn, initialValue) {
  var arr = Array.prototype.slice.call(this);
    var res, startIndex;
      res = initialValue ? initialValue : arr[0];
        startIndex = initialValue ? 0 : 1;
          for(var i = startIndex; i < arr.length; i++)
           { 
              res = fn.call(null, res, arr[i], i, this); 
               }
                 return res;
                 }

三、实现call/apply

思路: 利用this的上下文特性。

//实现apply只要把下一行中的...args换成args即可Function.prototype.myCall = 
function(context = window, ...args) {  let func = 
this;  let fn = 
Symbol("fn");  context[fn] = func;  let res = context[fn](...args);//重点代码,利用this指向,相当于context.caller(...args)  delete context[fn];  return res;}

四、实现Object.create方法(常用)
function create(proto) { 
   function F() {};
       F.prototype = proto;
     return new F();
 }
五、实现bind方法

核心要点:

1.对于普通函数,绑定this指向

2.对于构造函数,要保证原函数的原型对象上的属性不能丢失

Function.prototype.bind = function(context, ...args) {
    let self = this;//谨记this表示调用bind的数    
    let fBound = function() { 
    //this instanceof fBound为true表示构造函数的情况。new func.bind(obj)
            return self.apply(this instanceof fBound ? this : context || window, args);
    }
      fBound.prototype = Object.create(this.prototype);//保证原函数的原型对象上的属性不丢失
          return fBound;
   }

大家平时说的手写bind,其实就这么简单:)

六、实现new关键字

核心要点:

  1. 创建一个全新的对象,这个对象的__proto__要指向构造函数的原型对象

  2. 执行构造函数

  3. 返回值为object类型则作为new方法的返回值返回,否则返回上述全新对象

       function myNew(fn, ...args) {
    let instance = Object.create(fn.prototype);
    let res = fn.apply(instance, args);
    return typeof res === 'object' ? res: instance;
    }

七、实现instanceof的作用

核心要点:原型链的向上查找。

function myInstanceof(left, right) {
    let proto = Object.getPrototypeOf(left);
        while(true) {
       if(proto == null) return false;
              if(proto == right.prototype) return true;
      proto = Object.getPrototypeof(proto);
      }
    }

八、实现单例模式

核心要点: 用闭包和Proxy属性拦截

function proxy(func) { 
   let instance; 
      let handler = {
              constructor(target, args) {
  if(!instance) { 
                 instance = Reflect.constructor(fun, args);
    } 
    return instance;
  } 
}  
  return new Proxy(func, handler);
  }

九、实现数组的flat

方式其实很多,之前我做过系统整理,有六种方法,请参考:

JS数组扁平化(flat)方法总结

十、实现防抖功能

核心要点:

如果在定时器的时间范围内再次触发,则重新计时。

const debounce = (fn, delay) => { 
 let timer = null;
   return (...args) => { 
      clearTimeout(timer); 
     timer = setTimeout(() => { 
          fn.apply(this, args);
       }, 
      delay);
      };
    };

十一、实现节流功能

核心要点:

如果在定时器的时间范围内再次触发,则不予理睬,等当前定时器完成,才能启动下一个定时器。

const throttle = (fn, delay = 500) => {
  let flag = true;
    return (...args) => {    
    if (!flag) return;    
    flag = false;    
    setTimeout(() => {      
    fn.apply(this, args);      
    flag = true;   
     }, delay);
     };
    };

十二、用发布订阅模式实现EventEmit
十三、实现深拷贝

以下为简易版深拷贝,没有考虑循环引用的情况和Buffer、Promise、Set、Map的处理,如果一一实现,过于复杂,面试短时间写出来不太现实,如果有兴趣可以去这里深入实现:

深拷贝终极探索。

const clone = 
parent => {  // 判断类型  const isType =  (target, type) => `[object ${type}]` === Object.prototype.toString.call(target)  // 处理正则  const getRegExp = re => {    let flags = 
"";    if (re.global) flags += 
"g";    if (re.ignoreCase) flags += 
"i";    if (re.multiline) flags += 
"m";    return flags;  };  const _clone = 
parent => {    if (parent === 
null) 
return null;    if (typeof 
parent !== 
"object") 
return parent;    let child, proto;    if (isType(parent, 
"Array")) {      // 对数组做特殊处理      child = [];    } 
else if (isType(parent, 
"RegExp")) {      // 对正则对象做特殊处理      child = 
new RegExp(parent.source, getRegExp(parent));      if (parent.lastIndex) child.lastIndex = 
parent.lastIndex;    } 
else if (isType(parent, 
"Date")) {      // 对Date对象做特殊处理      child = 
new Date(parent.getTime());    } 
else {      // 处理对象原型      proto = Object.getPrototypeOf(parent);      // 利用Object.create切断原型链      child = Object.create(proto);    }    for (let i in 
parent) {      // 递归      child[i] = _clone(parent[i]);    }    return child;  };  return _clone(parent);};

到此,相信大家对“JS中一些重要的api实现分析”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

推荐阅读:
  1. ListView 一些重要属性详解
  2. 关于JS中一些重要的api实现,巩固你的原生JS功底

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

js api

上一篇:PXC5.7版本集群如何安装使用

下一篇:MySQL5.6中新增特性、不推荐使用的功能以及废弃的功能有哪些

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》