首页 > 其他分享 >js中的bind方法并模拟实现自己的bind方法

js中的bind方法并模拟实现自己的bind方法

时间:2022-09-28 01:33:24浏览次数:72  
标签:console 函数 bind js new 方法 hello log

Js中bind方法使用和实现

前面我们已经模拟实现了call和apply方法,今天来实现下同样可以改变this指向但是又有点不同得方法--> bind方法。

定义

首先来看下bind方法在mdn中得定义,bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

语法

function.bind(thisArg[, arg1[, arg2[, ...]]])

参数

thisArg 调用绑定函数时作为 this 参数传递给目标函数的值。 如果使用new运算符构造绑定函数,则忽略该值。当使用 bind 在 setTimeout 中创建一个函数(作为回调提供)时,作为 thisArg 传递的任何原始值都将转换为 object。如果 bind 函数的参数列表为空,或者thisArg是null或undefined,执行作用域的 this 将被视为新函数的 thisArg《医院证明模板》。
arg1, arg2, ... 当目标函数被调用时,被预置入绑定函数的参数列表中的参数。

返回值

返回一个原函数的拷贝,并拥有指定的 this 值和初始参数。

从上面mdn中得描述中我们看到bind方法和call、apply方法得不同点就是,bind方法同样是将调用函数得this指向第一个参数,但是这个时候不会执行函数,而是会创建一个新的函数并返回出来,除了第一个参数剩下得参数传入新返回得函数使用。并且返回的函数还可以被new操作符进行调用,使用new操作符时bind方法传入得第一个this指向得值就失效了,此时函数this得指向遵循new操作符的this指向原则。(new操作符解析)。

使用

function say(res, res2) {
        this.num = res;
        console.log(this);
        console.log(this.hello);
        console.log(res);
        console.log(res2);
    }
    let obj = {
        hello: 'hello'
    }
    const back = say.bind(obj, 1);
    back(3);
    // {hello: "hello", num: 1}
    // hello
    // 1
    // 3

上述代码由打印值可以看出,利用bind函数将say函数内部的this指向了obj对象,并且为obj对象添加了一个属性num赋值为1,并且bind函数返回的back函数传入的参数在bing函数传入参数的后面进行传入。但是没有使用new操作符,接下来看使用new操作符调用back函数。

    function say(res, res2) {
        this.num = res;
        console.log(this);
        console.log(this.hello);
        console.log(res);
        console.log(res2);
    }
    let obj = {
        hello: 'hello'
    }
    const back = say.bind(obj, 1);
    const b = new back(6);
    console.log(b, 'b')
    // say {num: 1}
    // undefined
    // 1
    // 6
    // say {num: 1} "b"

上述代码将bind函数返回的back函数使用new操作符调用,看打印结果将say函数的this指向了new操作符生成的实力对象b上。下面我们就根据规则实现模拟实现自己的bind操作符。

实现思路

1、 在Function的原型上添加自己的bind方法
2、 返回一个新的函数backFn
3、 判断函数是不是由new操作符调用
4、 是的话将this指向生成的实力对象,不是的话将this指向传入的第一个值
5、 如果原函数存在原型对象,将返回函数backFn的原型指向原来函数的原型对象(因为bind返回的函数相当于原函数的复制)
6、 返回backFn函数

实现

    // 添加bind方法,并传入参数
    Function.prototype.myBind = function (thisArg, ...bindRes) {
        // 将函数保存起来
        const thisFn = this;
        if (typeof thisFn !== 'function') {
            throw new TypeError(this + 'is not a function');
        }
        const backFn = function (...backRes) {
            // 判断是否是new操作符调用,是的话采用生成的实例对象(因此时backFn函数this就指向实例对象所以直接指向this即可)
            // 参数传入如果是es5实现可以使用arguments对象

            // 使用之前自己写好apply方法改变this指向
            if (new.target) {
                return thisFn.apply(this, [...bindRes, ...backRes]);
            } else {
                return thisFn.apply(thisArg, [...bindRes, ...backRes]);
            }
            // 或者也可以这样子写
            // return thisFn.apply(new.target? this: thisArg, [...bindRes, ...backRes]);

        }
        // 采用创建空函数的方法,将bacnFn函数原型指向原函数防止改变bacnFn函数原型对象而影响原函数原型对象
        if (thisFn.prototype) {
            const emptFn = function () {};
            emptFn.prototype = thisFn.prototype;
            backFn.prototype = new emptFn();
        }

        return backFn;
    }

