高频重要前端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. 闭包的概念 闭包与执行上下文.环境.作用域息息相关 执 ...
随机推荐
- 微信小程序表单验证(WxValidate使用)
参考博客: https://www.cnblogs.com/zhangxiaoyong/p/10166951.html https://github.com/wux-weapp/wx-extend/b ...
- laravel 7 H-ui模板ajax批删
1,HTML页面写一个button按钮 <a href="javascript:;" onclick="deleteAll()" class=" ...
- 禁用 Windows 共享服务,释放 445 端口
禁用 Windows 共享服务,释放 445 端口 转载自:https://blog.csdn.net/liu857279611/article/details/71786068 在 Window ...
- 『德不孤』Pytest框架 — 14、Pytest中的conftest.py文件
目录 1.conftest.py文件介绍 2.conftest.py的注意事项 3.conftest.py的使用 4.不同位置conftest.py文件的优先级 5.conftest.py中Fixtu ...
- 关于VBS编程初步
VBS是基于Visual Basic的脚本语言.VBS的全称是:Microsoft Visual Basic Script Edition.用记事本就可以看到源代码.在没有语法错误的前提下,直接双击左 ...
- Flask Web开发读书笔记
开篇:目前想自学Flask Web开发--基于Python,找了几本书准备啃啃,同时也会分享读书笔记.希望和大家一起进步. Flask是小型框架,可以算是微框架,但是他的功能还是比较多 Flask有三 ...
- sqlserver 中,如何将getdate()时间的时分秒固定为00:00:00或者忽略不要
在使用getdate()时,时间会实时刷新,那么我们就要再查询的时候就需要精确到毫秒后三位,非常难受,那么为了解决这个问题我们可以通过以下几种方法进行固定或者去掉毫秒 1.将毫秒固定为00:00:00 ...
- 4月19日 python学习总结 套接字模块的使用
服务端: import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 买电话 phone.bind(('127.0.0 ...
- 项目构建工具之maven01
Maven 是一个项目管理工具,可以对 Java 项目进行构建.依赖管理.Maven 也可被用于构建和管理各种项目,例如 C#,Ruby,Scala 和其他语言编写的项目.Maven 曾是 Jakar ...
- Mysql之Explain关键字及常见的优化手段
Explain关键字字段描述: Explain关键字字段详情描述 id 我们写的查询语句一般都以SELECT关键字开头,比较简单的查询语句里只有一个SELECT关键字,但是下边两种情况下在一条查询语句 ...