首页 > 编程知识 正文

socket bind函数的参数(手写bind函数)

时间:2023-05-06 07:15:40 阅读:74782 作者:3027

首先,我最近工作很忙,好久没时间在twdyl上研究什么了。 今天在研究call和apply的区别时,看到了github上的文章,读了之后,感觉启发很大。

文章链接到https://github.com/Lin-Xin/blog/issues/7,如果你有兴趣的童鞋,可以学习一下。

但我主要想写的不是我今天学这篇博文,那也太没技术含量了吧。

bind的实现其实文章不容易理解,对js有一定了解的学生就很容易理解。 我主要关心的是文章末尾显示的自己实现bind函数的代码。 代码如下。

if (! function.prototype.bind (function.prototype.bind=function ) ) { var self=this, //保存原始函数context=[].shift.chis其余参数为数组return function () (/新函数self.apply ) context,[ ].concat.cally [].slice.call ) (arguments ) )还给你}}老实说,看了这段代码,你会觉得没什么异样,但细细品味,会觉得很有滋味。

[].shift.call(arguments )的意思对于很多掌握js这种语言不是很深的童鞋来说,这段代码的意思似乎不太容易理解,但我们相信实际细分后,可以分离出几个知识点。

arguments的意思是,相信很多人应该都知道arguments,在实际的学习工作中也经常被使用,所以我想在这里复习一下。

在MDN站点中,Arguments对象的定义如下:

arguments是与传递给函数的参数相对应的类数组对象。

可以看到arguments是类数组对象。 他怎么用呢? 别急,我马上给你举个例子吧。

上面是在chrome浏览器控制台上进行的小测试。 arguments是类数组对象,其值包含调用函数时传递到内部的参数。

另一方面,对于对象的调用,一般采用点编号—— obj.key的调用方式或在括号中添加对象的key的方式—— obj[key],可知这两种方式完全相同。

因此,创建函数时,不需要向内部传递变量,直接在arguments中获取变量不是更好吗? 在我看来,这种方式可以灵活地接收参数,但也存在弊端。 函数的参数本来是为了便于自己和他人阅读而写的。 没有你的话,在c、Java中需要为参数指定类型。 JS已经够松了。 用这个标准慢慢写是很随意的,但是用了会很痛。

[].shift乍一看,你还不一定明白这段代码,但其实和Array.prototype.shift一样,打开你的chrome浏览器控制台,然后打开Array.prototype.shift 只是调用方法有区别,一个是以原型方式在类中直接调用,一个是实例化,继承,然后调用。

如果你对这个话题感兴趣,正好我在知道的地方看到了相关话题的讨论。 在js中[].slice和Array.prototype.slice有什么区别? 你可以自己看和讨论。

如果有同学不知道呼叫呼叫是什么,请到mdn网站的呼叫页面进行详细调查。

mdn的call定义如下:

call ) )方法调用具有指定this值和单独提供的参数(参数列表)的函数。

call的语法如下:

fun.call(thisarg,arg1,arg2,…)

了解了以上三个小知识点后,您现在可以理解[].shift.call(arguments )的含义了。 arguments是类数组对象,没有数组自己的方法,如shift。 我该怎么办? 这里,我想取出传递的参数中的第一个参数,怎么操作,只有这个方法。

试试看:

函数((返回参数; }vartemp=a(a )、(b ); temp.slice (; //uncaught typeerror 3360 temp.sliceisnotafunction如您所见,如果试图直接对temp使用slice ()函数,则不可能,也不可能! 因为arguments是类数组对象,不是真正的对象,没有slice

方法。

但是如果你用下面方法:

[].slice.call(temp); //["a", "b"]

我们可以看到的是,用上面的方式,就神奇般的得到了想要的结果。

我们在类数组对象上面,成功的运用了数组的 slice 方法。也就是说,相当于,先将 temp 转为数组,然后再对其运用了 slice 方法,然后返回了我们想要的结果。

当然,这种写法,在 es6 面前,已经成为了过去式,es6 为数组新增了一个 from 方法,这个函数的使用方式如下:

Array.from(temp).slice(); //["a", "b"]

感兴趣的同学,可以去 mdn 网站去了解 Array.from() 的详细解释。

因此,我们可以总结下,原来 context = [].shift.call(arguments) 这一句就是把参数中的第一个剪切出来,赋给 context,那么也就相当于起到了将 参数中的 this 保存的目的。

args = [].slice.call(arguments);

这一句,将除了 this 上下文的所有参数,传给了 args ,以备后来使用。

bind的理解

要读懂返回值,必须得理解,bind 的作用是什么。

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

有兴趣的同学,可以前往 Function.prototype.bind() 页面查看详细解读。简单点理解,bind 就是用来绑定上下文的,强制将函数的执行环境绑定到目标作用域中去。与 call 和 apply 其实有点类似,但是不同点在于,它不会立即执行,而是返回一个函数。因此我们要想自己实现一个 bind 函数,就必须要返回一个函数,而且这个函数会接收绑定的参数的上下文。

返回函数 return function () { // 返回一个新函数 self.apply(context,[].concat.call(args, [].slice.call(arguments)));}

这一段其实很好理解,因为bind 绑定了上下文,因此 self.apply 的第一个参数,是之前我们保存的 context。接下来,我们将 bind 的其余参数和调用bind后返回的函数在执行的过程中接收的参数进行拼接,作为一个数组传入apply的第二个参数中去。这就完美的实现了 bind 函数的功能,不得不说很是巧妙。

后记

做业务,其实不太能用上这些技术性很强的东西,但是我们如果止步不前,也许我们当初选行业的时候就选错了。互联网行业发展的速度日新月异,几天就出来了一个新的技术,我们如果不进步,就是在退步。

虽然工作很忙,但是也不能忘了充实自己。先立个 flag 吧,尽量每个星期写一篇技术方面的博文,积少成多,慢慢的,自己也会成为大神的吧。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。