测试

    function say(res, res2) {
        this.num = res;
        console.log(this);
        console.log(this.hello);
        console.log(res);
        console.log(res2);
    }
    say.prototype.str = '内容'
    let obj = {
        hello: 'hello'
    }
    const back = say.myBind(obj, 1);
    back(3);
    // {hello: "hello", num: 1}
    // hello
    // 1
    // 3



    const b = new back(6);
    console.log(b.str, 'b')
    // backFn {num: 1}
    // undefined
    // 1
    // 6
    // 内容 b

测试结果符合期望结果,至此我们自己的bind方法就实现了。

来源:http://www.chiniurou.com/tupian/493.html

标签:console,函数,bind,js,new,方法,hello,log
From: https://www.cnblogs.com/bkycnd/p/16736589.html

相关文章

  • python安装weditor报错error subprocess-exited-with-error的解决方法
    使用pip安装weditor失败,报错内容:  解决方法:第一步输入gitclonehttps://github.com/openatx/weditor第二步输入 pip3install-eweditor     验......
  • 前端三件套 HTML+CSS+JS基础知识内容笔记
    HTML基础目录HTML基础HTML5标签doctype标签html标签head标签meta标签title标签body标签文本和超链接标签标题标签段落标签换行标签水平标签强调标签图片标签与超链接标签......
  • TE对象message js脚本简单写法
        TE里的对象和图层都支持添加message,其中message类型中有一类为Script,在弹出的框里可以写JavaScript脚本,下图就是切换到脚本信息下: 写一个了简单的脚本示例:<scrip......
  • JS 刷新页面所有方法
    window.location.reload();使用window.open()弹出的弹出窗口,刷新父窗口非模态刷新父页面:window.opener.location.reload()使用window.showDialog弹出的模式窗口模态刷新父......
  • VueJs 自定义过滤器使用总结
    在这个教程中,我们将会通过几个例子,了解和学习VueJs的过滤器。我们参考了一些比较完善的过滤器,比如orderBy和filterBy。而且我们可以链式调用过滤器,一个接一个过滤。因此,我......
  • vuejs 开发问题解决方案总结一
    文章中提到的很多东西都在我的demo中用到,我的demo地址:​​https://github.com/MrZhang123/Vue_project/tree/master/vue_spa_demo​​1.Vuejs组件vuejs构建组件使用Vue.comp......
  • js循环数组各种方法array 汇总-基础
    js循环数组各种方法array汇总-基础这几天做系统,又用到多维数组循环交叉。所以总结一套以供参考记录1.varmyStringArray=["Hello","World"];2.......
  • 信号处理(1) --常用信号平滑去噪的方法
    前言:最近研究汽车碰撞的加速度信号,在信号的采集过程中难免遇到噪音,导致信号偏差,为了更好的反映系统情况,故常需要信号去噪,本文分享一些常用信号平滑去噪的方法。关键字:信号;去......
  • org.apache.ibatis.binding.BindingException
    点击查看代码org.apache.ibatis.binding.BindingException:Typeinterfacecom.example.mybatis.mapper.UserMapperisnotknowntotheMapperRegistry. atorg.apa......
  • 同一个数据源赋值成两个数组、避免数据会相互影响,可使用JSON.parse(JSON.stringify())
        getListCountryJdSc(obj).then((res)=>{        this.SummaryList=res.data.data        this.jdDataList=JSON.pars......