bind函数原理,自己实现一个bind函数

http://www.itjxue.com  2023-01-16 05:44  来源:未知  点击次数: 

理解this + bind函数

1.this指向规则

四种规则不再展开

箭头函数没有this,访问外围的this

const在全局声明的变量不会挂载在window上

2.bind函数

bind返回一个函数,这个函数的this绑定为所提供好的对象

因为arguments为类数组没有数组的方法,所以要用call

最后返回的函数中,拼接 调用bind时剩余的参数数组 和 过程中传入的参数数组

bind() 和 箭头函数的this

楼主在昨天在看Vue文档的时候,主要到 methods 和 computed 里面不要使用箭头函数,去看了下源码解析,发现里面调用的是通过自定义的 bind 函数,通过 call() 来执行函数以及绑定作用域,想巩固一下箭头函数,于是这篇有内涵的blog就上线了。

之前楼主有一篇 箭头函数的This , 对于它的理解感觉有偏差,这里全部再重复总结一遍。

看完本篇文章,你可以彻底了解this和bind

当使用构造函数的时候,我们需要构建原型链,所以需要加工一下。

解析 : 当我们调用bind()的时候,即执行了 var fn1 = fn.bind({name: 1},1,3) , 会返回一个新的函数,下面是作用域链解析。

实例 : 当我们调用bind()的时候,即执行了 var fn1 = fn.bind({name: 1},1,3) , 会返回一个新的函数,下面是作用域链解析。

再调用fn1(3,4) ,相当于执行函数

答案 {name:1} 3

所以当我们执行 fn.bind({name:1},1,2).call({name:2},3,4) ,本质上 call 并不能改变bind的返回函数的this,只是改变了内部封装了一个函数(xxx)的this,这也是 bind的this参数不能被重写的原因。

一句话总结: 箭头函数的函数体内的 this 就是 定义时候的 this ,和使用所在的this没有关系。

即 :在定义箭头函数的时候就已经绑定了this,可以理解为就是在定义的时候,通过bind函数进行强行绑定this。

总结: 我们知道Vue内部调用 methods 的时候,通过的 call 方法来执行 methods 中的相应的key函数,当我们使用箭头函数的时候,定义的时候就绑定了 this ,它源码中写的 call() 并不会被使用,所以必须不能使用箭头函数

Vue文档中methods的使用

Vue methods 用箭头函数取不到 this

vue源码解析-事件机制

什么时候“不要”用箭头函数

ES6 箭头函数使用禁忌

自己写的推理例子

jQuery中的bind()函数跟on()函数有什么区别呢?

bind()函数可以对同一个对象进行多次事件绑定,bind函数其实就是对on函数进行了处理,如果单纯用on函数来绑定事件的话,那么之前绑定的时间将会被后面的覆盖掉,也就是说,你用on函数给某一个对象绑定了事件1和事件2,但是只有事件2才能被正确执行,事件1则被事件2覆盖掉了。而用bind函数则可以避免这个问题,它可以判断是否已经绑定了其他事件,并且不会将之前绑定的函数覆盖掉,而且如果之前绑定了一个和现在将要绑定的一摸一样的函数的话,这里将不在进行绑定。所以bind是比较强大的。其实bind也是对on函数进行的加工处理得到的。希望采纳

C++ bind函数

bind是一组用于函数绑定的模板。在对某个函数进行绑定时,可以指定部分参数或全部参数,也可以不指定任何参数,还可以调整各个参数间的顺序。对于未指定的参数,可以使用占位符_1、_2、_3来表示。-1表示绑定后的函数的第1个参数,_2表示绑定后的函数的第2个参数,其他依次类推。

bind可以绑定到普通函数、函数对象、类的成员函数和类的成员变量。下面分别进行介绍。

1、普通函数

1 void nine_arguments(int i1,int i2,int i3,int i4,int i5,int i6,int i7,int i8,int i9);

2 int i1=1, i2=2, i3=3, i4=4, i5=5, i6=6, i7=7, i8=8, i9=9;

