javascript,如何理解函数原型链上的bind()方法?
发布于 作者:苏南大叔 来源:程序如此灵动~三个非常类似的函数:.call()
、.apply()
、.bind()
。本文介绍最后一个.bind()
函数,已知的是:.call()
和.apply()
两个函数的功能基本一致,只是传递参数的方法不一样。那么,.bind()
又有什么不一样的地方呢?这就是本文中要重点描述的内容。
大家好,这里是苏南大叔的程序如此灵动博客,这里记录苏南大叔和计算机代码的故事。本文描述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)
第二个例子,改变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.
的指向。
事实上,this.
并不能停留在字面上的理解,应该再进一步理解为引用对象。因为可能并不能显式的看到this.
显式调用的代码。下面这段代码在浏览器里面运行:
var w = document.write;
w.call(document, '苏南大叔');
w.bind(document)('苏南大叔');
w.apply(document,['苏南大叔']);
第三个例子,参数位置
这个例子里面,主要说明.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
的参数位置被换了,所以出现了异常输出。
这里实际上还可以把参数放到第一个括号里面,生成一个特殊的参数,传递了一半参数的函数。例如:
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
。
表格总结
方法 | 调用 | 覆盖this | 参数传递 |
---|---|---|---|
call | .call() | 第一个参数 | 第二个参数开始,单个传递 |
apply | .apply() | 第一个参数 | 所有参数包成数组,放在第二个位置 |
bind | .bind()() | 第一组第一个参数 | 单个传递,可以放第一个(第二个)括号里面,或者两个都放 |
可以从下面的文章中,获得更多这个表格的相关内容:
- https://newsn.net/say/js-call.html
- https://newsn.net/say/js-apply.html
- https://newsn.net/say/js-bind.html
总结
函数名.bind()()
,任何函数或方法都可以执行。需要注意的就是:这个.bind()
返回的是个函数,要执行的话,还是需要再次()
一下,参数可以放在任何一个()
内。更多经验文章链接:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。