c语言bind函数,c语言bind函数返回1的解决方法

http://www.itjxue.com  2023-01-20 12:27  来源:未知  点击次数: 

C语言结构体的一个疑问

你的函数调用是采用值传递的方式,也就是在f函数中另外生成一个结构体,你改变的是这个新生成的结构体的值,main中的结构体t的值不变。

可改用地址传递的方式:

#includestdio.h

struct info

{

int k;

char*s;

}t;

void f(struct info *t)

{

t-k=1997;

t-s="Borland";

}

void main()

{

t.k=2000;

t.s="Inprise";

f(t);

printf("%d,%s\n",t.k,t.s);

}

bind函数报errorc2784

程序出错。

bind函数的作用是通过绑定一个其他func函数生成一个依赖于func的新的函数对象,复用func函数的实现,但是可以改变这个func的参数数量和顺序,可以绑定普通函数、全局函数,静态函数,成员函数,而且其参数可以支持占位符来改变参数的顺序,并且可以设置func中默认的几个参数来减少输入参数的数量。

手动实现bind函数

为什么要自己去实现一个bind函数?

所以,为了理想主义和世界和平(所有浏览器上都能随心所欲调用它),必要的时候需要我们自己去实现一个bind。那么,一个bind函数需要具备什么功能呢?

绑定this、定义初始化参数是它存在的主要意义和价值。MDN对它的定义如下:

鉴于这两个核心作用,我们可以来实现一个简单版看看:

由于arguments是类数组对象,不拥有数组的slice方法,所以需要通过call来将slice的this指向arguments。 args就是调用bind时传入的初始化参数(剔除了第一个参数oThis)。将args与绑定函数执行时的实参arguments通过concat连起来作为参数传入,就实现了bind函数初始化参数的效果。

bind函数的另外一个也是最主要的作用:绑定this指向,就是通过将调用bind时的this(self)指向指定的oThis来完成。这样当我们要使用bind绑定某个对象时,执行绑定函数,它的this就永远固定为指定的对象了~

到这里,我们已经可以用上面的版本来使用大部分场景了。但是~

但是,这种方案就像前面说的,它会永远地为绑定函数固定this为指定的对象。如果你仔细看过MDN关于bind的描述,你会发现还有一个情况除外:

我们可以通过一个示例来试试看原生的bind对于使用new的情况是如何的:

试验结果发现,obj.name依然是lily而没有变成tom,所以就像MDN描述的那样,如果绑定函数cat是通过new操作符来创建实例对象的话,this会指向创建的新对象tom,而不再固定绑定指定的对象obj。

而上面的简易版却没有这样的能力,它能做到的只是永久地绑定指定的this(有兴趣的朋友可以在控制台使用简易版bind试下这个例子看看结果)。这显然不能很好地替代原生的bind函数~

那么,如何才能区分绑定函数有没有通过new操作符来创建一个实例对象,从而进行分类处理呢?

我们知道 检测一个对象是否通过某个构造函数使用new实例化出来的最快的方式是通过 instanceof :

A instanceof B //验证A是否为B的实例

那么,我们就可以这样来实现这个bind:

假设我们将调用bind的函数称为C,将fBound的prototype原型对象指向C的prototype原型对象(上例中就是self),这样的话如果将fBound作为构造函数(使用new操作符)实例化一个对象,那么这个对象也是C的实例,this instanceof self就会返回true。这时就将self指向新创建的对象的this上就可以达到原生bind的效果了(不再固定指定的this)。否则,才使用oThis,即绑定指定的this。

但是这样做会有什么影响?将fBound的prototype原型对象直接指向self的prototype原型对象,那么当修改fBound的prototype对象时,self(上述C函数)的prototype对象也会被修改!!考虑到这个问题,我们需要另外一个function来帮我们做个中间人来避免这个问题,我们看看MDN是怎么实现bind的。

MDN针对bind没有被广泛支持的兼容性提供了一个实现方案:

发现了吗,和上面经过改造的方案相比,最主要的差异就在于它定义了一个空的function fNOP,通过fNOP来传递原型对象给fBound(通过实例化的方式)。这时,修改fBound的prototype对象,就不会影响到self的prototype对象啦~而且fNOP是空对象,所以几乎不占内存。

其实这个思路也是YUI库如何实现继承的方法。他的extend函数如下:

最后一步是将Child的constructor指回Child。

实现一个原生的函数,最重要的是理清楚它的作用和功能,然后逐一去实现它们包括细节,基本上就不会有问题~

这里用到的一些关于 prototype 和 instanceof 的具体含义,可以参考阮一峰老师的 prototype 对象 ,相信对你理解JavaScript的原型链和继承会有帮助~

原文链接:

(责任编辑:IT教学网)

更多

推荐Oracle文章