Javascript 逐步了解Function.call.bind
一切都是从这个开始的 然后是@MinusFour的回答Javascript 逐步了解Function.call.bind,javascript,Javascript,一切都是从这个开始的 然后是@MinusFour的回答 var slice = Function.call.bind(Array.prototype.slice); 我想知道引擎盖下发生了什么, 我的好奇心因此提出了这个问题 实现什么目标?理解“函数.call.bind” 一步一步地解决同样的问题 开始于 注意:我在这里使用NodeJS 1) **输出** 8 这是意料之中的,没什么特别的 2) 这是我们的最终目标,从有界函数调用函数myFunc 函数(function.call.bind(
var slice = Function.call.bind(Array.prototype.slice);
我想知道引擎盖下发生了什么,
我的好奇心因此提出了这个问题
实现什么目标?理解“函数.call.bind
”
一步一步地解决同样的问题
开始于
注意:我在这里使用NodeJS
1)
**输出**
8
这是意料之中的,没什么特别的
2)
这是我们的最终目标,从有界函数调用函数myFunc
函数(function.call.bind(myFunc)
)
3)
输出
function anonymous() { function myFunc(a, b) { console.log(a + b); } }
function () { [native code] }
1 6 undefined NaN
期待!上面的代码没有任何作用,因为我调用的是“匿名”,
它什么也不做
4)
输出
function anonymous() {
}
期待着'.call'
调用'Function'
,将'this'
设置为'myFunc'
且不带任何参数或函数体。因此,输出是一个空的匿名函数。现在,我可以执行“var adder=Function.call(myFunc,myFunc);”
从步骤3创建相同的函数
到目前为止还不错
5)
输出
function anonymous() { function myFunc(a, b) { console.log(a + b); } }
function () { [native code] }
1 6 undefined NaN
这里第一个参数不会传递给'myFunc'
函数。
对于函数'adder'
(有界函数。调用)而言,这被视为'this'
现在我明白了(或者我误解了?)直到现在,但是
下面的代码是如何工作的
var slice = Function.call.bind(Array.prototype.slice);
function fn(){
var arr = slice(arguments);
}
在我的例子中,第一个参数到加法器被丢弃(或<代码>函数。调用< /代码>将其视为<代码>它的“< /代码>”,同样应该发生在 Studio上面,对吗?
无论如何,我想把它记录下来作为参考恐怕你走错了方向。这一行:
function anonymous() {
}
var slice = Function.call.bind(Array.prototype.slice);
从不调用函数,也从不安排以后调用它。唯一使用的函数
是它的调用
属性<代码>函数
可以是对象
或日期
或RegExp
或任何其他函数,也可以是函数。原型
;没关系<代码>函数。原型
会更直接,可能也不会那么混乱
这有点难以解释,因为它涉及两层处理这个
,其中这个
在不同的时间是不同的事情:
调用
函数调用具有特定值的函数,该值作为第一个参数,传递给它的任何其他参数。例如:
function foo(arg) {
console.log("this.name = " + this.name + ", arg = " + arg);
}
var obj = {name: "bar"};
foo.call(obj, "glarb"); // "this.name = bar, arg = glarb"
在那里,因为我们在foo
上调用了call
,call
调用了foo
,将设置为obj
,并传递“glarb”
参数
call
知道在call
调用过程中,根据这个
是什么,它应该调用什么函数foo.call
在call
期间将设置为foo
。这可能会让人困惑,让我们用图表来说明:
foo.call(obj,“glarb”)
callscall
:
call
查看this=foo
和参数obj
和glarb
call
调用此
(即foo
):
foo
查看this=obj
和单个参数“glarb”
关于slice
,您通常会看到call
与它一起使用,用于从某种数组创建一个数组,就像它不是真正的数组一样:
var divArray = Array.prototype.slice.call(document.querySelectorAll("div"));
或
在那里,我们调用call
,将设置为Array.prototype.slice
(或[].slice
,这是相同的函数),并将querySelectorAll
返回的集合作为第一个参数传递call
调用它认为是this
的函数,将其第一个参数用作该调用的this
,并传递任何其他参数
这是这个东西的第一层
bind
是函数具有的另一个函数,它与call
类似,但不同:其中call
使用给定的this
和参数调用目标函数,bind
创建并返回一个新函数,如果您调用它,它将执行此操作。回到我们的foo
示例:
function foo(arg) {
console.log("this.name = " + this.name + ", arg = " + arg);
}
var obj = {name: "bar"};
var fooWithObjAndGlarb = foo.bind(obj, "glarb");
fooWithObjAndGlarb(); // "this.name = bar, arg = glarb"
这称为将对象(obj
和的“glarb”
参数)绑定到foo
与call
不同,由于bind
创建了一个新函数,因此我们可以稍后添加参数:
function foo(arg) {
console.log("this.name = " + this.name + ", arg = " + arg);
}
var obj = {name: "bar"};
var fooWithObj = foo.bind(obj);
fooWithObj("glarb"); // "this.name = bar, arg = glarb"
好的,现在我们有了所有的工件。那么代码中发生了什么?让我们把它分成几个部分:
// Get a reference to the `call` function from the `call` property
// on `Function`. The reason `Function` has a `call` property is that
// `Function` is, itself, a function, which means its prototype is
// `Function.prototype`, which has `call` on it.
var call = Function.call;
// Get a reference to the `slice` function from `Array.prototype`'s `slice` property:
var rawSlice = Array.prototype.slice;
// Create a *bound* copy of `call` that, when called, will call
// `call` with `this` set to `rawSlice`
var callBoundToSlice = call.bind(rawSlice);
(callBoundToSlice
在你的问题中只是被称为slice
,但我使用callBoundToSlice
来避免混淆。)将rawsice
绑定到call
是这个处理的第一层,确定调用的将被视为这个。调用callBoundToSlice
将调用call
,并将设置为rawSlice
。然后,call
将调用它认为是this
(rawsice
)的函数,在调用过程中使用其第一个参数作为this
的值(this
处理的第二层)并传递任何进一步的参数
因此,我们的forEach
和来自querySelectorAll
的集合现在可以如下所示:
callBoundToSlice(document.querySelectorAll("div")).forEach(function(div) {
// Each div here
});
它将querySelectorAll
返回的集合传递到callBoundToSlice
,调用call
,调用this
作为rawsice
,调用Array.prototype.slice
function foo(arg) {
console.log("this.name = " + this.name + ", arg = " + arg);
}
var obj = {name: "bar"};
var fooWithObj = foo.bind(obj);
fooWithObj("glarb"); // "this.name = bar, arg = glarb"
// Get a reference to the `call` function from the `call` property
// on `Function`. The reason `Function` has a `call` property is that
// `Function` is, itself, a function, which means its prototype is
// `Function.prototype`, which has `call` on it.
var call = Function.call;
// Get a reference to the `slice` function from `Array.prototype`'s `slice` property:
var rawSlice = Array.prototype.slice;
// Create a *bound* copy of `call` that, when called, will call
// `call` with `this` set to `rawSlice`
var callBoundToSlice = call.bind(rawSlice);
callBoundToSlice(document.querySelectorAll("div")).forEach(function(div) {
// Each div here
});
var divArray = Array.from(document.querySelectorAll("div"));