Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/446.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/447.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript中的Chaining.bind()调用。意外的结果?_Javascript - Fatal编程技术网

JavaScript中的Chaining.bind()调用。意外的结果?

JavaScript中的Chaining.bind()调用。意外的结果?,javascript,Javascript,从: bind()方法创建一个新函数,该函数在调用时将其this关键字设置为提供的值 我很高兴看到它在这个例子中起作用: (function () { console.log(this); }).bind({foo:"bar"})(); 它记录对象{foo=“bar”} 但是,如果我链接另一个绑定调用,或者甚至是一个“调用”调用,我仍然会使用分配给传递给第一个绑定的对象的“this”来调用函数。示例: (function () { console.log(this); }).bin

从:

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

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

(function () {
   console.log(this);
}).bind({foo:"bar"})();
它记录
对象{foo=“bar”}

但是,如果我链接另一个绑定调用,或者甚至是一个“调用”调用,我仍然会使用分配给传递给第一个绑定的对象的“this”来调用函数。示例:

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

这两个日志都是log
Object{foo=“bar”}
而不是我所期望的:
Object{oof=“rab”}

无论我调用了多少绑定调用,似乎只有第一个有效果

为什么?

这可能会有帮助。我刚刚发现jQuery的版本也有同样的表现!:O

jQuery.proxy(
  jQuery.proxy(function() {
      console.log(this);
  },{foo:"bar"})
,{oof:"rab"})();
日志
对象{foo=“bar”}

我在以下位置找到了这一行:

bind()函数使用 函数体(ECMAScript 5术语中的内部调用属性)与 正在调用它的函数(绑定函数的目标 函数)将此值绑定到bind()的第一个参数, 不能被覆盖。


所以,一旦设置好,它可能真的无法被覆盖。

好的,这将主要是猜测,但我将尝试通过它进行推理

ECMAScript规范(目前处于关闭状态)为
bind
函数(强调我自己的功能)规定了以下内容:

15.3.4.5 Function.prototype.bind(thisArg[,arg1[,arg2,…])

bind方法接受一个或多个参数thisArg和(可选) arg1、arg2等,并通过执行 以下步骤:

  • 将目标设为该值的最大值。
  • 如果IsCallable(Target)为false,则引发TypeError异常
  • 假设A是一个新的(可能为空)内部列表,其中包含在thisArg(arg1、arg2等)之后提供的所有参数值
  • 设F为新的本机ECMAScript对象
  • 按照8.12中的规定,设置F的所有内部方法,除了[[Get]]
  • 按照15.3.5.4的规定设置F的[[Get]]内部属性
  • 将F的[[TargetFunction]]内部属性设置为Target。
  • 将F的[[BoundThis]]内部属性设置为thisArg的值
  • 将F的[[BoundArgs]]内部属性设置为A
  • 将F的[[Class]]内部属性设置为“Function”
  • 将F的[[Prototype]]内部属性设置为中指定的标准内置函数Prototype对象 15.3.3.1
  • 如15.3.4.5.1所述,设置F的[[Call]]内部属性
  • 如15.3.4.5.2所述,设置F的[[Construct]]内部属性
  • 如15.3.4.5.3所述,设置F的[[HasInstance]]内部属性
  • 如果Target的[[Class]]内部属性为“Function”,则a。设L是目标的长度属性减去A.b的长度。 将F的length own属性设置为0或L,以两者中的值为准 更大的
  • 否则将F的length own属性设置为0
  • 将F的length own属性的属性设置为15.3.5.1中规定的值
  • 将F的[[Extensible]]内部属性设置为true
  • 让thrower成为[[ThrowTypeError]]函数对象(13.2.3)
  • 使用参数“caller”、PropertyDescriptor{[[Get]]:thrower、[[Set]]:thrower调用F的[[DefineOwnProperty]]内部方法, [[Enumerable]]:false、[[Configurable]]:false}和false
  • 使用参数“arguments”,PropertyDescriptor{[[Get]]:thrower,[[Set]]:thrower, [[Enumerable]]:false、[[Configurable]]:false}和false
  • 返回F
  • 当您对使用
    bind
    创建的对象调用
    函数时:

    15.3.4.5.1[[呼叫]]

    当使用bind函数创建的函数对象F的[[Call]]内部方法用 此值和参数列表为ExtraArgs,下面的步骤是 采取:

  • 设boundArgs为F的[[boundArgs]]内部属性的值
  • 设boundThis为F的[[boundThis]]内部属性的值
  • 让target为F的[[TargetFunction]]内部属性的值。
  • 设args是一个新列表,其中包含与列表边界args相同的值,顺序相同,后跟与列表相同的值 外部参数的顺序相同
  • 返回调用目标的[[Call]]内部方法的结果,该方法提供boundThis作为该值,并提供args作为 论点
  • Call指定如何调用每个函数。并且有点类似于JavaScript
    调用

    someFunction.[[call]](thisValue, arguments) {
    
    }
    
    但是,当对绑定函数使用
    [[call]]
    时,
    此值将被
    [[BoundThis]]]
    的值覆盖。在第二次调用
    bind
    的情况下,尝试覆盖第一次的
    thisValue
    将被
    [[BoundThis]]
    替换,基本上不会对
    thisValue
    的值产生任何影响:

    boundFunction.[[call]](thisValue, arguments) {
      thisValue = boundFunction.[[BoundThis]];
    }
    

    您会注意到,如果尝试并使用
    call
    apply
    ,它们也将无效,因为它们重写
    thisValue
    属性的尝试将在
    [[call]]时被逆转
    调用下一个函数。

    人们很容易将
    绑定
    视为以某种方式修改函数以使用新的
    。在这种(不正确的)解释中,人们认为
    bind
    是在函数中添加了某种魔旗,告诉它下次调用时使用不同的
    this
    。如果是这样,那么应该可以“o”
    boundFunction.[[call]](thisValue, arguments) {
      thisValue = boundFunction.[[BoundThis]];
    }
    
    // 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);
    
    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
    
    function orig() { }
    my_bound_fn = orig.bind(my_obj);
    
    my_bound_fn = my_bound_fn.bind(my_other_obj);     // No effect
    
    my_other_bound_fn = orig.bind(my_other_obj);
    
    function bound_function() {
    
        function original_function() {
            console.log(self);
        }
    
        var self = 1;
        original_function();
    }
    
    bound_function()
    
    function bound_function2() {
    
        function bound_function1() {
    
            function original_function() {
                console.log(self);
            }
    
            var self = 1;
            original_function();
        }
    
        var self = 2;
        bound_function1();
    }
    
    bound_function2()
    
    myFunk.bind(something)
          .unbind(); // -> has same behavior as original myFunk