首页 > 其他分享 >手写实现 js 中的bind,并实现 softBind

手写实现 js 中的bind,并实现 softBind

时间:2022-08-17 23:45:48浏览次数:54  
标签:10 bind softBind js let context fn

// bind会返回一个硬绑定的新函数,新函数会使用指定的第一个thisCtx去调用原始函数,并将其它参数传给原始函数。 硬绑定会降低函数的灵活性,在绑定之后不能通过显式或硬绑定的方式改变this,只能通过new改变
// softBind 会对指定的函数进行封装,首先检查调用时的 this,如果 this 绑定到全局对象或者 undefined,那就用指定的thisCtx 去调用函数,否则不会修改 this
Function.prototype.myBind = function (context, ...args) {
    const self = this;
    const fn = function (...newArgs) {
        console.log("this", this); //  链式调用的时候 { a: 6 }
        console.log("context", context); //{ a: 2 }
        // 优先判断是否来自new 调用之后的实例,是的话 this 不变
        self.apply(this instanceof fn ? this : context, args.concat(newArgs));
    };
    fn.prototype = Object.create(this.prototype);
    return fn;
};
function f1(b) {
    console.log(this.a, b);
}
let fb11 = f1.myBind({ a: 1 }, 10);
let bindFn1 = new fb11(); // undefined 10   因为 new 调用优先级高于 bind 改变的this 指向
let fb22 = f1.myBind({ a: 2 }, 10);
fb22(); // 2,10
let fb33 = f1.myBind({ a: 3 }, 10);
fb33(); // 3,10
let fb66 = fb22.myBind({ a: 6 }, 10)(); // 2,10
// fb66(); // 2,10
// 结论:bind方法链式调用,都以第一次bind绑定为准,所以叫硬绑定,原理为 下一次 调用bind的方法为上一个bind方法返回的闭包,已经将 context、args 存储好并固定返回了
// 参考链接:https://juejin.cn/post/6921897996258918413
// bind方法分别多次调用,各自都可绑定成功
console.log("=================");
// softBind   globalThis 代表获取当前环境下的全局对象
Function.prototype.softBind = function (context = globalThis, ...args) {
    const self = this;
    const fn = function (...newArgs) {
        // new 的时候和链式调用 softBind 的时候打印
        if (this !== globalThis) {
            console.log("this", this); //  链式调用的时候 { a: 6 }
            console.log("context", context); //{ a: 2 }
        }
        self.apply(
            this instanceof fn ? this : !this || this === globalThis ? context : this,
            args
        );
    };
    fn.prototype = Object.create(this.prototype);
    return fn;
};
let fs22 = f1.softBind({ a: 2 }, 10);
fs22(); // 2 10
let fs33 = f1.softBind({ a: 3 }, 10);
fs33(); // 3 10
let fs66 = f1.softBind({ a: 2 }, 10).softBind({ a: 6 }, 10);
fs66(); //6 10
let fs11 = f1.softBind({ a: 1 }, 10);
let softbindFn1 = new fs11(); // undefined 10   因为 new 调用优先级高于 bind 改变的this 指向

 

标签:10,bind,softBind,js,let,context,fn
From: https://www.cnblogs.com/beileixinqing/p/16597249.html

相关文章

  • 817笔记(轮播图js)
    网页轮播图步骤:鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮点击右侧按钮一次,图片往左播放一次,以此类推,左侧按钮同理图片播放的同时,下面小圆圈模块跟随一起变化......
  • [js] uncaught exception: Error: listDatabases failed
    当mongo搭建的是replicaset集群。如果你登录某一台SECONDARY节点执行命令showdbs报错2022-08-16T15:20:00.606+0800EQUERY[js]uncaughtexception:Error:list......
  • Js的cookie和session
    Cookie的概念:保存在客户端一个字符串属性,读取cookie的值时,得到一个字符串;cookie除了name名和value值外,还有expires过期时间、path路径、domain域、以及secure安全。JS代码......
  • 16js运动
     运动概述运动主要是动画的操作,主要是操作某个document元素的属性变化(位置变化)运动主要的三步骤使用定时器来定时更改对应的内容实时获取对应的元素的属性及相关......
  • SpringMvc_06Jackson,Controller返回json数据
    初识json 通过json对象来实现,但是会有乱码问题  乱码问题可以通过Springmvc-servlet配置    同样的,可以通过RestController让其不仅过视图解析器,返回一个......
  • js一个快速提取所需字符串的方法
    varobj={"dependencies":{"axios":"^0.27.2","lodash":"^4.17.21","nanoid":"^4.0.0","normalize.css":"^8.0.1","pinia":"^2......
  • js判断移动端还是pc端
    functionisMobile(){letuserAgentInfo=navigator.userAgent;letAgents=['Android','iPhone','SymbianOS','WindowsPhone','iPad','iPod'];le......
  • MockJs
    MockJs一、为什么使用mockjs在做开发时,当后端的接口还未完成,前端为了不影响工作效率,手动模拟后端接口。1.我们可以使用json文件来模拟后台数据,但比较局限,无法模拟数据......
  • 学习Js-day18
    放大镜的简单实现效果图如下:对结构,布局,效果,进行分析“一、结构分析:1.一个小盒子box包着一个移动的盒子move,再连接一个大盒子bigbox展示图片的细节。二、布局分析:1.放小......
  • JSP和servlet之间的相互传值
    1.从一个jsp页面跳转到另一个jsp页面时的参数传递(1)使用request对象获取客户端提交的信息login.jsp页面代码如下:点击查看代码<%@pagelanguage="java"import="java......