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:好的部分-第8章,function.apply()_Javascript_Bind_Apply - Fatal编程技术网

JavaScript:好的部分-第8章,function.apply()

JavaScript:好的部分-第8章,function.apply(),javascript,bind,apply,Javascript,Bind,Apply,对于以下代码,基于“JavaScript:the Good Parts”第84页,有人能解释为什么使用[1]和[0]?我知道他们分别为切片提供参数1和0,但这有什么意义 Function.prototype.bind = function (that) { var method = this; var slice = Array.prototype.slice; var args = slice.apply(arguments, [1]); // Why is [1] here?

对于以下代码,基于“JavaScript:the Good Parts”第84页,有人能解释为什么使用[1][0]?我知道他们分别为切片提供参数10,但这有什么意义

Function.prototype.bind = function (that) { 
  var method = this;
  var slice = Array.prototype.slice;
  var args = slice.apply(arguments, [1]); // Why is [1] here?

  return function () { 
    return method.apply(that, args.concat(slice.apply(arguments, [0]))); // Why is [0] here?
  };
};

var x = function () { 
  return this.value;
}.bind({ value: 666 }); 

console.log(x()); // Returns 666.
我相信我了解全局-函数x设计用于提取value属性的值。然后,我们绑定一个具有值的对象属性名/值对,并执行x函数。x函数进入提供的对象,就好像它是该对象的方法一样,并返回value属性的值


我不明白的是这是如何实现的(我注意到Crockford对666的近乎有趣的使用)。提前感谢。

apply的第二个参数需要是数组,如果[2]是2,则会发生这种情况

Array.prototype.slice.apply(参数,2); 未捕获类型错误:Function.prototype.apply:参数列表的类型错误

arguments
是一个烘焙属性,它表示发送到类似数组的对象中的函数的所有参数。切片此阵列将删除不需要的部分。在bind的情况下,
作为参数传递,因此在1之后切片将删除该参数

结果

var args = slice.apply(arguments, [1]); // Why is [1] here?
例如,将获取发送到bind的所有额外参数。bind({},1,2,3,4)将导致args为[1,2,3,4]

接下来,返回一个函数

return function () { 
 return method.apply(that, args.concat(slice.apply(arguments, [0]))); // Why is [0] here?
};

将要使用的新范围,
方法
是最初从
args调用bind的函数。concat
将使用前面检查过的数组,然后添加调用该方法时使用的所有参数,这就是为什么使用
[0]
而不是
[1]
(其中,
已传递且未用作方法的参数)。

函数。prototype.apply()
接受两个参数,一个值表示
和一个
参数数组。即使只有一个参数,它也需要一个数组

因此:

几乎相当于:

arguments.slice(1);
我之所以这么说,几乎是因为
参数
不是一个真正的数组,而且它没有切片方法,这就是为什么你必须用一种时髦的方式来做这件事

正如其他人在评论中所指出的那样,您可以使用
call
来简化此操作。
call
需要此
this
的值,然后是任意数量的附加参数。这意味着您可以改为执行以下操作:

slice.call(arguments, 1);

让我们假设您有一些函数,不管它做什么,并且您将它绑定到一个上下文并传入一些参数

function myFunc(a, b, c) {

}.bind(myContext, arg1, arg2)
现在让我们看看
.bind
的作用:

Function.prototype.bind = function (that) { 
  var method = this;
  var slice = Array.prototype.slice;
  var args = slice.apply(arguments, [1]); // Why is [1] here?
apply
接受参数
上下文[arg1,arg2,…]
。因此
slice.apply(arguments,[1])
类似于调用
参数。slice(1)
(如注释中所述,您可以使用
call
并去掉数组括号。)
1
的目的是从
1
索引开始切片。
传入的
参数[0]
。上下文之后传递给
.bind
的任何参数都将包含在此切片中。因此,您可以调用
myFunc.bind(myContext,arg1,arg2)
;该
切片将
args
设置为
[arg1,arg2]

  return function () { 
    return method.apply(that, args.concat(slice.apply(arguments, [0]))); // Why is [0] here?
  };
};
这是由
.bind
返回的函数;这是在
myFunc时实际调用的函数(这里是一些参数)
直接调用。本例中的
切片是整个参数列表;从0切片返回整个列表,转换为数组,以便可以将其传递到外部
apply。


太长,读不下去了 第一个参数从
1
切片,以删除
that
并获取其后面的所有参数。第二个列表从
0
切片,以包含传入的所有参数。

文档和上下文 请仔细查看、和

apply
将对象作为调用函数的上下文,并向被调用函数发送参数数组的附加可选参数

切片(0)
slice(0)
通常用于将类似数组的对象转换为数组

slice.apply(arguments,[0])
几乎等同于arguments.slice(0),只是它不会更改发送到主函数的参数,而是会生成一个新数组,保证为数组

切片(1)
与上面类似,但将从数组中删除第一个条目。

这看起来很愚蠢。如果有什么问题,我会使用
slice.call(arguments,1)
。重点是将第一个(
0
index)之后的所有参数放入新数组。这与更常见的
[].slice.call(arguments,1)相同
。如果
参数
是一个实数组,那么您可以编写
参数。如果您询问为什么会有括号,这是因为它将参数作为数组应用到函数中。正如@Ian所指出的,使用call允许您使用参数,而无需将参数包装到数组中。
  return function () { 
    return method.apply(that, args.concat(slice.apply(arguments, [0]))); // Why is [0] here?
  };
};