资讯专栏INFORMATION COLUMN

一行代码看懂bind,call

Lavender / 858人阅读

摘要:代码方法返回一个新的数组对象原数组的浅拷贝,常用于动态解析参数。看过的童鞋,对这行代码不会陌生。所以笔者觉得,从理解角度来看,新创建的函数命名为更便于理解。总结乍一看,函数有点绕,一经推敲还是很好理解的。

代码
var slice = Function.prototype.call.bind(Array.prototype.slice);

slice() 方法返回一个新的数组对象(原数组的浅拷贝),常用于动态解析参数。看过MDN的童鞋,对这行代码不会陌生。MDN上的描述比较官方,下面我们通过对这行代码的知识点的逐一分析来加深理解。

Function.prototype.call

call :临时性的改变一个函数的this。原本函数是谁调用,this就指向谁。call是通过第一个参数,告诉函数本次调用者另有其人,然后接着传入参数:

fun.call(thisArg, arg1, arg2, ...)

测试demo:

function testCall(){console.log(this)}
testCall()
//Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
testCall.call({})
//{}
testCall()
//Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
Function.prototype.bind

bind:创建一个新的函数,新函数的this永久指向第一个参数:

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

测试demo:

var t={testBind(){console.log(this)}}
t.testBind()
//{testBind: ƒ}
t.testBind2=t.testBind.bind({x:1})
t.testBind2()
//{x: 1} 虽然调用的还是t,但是this指向的还是bind的
t.testBind()
//{testBind: ƒ, testBind2: ƒ}
t.testBind2===t.testBind
//false

使用bind去创建的新函数的频次并不高,笔者表示从没用到过~
实用一点的是MDN上介绍的偏函数,即使函数预设参数:

//来源MDN
function list() {
  return Array.prototype.slice.call(arguments);
}

var list1 = list(1, 2, 3); // [1, 2, 3]

// Create a function with a preset leading argument
var leadingThirtysevenList = list.bind(undefined, 37);

var list2 = leadingThirtysevenList(); // [37]
var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]

var leadingThirtysevenList = list.bind(undefined, 37,38,39,40);
leadingThirtysevenList();//[37, 38, 39, 40]
leadingThirtysevenList(1,2,3);//[37, 38, 39, 40, 1, 2, 3]

另外一个实用的地方就是文章开头写的快捷调用了:

var slice = Function.prototype.call.bind(Array.prototype.slice);

经过前面的了解,我们再来分析下这段代码:
使用bindcall函数的this永久绑定Array.prototype.slice函数,返回一个新的call函数,我们打印一下:

slice
// ƒ call() { [native code] }

slice({length:1})等价于Array.prototype.slice.call({length:1}),也就是说创建的slicecall 函数的一个变体,是call 函数的一个变体,是call 函数的一个变体。所以笔者觉得,从理解角度来看,新创建的函数slice 命名为newCall更便于理解。

总结

乍一看,newCallslice函数有点绕,一经推敲还是很好理解的。由此我们也可以写出来更多的newCall(快捷调用),例如精确类型判断需要用到的toString

var toString=Function.prototype.call.bind(Object.prototype.toString)
toString({})
//"[object Object]"
toString(1)
//"[object Number]"
toString(null)
//"[object Null]"
toString()
//"[object Undefined]"
toString(false)
//"[object Boolean]"
toString(function(){})
//"[object Function]"

MDN文档:

MDN-call
MDN-bind

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108573.html

相关文章

  • JS 兼容、继承、bind、this

    摘要:我们都说构造函数开头首字母大写但那只是人为的规定并不是语法。只是一个操作符,任何函数都能通过来执行,并不只是构造函数,只不过我们认为之后的都是构造函数。 这一篇文章主要是讲述一些有关js的小知识点。因为我也不是很精通哪一方面只能把自己知道的一点点写出来。取名大杂烩也是这意思吧,既然是道菜那么就来尝尝我的手艺吧。 第一道菜 1.首先,我想说一下事件绑定。事件绑定我们都知道有:on + t...

    YacaToy 评论0 收藏0
  • Javascript之bind

    摘要:返回的函数可以作为构造函数使用被用作构造函数时,应指向出来的实例,同时有属性,其指向实例的原型。判断当前被调用时,是用于普通的还是用于构造函数从而更改指向。运算符用来测试一个对象在其原型链中是否存在一个构造函数的属性。 写在最前 最近开始重新学习一波js,框架用久了有些时候觉得这样子应该可以实现发现就真的实现了,但是为什么这么写好像又说不太清楚,之前读了LucasHC以及冴羽的两篇关于...

    王岩威 评论0 收藏0
  • callbind的模拟实现

    摘要:大致就是这样所以可以模拟实现和。这些参数作为的第二个参数跟在后面,之后它们会被插入到目标函数的参数列表的开始位置,传递给绑定函数的参数会跟在它们的后面。 一个前端知识点汇总综合了学习过程中的知识点,比如this、闭包、BFC、ES6等,如果大佬们觉得还可以的话,求个star啦! call和apply 每个函数都包含两个非继承而来的方法:apply()和call() 用途相同,都是在...

    mmy123456 评论0 收藏0
  • 一行等式理解JS当中的call, apply和bind

    摘要:所以,这篇文章将通过一段非常简洁的等式,把当中一个相对较难的知识点,,和给串联起来要理解当中的这三个关键字,首先得弄清楚它们是用来干嘛的。方案让吃掉,直接消化吸收的所有能力。 关于JS当中的call,apply和bind,相信大家和我一样,已经看过了无数篇相关的文章,都有自己的理解。所以这篇文章并非什么科普类的文章,仅仅是把我自己的理解记录下来。 我的学习习惯,是喜欢把各种看似孤立的知...

    CarterLi 评论0 收藏0
  • 进击的 JavaScript(六) 之 this

    摘要:绑定为这个数组五绑定如果使用来创建对象,因为后面跟着的是构造函数,所以称它为构造器调用。为传进来的构造函数你这要看懂这步就行。 记得刚开始,我理解 this 的时候 也是云里雾里的,哈哈,希望通过这篇文章,对你有帮助吧。 关于 this 最多的说法,就是:谁调用它,this就指向谁。这话呢,不能说它错了,只能说它讲的不严谨,为什么呢?我们先来了解下 this 的几种绑定规则。 一...

    chemzqm 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<