高频重要前端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的实现

函数的柯里化

原文地址:https://www.cnblogs.com/qqfontofweb/p/14890060.html