windows 改变文件大小 函数_手写 bind call apply 方法 与 实现节流防抖函数
实现 bind call apply 方法
this 是什么?
this是指包含它的函数作为方法被调用时所属的对象。这句话理解起来感觉还是很拗口的,但是如果你把它拆分开来变成这三句话后就好理解一点了。
- 包含它的函数
- 作为方法被调用时
- 所属的对象
改变 this 指向的函数
bind、call、apply
- 共同点
- 目标函数被调用时,改变 this 的指向为指定的值
- 三个方法都是函数的方法,挂载在 Funtion.prototype 上
- 不同点
- 目标函数调用 call 和 apply 后会直接被执行。
- 目标函数调用 bind 后,不会立即执行,而是返回一个新的函数,调用新函数才会执行目标函数。
回顾 call apply bind 的使用
var btn = document.querySelector(".btn");
var name = "windows";
var obj = {name: "Linux",num: 0,updateNum: function(){this.num++;console.log(this.num) // 1,2,3,4}
}function fn(){console.log(this.name);
};btn.addEventListener("click", obj.updateNum.bind(obj))fn(); // windows
fn.call(obj); // Linux
fn.apply(obj)
fn(null); // windows
回顾call与apply的参数使用
let name = "wanna";let age = 20;let obj = {name: "hurt",objAge: this.age,objFn: function(a, b){console.log(this.name + "年龄" + this.age, "性别:" + a + "兴趣爱好" + b);}};let user = {name: "hico",age: 18};obj.objFn.call(user, "男", "篮球"); // hico年龄18 性别:男 兴趣爱好篮球obj.objFn.apply(user, ["男","足球"]); // hico年龄18 性别:男 兴趣爱好足球obj.objFn.bind(user, "男", "排球")(); // hico年龄18 性别:男 兴趣爱好排球obj.objFn.bind(user, ["男", "乒乓球"])(null); // hico年龄18 性别:男 乒乓球 兴趣爱好null
不同的是 bind 必须调用它才会执行
实现 call
思路
- call是可以被所有方法调用的,所以毫无疑问的定义在 Function的原型上
- 绑定函数被调用时只传入第二个参数及之后的参数
- 如果调用者函数,被某一个对象所拥有,那么该函数在调用时,内部的this指向该对象。
Function.prototype.MyCall = function(){const ctx = arguments[0] || window;// 被调用的方法定义在 ctx.fn 绑定 thisctx.fn = this;// 获取实参const arg = [...arguments].slice(1); // 以对象调用的形式调用 fn ,此时的 this 指向 ctx,也就是传入的需要绑定 this 指向const res = arguments.length > 1 ? ctx.fn(...arg) : ctx.fn();// 删除方法,防止对传入的对象造成污染delete ctx.fn;return res;
};
实现 apply
apply实现的思路与call基本相同,我们只需要对参数进行不同处理即可
Function.prototype.MyApply = function(){const ctx = arguments[0] || window;// 被调用的方法定义在 ctx.fn 绑定 thisctx.fn = this;// 以对象调用的形式调用 fn ,此时的 this 指向 ctx,也就是传入的需要绑定 this 指向const res = arguments[1] ? ctx.fn(...arguments[1]) : ctx.fn();// 删除方法,防止对传入的对象造成污染delete ctx.fn;return res;
};
实现 bind
思路
- call是可以被所有方法调用的,所以毫无疑问的定义在 Function的原型上
- 绑定函数被调用时只传入第二个参数及之后的参数
- 如果调用者函数,被某一个对象所拥有,那么该函数在调用时,内部的this指向该对象。
- 调用执行,不调用绑定 this 指向
Function.prototype.MYBind = function(context){// 深拷贝 防止污染const ctx = JSON.parse(JSON.stringify(context)) || window;// 被调用的方法定义在 ctx.fn 绑定 thisctx.fn = this;// 获取实参const args = [...arguments].slice(1);// 返回一个绑定函数,等待调用return function () {// 合并实参const allArgs = args.concat([...arguments]);// 以对象调用的形式调用 fn ,此时的 this 指向 ctx,也就是传入的需要绑定 this 指向return allArgs.length ? ctx.fn(...allArgs) : ctx.fn();}};
什么是节流?怎么实现节流函数
我们举例一个简单的 demo ,假设我们在页面用到了滚轮事件
window.addEventListener("scroll",()=>console.log("1"))
我现在打算从页面滚动一次
于是我们会发现
轻轻的一滚动执行了 16 次打印,这个函数的默认执行频率太高了,但是实际上我们并不需要如果高频的执行,毕竟浏览器的性能是有限的,不应该在这里浪费,接下来我们来看看如何优化这种场景。
如果在限定时间段内,不断触发滚动事件。好比我们假设上了一趟公共厕所,发现水龙头的水大量的喷出,于是我们下意识的拧紧关闭水龙头,却拧不紧,即使拧不紧也要节约一下用水,让水龙头的水量变小,节约用水,人人有责嘛,好了,废话不多说,直接上代码
let getLog = () => console.log("滚动");
window.addEventListener("scroll", throttle(getLog, 300));
// 节流
function throttle(fn, interval=300){let timer = 0;return function(...arg) {let _this = this;if(timer)return;fn.call(_this, ...arg);timer = setTimeout(function(){timer = 0;},interval);};
};
也就是让函数执行一次后,在某个时间段内暂时失效,过了这段时间后再重新激活(类似于技能冷却)
开始从顶部滚动,这下狠一点,滚到底部看看效果。
于是我们发现
滚到底部居然只打印了11次,坑比我们上面的滚动一次打印 15 次,大大节省了性能的消耗。
什么是防抖?怎么实现防抖函数
举例一个简单的 demo,现在我打算窗口大小发生改变时打印日志
let getLog = () => console.log("防抖");
window.addEventListener("scroll",getLog)
我打算从左边拉动到右边
小小改变窗口大小就发生了这样的事
其实实际上我们并不需要如果高频的执行,毕竟浏览器的性能是有限的,不应该在这里浪费,我们来整理一下思路。
在第一次触发事件后,不应该立即执行函数,而是给出一个期限值比如 500ms 。
- 如果 500ms 内没有再次触发滚动,那么就执行函数。
- 如果 500ms 内再次触发滚动事件,那么当前的计时取消,重新开始计时。
效果:短时间内大量触发同一事件,只会执行最后一次
实现:既然前面都提到了计时了,那实现的关键就在于 setTimeOut 这个函数了。
let getLog = () => console.log("防抖");window.addEventListener("resize", debounce(getLog));// fn 要防抖的函数 interval 间隔时间
function debounce(fn, interval=500){let timer = 0;return function(...arg) {let _this = this;clearTimeout(timer);timer = setTimeout(function(){fn.call(_this, ...arg);},interval);}
}
现在我打算窗口从右边拖到到左边。
天呐,控制台居然只输出了一次日志,不管我怎么拉动,当我停下来的时候就执行了最后一次
这下我们明白了。防抖的含义就是让某个时间期限内,事件处理函数只执行一次,大大节省了性能的消耗。
windows 改变文件大小 函数_手写 bind call apply 方法 与 实现节流防抖函数相关推荐
- 原生js已载入就执行函数_手写CommonJS 中的 require函数
前言 来自于圣松大佬的文章<手写CommonJS 中的 require函数> 什么是 CommonJS ? node.js 的应用采用的commonjs模块规范. 每一个文件就是一个模块, ...
- 手写 call、apply 及 bind 函数
之前在bind和apply以及call函数使用中详解总结过bind和apply以及call函数的使用,下面手写一下三个函数. 一.首先call函数 Function.prototype.MyCall ...
- 【bind()函数】JavaScript手写bind()及详解-超详细~~~
这两天学习了手写call.apply.bind,手写bind思考了很久才实现了MDN的示例的结果,所以记录下来~ 因为是第一篇文章,所以可能存在一些错误,希望各位大佬批评指正,不吝赐教. 也欢迎不懂的 ...
- 全网最详细手写bind
手写bind 在写代码前,一定要分析这个api或者关键字实现了什么,拥有什么功能,如果对其原理认识不到时,也不能达到一比一还原 bind bind执行返回的是一个新的函数 这个函数可以被new关键字执 ...
- 手写一个promise用法_手写一个 Promise
1 js 的基本数据类型? 2 JavaScript 有几种类型的值? 3 什么是堆?什么是栈?它们之间有什么区别和联系? 4 内部属性 [Class] 是什么? 5 介绍 js 有哪些内置对象? 6 ...
- 苹果键盘怎么手写_手写笔的魅力
请点击文末右下角"",移步官网获取更好阅读体验! 欢迎加入Augix官方QQ群:595698697. 喜讯!Augix已开通微博,请搜索关注:Augix频道. B站视频更新频道也已 ...
- python画cpk图_TensorFlow MNIST手写数据集的实现方法
MNIST数据集介绍 MNIST数据集中包含了各种各样的手写数字图片,数据集的官网是:http://yann.lecun.com/exdb/mnist/index.html,我们可以从这里下载数据集. ...
- [js] 手写一个trim()的方法
[js] 手写一个trim()的方法 function trim(str) { if (str[0] === ' ' && str[str.length - 1] === ' ') { ...
- js拆字_分图程序 _制作个人字体_手写字制作ttf字体方法
js拆字_分图程序 _制作个人字体_手写字制作ttf字体方法 前言 FontForgeBuilds制作ttf FontForgeBuilds制作个人字体 Adobe_Fireworks_CS5批量转换 ...
最新文章
- spring 组件基于注解的注册方式
- 使用文本用户界面(NMTUI)进行网络配置
- 远程办公还将持续,智办事助力企业团队协作难点“破冰”
- VC++使用Soap ToolKit3.0调用WebService接口
- 阿里云centos7安装和卸载图形化操作界面
- Yahoo Mail,慢功出细活〔转载〕
- C和指针之Eratosthenes-埃拉托斯特尼筛方法找质数
- 坑爹的日志无法按天切割问题
- 在ASP.NET MVC中实现Select多选
- 【机器学习】 关联规则Apriori和mlxtend——推荐算法
- 性能提升一倍,云原生网关支持 TLS 硬件加速
- html判断ie6,jquery如何判断是否是ie?
- Hivesql-高级进阶技巧
- python 多帧 超分辨_利用python-opencv生成视频帧数控制,和常见错误总结
- java抓取网页数据_Golang丨Java丨Python爬虫实战—Boss直聘网站数据抓取
- 最大最小距离聚类算法c语言,聚类算法-最大最小距离算法(实例+代码)
- NCL中绘制中国任意省份的精确地图
- 基于扩张卷积神经网络的图像超分辨率
- 计算机网络(四)—— 网络层(1、2):网络层概述、网络层提供的两种服务
- hypermedia_Hypermedia REST API简介
热门文章
- 迁移上云方法论-6R
- ubuntu挂载windows下的文件目录的步骤
- 重游HBase核心知识点总结
- Spark _03RDD_Transformations_Action_使用scalajavaAPI
- 数据结构与算法(一):排序算法之 - 快速排序(详细步骤图解,附代码)
- 【Python】import pandas时,报错 pandas Missing required dependencies ['numpy'] 原因分析
- 《FlaskWeb开发:基于Python的Web应用开发实战》笔记
- jar包冲突常用的解决方法
- java动态代理原理及解析
- google怎么做(3.搜索结果重排序)