链接.bind()调用JavaScript。出乎意料的结果? [英] Chaining .bind() calls in JavaScript. Unexpected result?

查看:106
本文介绍了链接.bind()调用JavaScript。出乎意料的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自 MDN


bind()方法创建一个新函数,在调用时,将其this关键字设置为提供的值

The bind() method creates a new function that, when called, has its this keyword set to the provided value

我很高兴看到它在这个例子中起作用:

And I can happily see it working in this example:

(function () {
   console.log(this);
}).bind({foo:"bar"})();

记录对象{foo =bar}

但如果我链接另一个绑定调用,甚至是调用调用,我仍然会调用调用该函数并将this分配给该对象传递给第一个绑定。示例:

But if I chain another bind call, or even a "call" call, I'm still getting the function invoked with "this" assigned to the object passed to the first bind. Examples:

(function () {
   console.log(this);
}).bind({foo:"bar"}).bind({oof:"rab"})();

&

(function () {
   console.log(this);
}).bind({foo:"bar"}).call({oof:"rab"});

两个日志对象{foo =bar} 而不是我期望的:对象{oof =rab}

Both log Object { foo="bar"} instead of what I would expect: Object { oof="rab"}.

无论多少绑定调用I链,只有第一个似乎有效。

No matter how many bind calls I chain, only the first one seems to have an effect.

为什么?

这可能会有所帮助。我刚刚发现jQuery的版本行为方式相同! :O

This might help. I just found out jQuery's version is behaving the same way! :O

jQuery.proxy(
  jQuery.proxy(function() {
      console.log(this);
  },{foo:"bar"})
,{oof:"rab"})();

logs Object {foo =bar}

推荐答案

很有可能将 bind 视为某种方式修改函数以使用新的。在这个(不正确的)解释中,人们会想到 bind 为函数添加某种魔术标志,告诉它使用不同的这个下次打电话给他。如果是这种情况,则应该可以覆盖并更改魔术标志。然后人们会问,任意限制这种能力的原因是什么?

It is tempting to think of bind as somehow modifying a function to use a new this. In this (incorrect) interpretation, people think of bind as adding some kind of magic flag to the function telling it to use a different this next time it's called. If that were the case, then it should be possible to "override" and change the magic flag. And one would then ask, what is the reason for arbitrarily restricting the ability to do so?

但事实上,这是它是如何运作的。 bind 创建并返回一个 new 函数,在调用时调用具有特定的第一个函数此。在创建函数时,使用指定的 this 来调用原始函数的新创建函数的行为中刻录。它不能被改变,因为函数返回的任何其他函数的内部都可以在事后更改。

But in fact, that's not how it works. bind creates and returns a new function which when called invokes the first function with a particular this. The behavior of this newly created function, to use the specified this to call the original function, is burned in when the function is created. It cannot be changed any more than the internals of any other function returned by a function could be changed after the fact.

这可能有助于查看一个真正简单的实现 bind

It may help to look at a real simple implementation of bind:

// NOT the real bind; just an example
Function.prototype.bind = function(ctxt) {
    var fn = this;
    return function bound_fn() {
        return fn.apply(ctxt, arguments);
    };
}

my_bound_fn = original_fn.bind(obj);

如你所见,中没有任何地方bound_fn ,从 bind 返回的函数,它是否引用了调用绑定函数的 this 。它被忽略了,所以

As you can see, nowhere in bound_fn, the function returned from bind, does it refer to the this with which the bound function was called. It's ignored, so that

my_bound_fn.call(999, arg)            // 999 is ignored

obj = { fn: function () { console.log(this); } };
obj.fn = obj.fn.bind(other_obj);
obj.fn();                            // outputs other_obj; obj is ignored

所以我可以绑定从 bind 再次,但重新绑定原始函数;它只是绑定外部函数,它对内部函数没有影响,因为它已经设置为调用底层函数,并将上下文( this 值)传递给结合。我可以一次又一次地绑定但是我最终做的就是创建更多外部函数,这些函数可能绑定到某些东西但最终仍然调用从第一个 bind 返回的最内层函数。

So I can bind the function returned from bind "again", but that is not rebinding the original function; it's merely binding the outer function, which has no effect on the inner function, since it is already set up to call the underlying function with the context (this value) passed to bind. I can bind again and again but all I end up doing is creating more outer functions which may be bound to something but still end up calling the innermost function returned from the first bind.

因此,说 bind 无法覆盖有点误导。

Therefore, it is somewhat misleading to say that bind "cannot be overridden".

如果我想重新绑定一个函数,那么我可以对原始函数进行新的绑定。所以如果我绑定一次:

If I want to "rebind" a function, then I can just do a new binding on the original function. So if I've bound it once:

function orig() { }
my_bound_fn = orig.bind(my_obj);

然后我想安排我的原始函数与其他一些这个,然后我不重新绑定绑定函数:

and then I want to arrange for my original function to be called with some other this, then I don't rebind the bound function:

my_bound_fn = my_bound_fn.bind(my_other_obj);     // No effect

相反,我只是创建一个绑定到原始函数的新函数:

Instead, I just create a new function bound to the original one:

my_other_bound_fn = orig.bind(my_other_obj);

这篇关于链接.bind()调用JavaScript。出乎意料的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