专栏首页原创分享js的bind函数那些你可能没想过的点

js的bind函数那些你可能没想过的点

1 js中对一个bind返回的函数执行new时会怎样

function A(a,b){
    this.a=a;
    this.b=b
}
var a = A.bind({x:1},1)
var b = new a(2) // {a: 1, b: 2}

加上上一篇文章中说的情况,我们可以总结到,当我们对一个bind返回的函数进行操作时,实际上这种操作是对目标函数的操作,也就是调用bind的函数。下面我们看一下es5文档的说明。

When the [[Construct]] internal method of a function object, F that was created using the bind function is called with a list of arguments ExtraArgs, the following steps are taken: Let target be the value of F’s [[TargetFunction]] internal property. If target has no [[Construct]] internal method, a TypeError exception is thrown. Let boundArgs be the value of F’s [[BoundArgs]] internal property. Let args be a new list containing the same values as the list boundArgs in the same order followed by the same values as the list ExtraArgs in the same order. Return the result of calling the [[Construct]] internal method of target providing args as the arguments.

文档里说到,执行new的时候,实际上是会执行目标函数,并且把所有的参数列表传进去,也就是bind的时候传进去的加上new时传进去的参数。

2 js中当函数执行bind后再次执行bind或call时会怎样

var test = function(x,y){
    console.log(this,arguments)
}
var a=test.bind({s:1},1)
a.call({d:1},2) // {s: 1} 1 2
var b = a.bind({d:1},2)
b()// {s: 1} 1 2

var c = b.bind({e:3},3) 
c()

从上面的代码执行结果中我们发现一点,第一次bind绑定的对象是固定的,也就是后面通过bind或者call再次绑定的时候,就无法修改这个this了,从es5文档中我们能找到答案。

When the [[Call]] internal method of a function object, F, which was created using the bind function is called with a this value and a list of arguments ExtraArgs, the following steps are taken: Let boundArgs be the value of F’s [[BoundArgs]] internal property. Let boundThis be the value of F’s [[BoundThis]] internal property. Let target be the value of F’s [[TargetFunction]] internal property. Let args be a new list containing the same values as the list boundArgs in the same order followed by the same values as the list ExtraArgs in the same order. Return the result of calling the [[Call]] internal method of target providing boundThis as the this value and providing args as the arguments.

这段话中说到如果我们在一个由bind创建的函数中调用call,假设是x.call(obj,y,z,…)并且传入this,和参数列表的时候会执行下面的步骤: 1.首先用三个参数分别保存函数x函数的内部属性中存的this值、目标函数和参数 列表。 2.然后执行目标函数的内部call函数,也就是执行目标函数的代码,并且传入1中保存的this和实参(这里的实参是目标函数本来就有的也就是bind时传入的实参加上调用call时传的实参) 重点在1中,从es5的bind函数说明中我们知道,当我们用一个函数调用bind的时候,返回的函数中会保存这三个参数。所以最后调用call的时候执行的函数是目标函数,也就是调用了bind的函数,传入的this也是bind调用时传入的,这些都是无法被修改的了,但是参数是调用bind和call时的叠加,这是我们唯一可以修改的地方。执行两次bind的原理可以参考bind的源码,和call的差不多,也是目标函数和this是被固定的了,只有参数列表会叠加。

3 js中对bind返回的函数执行new的时候,instanceof的行为

function A(){
}
var b = A.bind({})
var c = new b();
c instanceof A // true
c instanceof b // true

es5文档中说到

When the [[HasInstance]] internal method of a function object F, that was created using the bind function is called with argument V, the following steps are taken: Let target be the value of F’s [[TargetFunction]] internal property. If target has no [[HasInstance]] internal method, a TypeError exception is thrown. Return the result of calling the [[HasInstance]] internal method of target providing V as the argument.

从文档中我们可以知道,对于c和b执行instanceof的时候,其实判断的是c和b的目标函数A的关系,最后是执行正常的instanceof判断,也就是根据原型链去判断。从上一篇中我们知道,c是用A去new出来的,所以c instanceof b是返回true的。

本文分享自微信公众号 - 编程杂技(theanarkh)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-02-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • nginx0.1.0之http模块初始化源码分析(4)

    我们继续分析ngx_http_block函数剩余的代码,剩下的代码就是处理phases和监听的端口、地址、servername的。

    theanarkh
  • js引擎v8源码解析之zone(基于0.1.5)

    theanarkh
  • 发布你的第一个node-cli

    cli可以方便我们的日常工作,类似shell脚本一样。而且可以实现一次编写,到处运行。下面我们来看一下怎么编写一各node-cli。 首先新建一个目录s...

    theanarkh
  • win10 uwp xaml 绑定接口

    早上快乐 就在你的心问了我一个问题,他使用的属性是显式继承,但是无法在xaml绑定

    林德熙
  • 勿乱动arguments对象

    此题是看到51js论坛上有人提出这个问题:求解arguments对象的内部实现原理

    meteoric
  • POJ-----C Looooops

    C Looooops Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 15...

    Gxjun
  • Swift 读标准库源码笔记 -- Integers(基本数据类型篇)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    ZY_FlyWay
  • Kaggle竞赛:《NIPS 2017 Adversarial Learning Challenges》

    Batch normalization potentially helps in two ways: faster learning and higher ov...

    fishexpert
  • 机器人体验营笔记(四)实践

    版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons)

    zhangrelay
  • 二值网络训练--A Empirical Study of Binary Neural Networks' Optimisation

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.n...

    用户1148525

扫码关注云+社区

领取腾讯云代金券