[英]JavaScript: The Good Parts - chapter 8, function.apply()
For the following code, based on page 84 of "JavaScript: The Good Parts", can someone explain why [1] and [0] are used? 对于以下基于“ JavaScript:优质零件”的第84页的代码,有人可以解释为什么使用[1]和[0]吗? I understand that they're supplying the arguments 1 and 0 to slice, respectively, but what's the point of that?
我知道他们分别提供参数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?
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.
I believe I understand the big picture - the function x has been designed to extract the value of the value property. 我相信我了解全局-函数x旨在提取value属性的值 。 We then bind an object that has a value property name/value pair and execute the x function.
然后,我们绑定一个具有值属性名称/值对的对象,并执行x函数。 The x function reaches into the supplied object, as if it where a method of that object, and returns the value of the value property.
x函数进入所提供的对象,就像该对象的方法一样,并返回value属性的值 。
What I do not understand is how this is accomplished (I note Crockford's quasi-amusing use of 666 ). 我不了解这是如何实现的(我注意到Crockford准使用666 )。 Thanks in advance.
提前致谢。
The second argument for apply needs to be an array, if [2] were 2 instead, this would happen apply的第二个参数必须是一个数组,如果[2]改为2,则会发生这种情况
Array.prototype.slice.apply(arguments, 2);
Array.prototype.slice.apply(arguments,2); Uncaught TypeError: Function.prototype.apply: Arguments list has wrong type
未捕获的TypeError:Function.prototype.apply:参数列表具有错误的类型
arguments
is a baked in property which represents all of the arguments send to a function in an array like object. arguments
是一个烘培的属性,它代表发送给类似对象数组中的函数的所有参数。 slicing this array will remove unwanted parts. 切片此数组将删除不需要的部分。 In the case of bind,
that
is passed as an argument so slicing after 1 will remove that. 在bind的情况下,将
that
作为参数传递,因此在1之后进行切片将删除该参数。
As a result 结果是
var args = slice.apply(arguments, [1]); // Why is [1] here?
Will take all of the extra arguments sent to bind, for example .bind({},1,2,3,4) will result in args being [1,2,3,4] 将采用所有发送来绑定的额外参数,例如.bind({},1,2,3,4)将导致args为[1,2,3,4]
Next, a function is returned 接下来,返回一个函数
return function () {
return method.apply(that, args.concat(slice.apply(arguments, [0]))); // Why is [0] here?
};
that
is going to be the new scope to use, method
is the function that bind was originally called from, args.concat
is going to take the previous array examined, and then add in all of the arguments which the method was called with, which is why [0]
was used as opposed to [1]
(where that
was passed and was not being used as an argument for the method). that
是要使用的新作用域, method
是最初从bind调用的函数, args.concat
将接受先前检查的数组,然后添加使用该方法调用的所有参数,其中就是为什么[0]
被用作相对于[1]
其中, that
被传递并没有被用作用于该方法的自变量)。
Function.prototype.apply()
takes 2 arguments, a value for this
and an array of arguments
. Function.prototype.apply()
需要两个参数,对于一个值this
和的阵列 arguments
。 Even if there is only one argument, it expects an array. 即使只有一个参数,它也需要一个数组。
So: 所以:
slice.apply(arguments, [1]);
is almost equivalent to: 几乎等同于:
arguments.slice(1);
I say almost because arguments
is not a real array, and it does not have a slice method, which is why you have to do this the funky way. 我说这几乎是因为
arguments
不是真正的数组,并且它没有切片方法,这就是为什么您必须采用时髦的方式。
As others note in the comments, you can use call
instead to make this cleaner. 正如其他人在评论中指出的那样,您可以改用
call
来使其更整洁。 call
expects a value for this this
and then any number of additional individual arguments. call
预计,该值this
,然后任意数量的附加参数的方式。 Which means you can instead do: 这意味着您可以改为:
slice.call(arguments, 1);
Let's assume you have some function, it doesn't matter what it does, and you are binding it to a context and passing some arguments in. 假设您有一些函数,不管它做什么,都将其绑定到上下文并传递一些参数。
function myFunc(a, b, c) {
}.bind(myContext, arg1, arg2)
Now let's look at what .bind
does: 现在让我们看一下
.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
takes the arguments context, [arg1, arg2, ...]
. apply
接受参数context, [arg1, arg2, ...]
。 So slice.apply(arguments, [1])
is like calling arguments.slice(1)
. 所以
slice.apply(arguments, [1])
就像调用arguments.slice(1)
。 (As noted in the comments, you could use call
and drop the array brackets.) The purpose of the 1
is to start the slice from the 1
index. (如注释中所述,您可以使用
call
并放下数组括号。) 1
的目的是从1
索引开始切片。 that
which is passed in is arguments[0]
. that
这是在传递是arguments[0]
Any arguments passed to .bind
after the context would be included in this slice. 上下文之后传递给
.bind
任何参数都将包含在此片中。 So you might call myFunc.bind(myContext, arg1, arg2)
; 因此,您可以调用
myFunc.bind(myContext, arg1, arg2)
; that slice
would set args
to [arg1, arg2]
. 该分
slice
会将args
设置为[arg1, arg2]
。
return function () {
return method.apply(that, args.concat(slice.apply(arguments, [0]))); // Why is [0] here?
};
};
This is the function that gets returned by .bind
; 这是
.bind
返回的函数; this is the function that will actually be called when myFunc(some, params, here)
is called directly. 这是当直接调用
myFunc(some, params, here)
时实际上将被调用的函数。 The slice
in this case is the entire arguments list; 在这种情况下,
slice
是整个参数列表; slicing from 0 returns the whole list, converted to an array, so that it can be passed to the outer apply.
从0切片将返回整个列表,并将其转换为数组,以便可以将其传递到外部
apply.
The first arguments are sliced from 1
to drop that
and get all the arguments after it. 第一个参数从薄片
1
下降that
和之后获得的所有参数。 The second list is sliced from 0
to include ALL the arguments passed in. 第二个列表从
0
切片,以包含所有传入的参数。
Take a closer look at Function.prototype.apply() , the arguments object , and the slice function . 仔细看看Function.prototype.apply() , arguments对象和slice函数 。
apply
takes an object as the context to call a function, with an additional optional parameter of an array of arguments to send to the called function. apply
将对象作为调用函数的上下文,并将参数数组的附加可选参数发送给被调用的函数。
slice(0)
is often used to covert array-like objects into arrays. slice(0)
通常用于将类似数组的对象转换为数组。
slice.apply(arguments, [0])
is nearly equivalent to arguments.slice(0), except that it will not alter the arguments sent to the main function, but will result in a new array, guaranteed to be an array. slice.apply(arguments, [0])
几乎等同于arguments.slice(0),不同之处在于它将不会更改发送到主函数的参数,但会导致一个新数组,保证是一个数组。
Similar to above, but will remove the first entry from the array. 与上面类似,但是将从数组中删除第一个条目。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.