3 bind(nine_arguments,_9,_2,_1,_6,_3,_8,_4,_5,_7(i1,i2,i3,i4,i5,i6,i7,i8,i9);

4 bind(nine_arguments,i9,i2,i1,i6,i3,i8,_1,_2,_1)(i8,i9);

5 bind(nine_arguments, i9,i2,i1,i6,i3,i8,i4,i5,i7)();

2、函数对象

1 class CStudent

2 {

3 public:

4 void operator() (string strName, int nAge)

5 {

6 cout strName " : " nAge endl;

7 }

8 };

9 bind(CStudent(), "Mike", _1)(12);

3、类的成员函数

1 struct TAdd

2 {

3 int Add(int x,int y)

4 {

5 return x+y;

6 }

7 };

8 TAdd tAdd;

9 TAdd *p = new TAdd();

10 shared_ptrTAdd *q(p);

11 bind(TAdd::Add, tAdd, 2, 3)();

12 bind(TAdd::Add, p, 2, 3)();

13 bind(TAdd::Add, q, 2, 3)();

4、类的成员变量

1 void Output(const string name)

2 {

3 cout name endl;

4 }

5

6 mapint, string map1;

7 for_each(map1.begin(), map1.end(), bind(Output, bind(mapint,

8 string::value_type::second, _1)));

bind还可以进行嵌套绑定。假设有一个CPerson类,该类有一个获取年龄的接口int GetAge(),现在有一个CPerson对象的vector,需要对其进行排序,则可以如下使用bind:

1 vectorCPerson vctPerson;

2 sort(vctPerson.begin(), vctPerson.end(), bind(lessint(),

3 bind(CPerson::GetAge, _1), bind(CPerson::GetAge, _2)));

假设有一个整数的vector, 现在想要获取其中大于20但小于30的整数的个数,则有:

1 count_if(vctNum.begin(), vctNum.end, bind(logic_andbool(),

2 bind(greaterint(), _1, 20), bind(lessint(), _1, 30)));

在使用bind时,还有一些需要特别注意的地方,下面逐一进行介绍。

1、对于指定了值的参数,bind返回的函数对象会保存这些值,并且缺省是以传值方式保存的。考虑下面的代码:

1 void inc(int a) { a++; }

2 int n = 0;

3 bind(inc, n)();

调用bind返回的函数对象后,n仍然等于0。这是由于bind时,传入的是n的拷贝。如果需要传入n的引用,则可以使用ref或cref函数,比如:

1 bind(inc, ref(n))(); // n现在等于1了

2、bind的第一个参数是一个函数对象,不能用占位符来代替。考虑下面的代码:

1 typedef functionvoid (int) Func;

2 vectorFunc vctFunc;

3 for_each(vctFunc.begin(), vctFunc.end(), bind(_1, 5)); // 编译出错

此时,可以借助apply模板。apply模板的第一个参数是传入的函数对象,后面可以有若干个参数,表示函数对象的参数。比如:

1 applyvoid a; // void是函数对象的返回值类型

2 a(f); // 相当于调用f()

3 a(f, x); // 相当于调用f(x)

4 a(f, x, y); // 相当于调用f(x, y)

使用apply后,我们可以将vctFunc中的元素当作占位符传递过来。参考代码如下:

1 for_each(vctFunc.begin(), vctFunc.end(), bind(applyvoid(), _1, 5));

-- 本文来源于创世软件团队博客, 原文地址:

JS之bind浅析及应用场景

fn.bind(obj, args)

bind() 方法会创建一个函数,该函数的 this 指向了传入的第一个参数,当 bind() 的参数为空时, this 指向全局对象。如浏览器中的 window 。

因为 js 是一门 Duck typing 语言,所以我们可以通过 bind 实现一些共有方法。

有的时候我们需要针对特定的 this 调用某些方法。写起来比较麻烦,这个时候就可以使用 bind 创建一个 shortcut 方便调用。

bind 也可以绑定构造函数,但是当执行生成的函数时,会忽略this指向,即使在绑定时已经对其赋值。

(责任编辑:IT教学网)

更多