我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

三个非常类似的函数:.call().apply().bind()。本文介绍最后一个.bind()函数,已知的是:.call().apply()两个函数的功能基本一致,只是传递参数的方法不一样。那么,.bind()又有什么不一样的地方呢?这就是本文中要重点描述的内容。

苏南大叔:javascript,如何理解函数原型链上的bind()方法? - bind-bind
javascript,如何理解函数原型链上的bind()方法? (图6-1)

大家好,这里是苏南大叔的平行空间笔记本博客,这里记录苏南大叔和计算机代码的故事。本文描述js代码中.bind()的使用方法。测试环境:node@16.14.2

基本思路

三个类似函数.call().apply().bind(),函数功能都是执行一个函数。使用方式上也是非常的类似,其不同之处在于:

  • .bind()返回的是一个函数,也就是说需要再次()执行一下。
  • .bind()的执行变成了.bind()()之后,就有了两个传递参数的位置,这也是第二个不同之处。

下面还是以代码做例子:

function test(university) {
    console.log(this.who + "," + university)
}
var sunan = { who: "苏南大叔" };
test.call(sunan, 'PKU');
test.apply(sunan, ['北大']);
test.bind(sunan, '北京大学')();
test.bind(sunan)('圆明园职业技术学院');

如果函数体内没有涉及到this.的话,那么这一系列方法中的第一个参数,传递啥都可以。上述代码的执行结果是:

苏南大叔 , PKU
苏南大叔 , 北大
苏南大叔 , 北京大学
苏南大叔 , 圆明园职业技术学院

从上述代码中可以看到.bind使用方式如下:

  • .bind(覆盖this,参数1,参数2)()
  • .bind(覆盖this)(参数1,参数2)

苏南大叔:javascript,如何理解函数原型链上的bind()方法? - bind-code-1
javascript,如何理解函数原型链上的bind()方法? (图6-2)

第二个例子,改变this.指向

var sn = {
  name: "苏南",
  info: function (university) {
    console.log(this.name + " , " + university);
  }
}
var sunan = {
  name: "苏南大叔",
}
sn.info.call (sunan, 'PKU');
sn.info.apply(sunan, ['北大']);
sn.info.bind (sunan, '北京大学')();
sn.info.bind (sunan)('圆明园职业技术学院');

输出内容为:

苏南大叔 , PKU
苏南大叔 , 北大
苏南大叔 , 北京大学
苏南大叔 , 圆明园职业技术学院

这个例子里面,主要说明的是.bind()可以和其它方法一样,改变this.的指向。

苏南大叔:javascript,如何理解函数原型链上的bind()方法? - bind-code-2
javascript,如何理解函数原型链上的bind()方法? (图6-3)

事实上,this.并不能停留在字面上的理解,应该再进一步理解为引用对象。因为可能并不能显式的看到this.显式调用的代码。下面这段代码在浏览器里面运行:

var w = document.write;
w.call(document, '苏南大叔');
w.bind(document)('苏南大叔');
w.apply(document,['苏南大叔']);

苏南大叔:javascript,如何理解函数原型链上的bind()方法? - 浏览器里面运行的代码
javascript,如何理解函数原型链上的bind()方法? (图6-4)

第三个例子,参数位置

这个例子里面,主要说明.bind的参数可以分开传递。只是代表this的第一个参数,必须放置在第一个括号的第一个参数位置。其它的参数可以在两个括号里面,按顺序随便传递。

var sn = {
    name: "苏南",
    info: function (university, college) {
        console.log(this.name + " , " + university + " , " + college);
    }
}
var sunan = {
    name: "苏南大叔",
}
sn.info.bind(sunan, '圆明园职业技术学院', '计算机学院')();
sn.info.bind(sunan, '圆明园职业技术学院')('计算机学院');
sn.info.bind(sunan)('圆明园职业技术学院', '计算机学院');
sn.info.bind()(sunan, '圆明园职业技术学院', '计算机学院');

最后一个代码中,因为代表this的参数位置被换了,所以出现了异常输出。

苏南大叔:javascript,如何理解函数原型链上的bind()方法? - 参数位置
javascript,如何理解函数原型链上的bind()方法? (图6-5)

这里实际上还可以把参数放到第一个括号里面,生成一个特殊的参数,传递了一半参数的函数。例如:

sn.info.bind(sunan, '圆明园职业技术学院')

这实际上就是一个传递了一部分参数的函数,参考文章:

第四个例子,返回一个函数

本文关于.bind()返回一个函数的事情,这里还需要特殊说明一下。并不是说碰到bind就必须是()()的情况,如果需要的是个函数,那么就执行一个()即可。范例代码:

var sn = {
    go: function () {
        var that = this;
        var test = function () {
            console.log(that.who);
        }
        test();
    },
    who: 'sunan'
}
sn.go();

var sn = {
    go: function () {
        var test = function () {
            console.log(this.who);
        }.bind(this);
        test();
    },
    who: 'sunan'
}
sn.go();

var sn = {
    go: function () {
        var test = function () {
            console.log(this.who);
        }
        test.bind(this)();
    },
    who: 'sunan'
}
sn.go();

输出结果都是sunan

苏南大叔:javascript,如何理解函数原型链上的bind()方法? - 另外一个例子
javascript,如何理解函数原型链上的bind()方法? (图6-6)

表格总结

方法调用覆盖this参数传递
call.call()第一个参数第二个参数开始,单个传递
apply.apply()第一个参数所有参数包成数组,放在第二个位置
bind.bind()()第一组第一个参数单个传递,可以放第一个(第二个)括号里面,或者两个都放

可以从下面的文章中,获得更多这个表格的相关内容:

总结

函数名.bind()(),任何函数或方法都可以执行。需要注意的就是:这个.bind()返回的是个函数,要执行的话,还是需要再次()一下,参数可以放在任何一个()内。更多经验文章链接:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   js