• 高频重要前端API手写整理(call,apply,bind,instanceof,flat,filter,new,防抖,节流,深浅拷贝,数组乱序,数组去重,继承, lazyman,jsonp的实现,函数的柯里化 )


    Function.prototype.call = function(context,...args){
         var context = context || window;
         context.fn = this;
         var result = eval(`context.fn(...args)`);
         delete context.fn;
         return result;  
    }

    call的实质就是调用函数时候改变函数中this的指向,利用对象中函数调用时候 this指向这个对象的特性我们给函数加上fn属性,指向函数本身,然后调用这个函数。指向就变成了fn前面的context也就是call的第一个参数;

    Function.prototype.apply = function (context, args) {
      let context = context || window;
      context.fn = this;
      let result = eval('context.fn(...args)');
    
      delete context.fn
      return result;
    }
    

      

    apply同理 只是参数改变成为了数组

    bind 

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

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

    Function.prototype.bind = function (context, ...args) {
        // 异常处理
        if (typeof this !== "function") {
          throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
        }
        // 保存this的值,它代表调用 bind 的函数
        var self = this;
        var fNOP = function () {};
    
        var fbound = function () {
            self.apply(this instanceof self ? 
                        this : 
                        context, args.concat(Array.prototype.slice.call(arguments)));
        }
    
        fNOP.prototype = this.prototype;
        fbound.prototype = new fNOP();
    
        return fbound;
    }

    instanceOf

    用法是a instanceOf A  原理是通过 a 的原型链和A的原型来判断a是否是A的实例

     1 function instance_of(L, R){
     2      const baseType = ['string', 'number','boolean','undefined','symbol'];
     3     if(baseType.includes(typeof L)) return false
     4     
     5     let RP = R.prototype; // 取R的原型
     6      L = L.__proto__; // 取L的原型链
     7     while(true){
     8         if(L === null){
     9               return false;
    10         }
    11        if(L === RP){
    12                return true;
    13        }
    14       L = L.__proto__; // 没找到继续造
    15 
    16 }
    17 }

    flat : 利用递归,依次遍历

     Array.prototype.myFlat2 = function(arr){
         let newArr=[];
          
         (function flatArr(arr){
            arr.forEach((item,idx) => {
                if(typeof item != 'object'){
                    newArr.push(item)
                }else{
                    flatArr(arr[idx])
                }
            })
         })(arr)
         return newArr;
     }
     let a = [1,[1,2,3],[[1,23],[12,11]]];
     console.log(Array.prototype.myFlat2(a));

    filter

    filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。 
    
    Array.prototype.filter = function(fn){
       var _this;
      if (typeof fn !== "function") {
        throw "参数必须为函数";
      }
    
      //get array going to be iterated
      let arr = this;
      if (!Array.isArray(arr)) {
        throw "只能对数组使用forEach方法";
      }
    
      if (arguments.length > 1) {
        _this = thisArg;
      }
      let result = [];
    
      for (let index = 0; index < arr.length; index++) {
        let invokedReturn = fn.call(_this, arr[index], index, arr);
        if (invokedReturn) {
          result.push(arr[index]);
        }
      }
      return result;
    }

    new: js高级程序设计第四版中对于new的描述如下

    1. 在内存中创建一个新对象;

    2. 这个新对象内部的[[prototype]]特性被复制为构造函数的prototype属性

    3. 构造函数内部的this被赋值为这个新对象

    4. 执行构造函数内部代码

    5. 如果构造函数返回非空对象,则返回该对象,否则返回刚创建的实例

    function myNew(ctor, ...args){
      if(typeof ctor !='function'){
           throw 'newOperator function the first param must be a function';
      }
      let obj = new Object();
      obj.__proto__ = Object.create(ctor.prototype);  // 关键步骤1
      let res  = ctor.call(obj, ...args)// 关键步骤2
    if(result !== null && /^(object|function)$/.test(typeof res)){ return result } }

    防抖

    节流

    深浅拷贝

    数组乱序

    数组去重

    八种继承及各种继承之间的特点

    lazyman

    jsonp的实现

    函数的柯里化

  • 相关阅读:
    js递归函数和call()
    前端常用
    整理项目中用到的angularjs及其他js代码
    体验设计真的是让一切简单到极致吗?
    iview table中利用render动态循环输出
    Vue+iview在render函数中添加Poptip提示操作
    jQuery
    外部js调用vue实例方法
    es6 filter() 数组过滤方法总结
    vue通信、传值的多种方式
  • 原文地址:https://www.cnblogs.com/qqfontofweb/p/14890060.html
Copyright © 2020-2023  润新知