高频重要前端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
对于普通函数,绑定this指向
对于构造函数,要保证原函数的原型对象上的属性不能丢失
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的实现
函数的柯里化
高频重要前端API手写整理(call,apply,bind,instanceof,flat,filter,new,防抖,节流,深浅拷贝,数组乱序,数组去重,继承, lazyman,jsonp的实现,函数的柯里化 )的更多相关文章
- JS 函数的柯里化与反柯里化
===================================== 函数的柯里化与反柯里化 ===================================== [这是一篇比较久之前的总 ...
- 关于arguments对象以及函数的柯里化;
1.arguments对象 Arguments是个类似数组但不是数组的对象,说他类似数组是因为其具备数组相同的访问性质及方式,能够由arguments[n]来访问对应的单个参数的值,并拥有数组长度属性 ...
- 浅析 JavaScript 中的 函数 currying 柯里化
原文:浅析 JavaScript 中的 函数 currying 柯里化 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字 ...
- Scala_方法、函数、柯里化
方法.函数.柯里化 方法 声明方法: scala> def m1(x:Int,y:Int):Int = { | x + y | }m1: (x: Int, y: Int)Ints ...
- js高阶函数--判断数据类型、函数胡柯里化;
一.判断数据类型: 常见的判断有typeof.instanceof. constructor. prototype,先来看typeof: var a = "hello world" ...
- JavaScript函数式编程(纯函数、柯里化以及组合函数)
JavaScript函数式编程(纯函数.柯里化以及组合函数) 前言 函数式编程(Functional Programming),又称为泛函编程,是一种编程范式.早在很久以前就提出了函数式编程这个概念了 ...
- 前端开发者进阶之函数反柯里化unCurrying
函数柯里化,是固定部分参数,返回一个接受剩余参数的函数,也称为部分计算函数,目的是为了缩小适用范围,创建一个针对性更强的函数. 那么反柯里化函数,从字面讲,意义和用法跟函数柯里化相比正好相反,扩大适用 ...
- JavaScript函数的柯里化(currying)
转载请注明出处:http://www.cnblogs.com/shamoyuu/p/currying.html 什么是js函数的currying /柯里化? 说到js的柯里化,相信很多朋友都会头大.或 ...
- 理解运用JS的闭包、高阶函数、柯里化
JS的闭包,是一个谈论得比较多的话题了,不过细细想来,有些人还是理不清闭包的概念定义以及相关的特性. 这里就整理一些,做个总结. 一.闭包 1. 闭包的概念 闭包与执行上下文.环境.作用域息息相关 执 ...
随机推荐
- 3、myql的逻辑架构和sql的执行流程
msyql逻辑架构 逻辑架构的解析 逻辑架构图如下(序号代表的是:服务器处理客户端请求的流程) 1.1connectors connectors是指使用不同语言的客户端与mysql server服务器 ...
- LGP7915题解
奇怪的乱搞做法(? 首先我们枚举序列的每一个位置,从这个位置劈开,假设这个位置是 \(i\),那么按照题意模拟,我们能够构造一个最终序列有 \(i\) 个 L 和 \(n-i\) 个 R 的符合题意的 ...
- python+pytest接口自动化(10)-session会话保持
在接口测试的过程中,经常会遇到有些接口需要在登录的状态下才能请求,否则会提示请登录,那么怎样解决呢? 上一篇文章我们介绍了Cookie绕过登录,其实这就是保持登录状态的方法之一. 另外一种方式则是通过 ...
- java的https的get请求
package com.wl.webservice; import java.io.InputStream; import java.net.HttpURLConnection; import jav ...
- 利用公网Msf+MS17010跨网段攻击内网
其实很多小白在对利用msf进行ms17010攻击的时候总是不成功,其实这都是因为网上大部分的文章都是写的内网对内网(192.168.1.2-->192.168.1.3)这样的案例,今天写了一下利 ...
- DDOS防御----CENTOS 内核TCP参数优化
0x01 环境 attact作为攻击发起方,安装有hping server作为被攻击方,修改内核TCP参数.使用操作系统CENTOS7 0x02 步骤 一.发起攻击 修改TCP最大SYN连接数 使用a ...
- Redis运维实战之集群中的脑裂
1.对于分布式Redis主从集群来说,什么是脑裂? 所谓的脑裂,就是指在主从集群中,同时有两个主节点,它们都能接收写请求.而脑裂最直接的影响,就是客户端不知道应该往哪个主节点写入数据,结果就是不同的客 ...
- 解决Hadoop集群hdfs无法启动DataNode的问题
问题描述: 在hadoop启动hdfs的之后,使用jps命令查看运行情况时发现hdfs的DataNode并没有打开. 笔者出现此情况前曾使用hdfs namenode -format格式化了hdfs ...
- [源码解析] TensorFlow 分布式环境(5) --- Session
[源码解析] TensorFlow 分布式环境(5) --- Session 目录 [源码解析] TensorFlow 分布式环境(5) --- Session 1. 概述 1.1 Session 分 ...
- 通过R Studio用Markdown写Beamer
技术背景 在写一些学术演示文档时,经常有可能用到Beamer--一种Latex的学术风PPT模板,比如下图所示的这种: 这种风格的演示文档有几个明显的优点:简约.严肃.可以用Latex敲公式和推导.可 ...