我正在读this page只是为了精通.apply
语法,但我意识到我在JS知识方面存在空白:
您可以使用this
和.bind
来更改函数中.apply
的值(我假设.call
遵循与.apply
相同的规则,所以我不会单独讨论)。所以我想知道,如果我先使用.bind
然后再使用.apply
进行调用,那会优先吗?
所以我只是从w3schools看了这个示例并对其进行了修改:
var person = {
fullName: function(city, country) {
return this.firstName + " " + this.lastName + "," + city + "," + country;
}
}
var person1 = {
firstName: "John",
lastName: "Doe"
}
var person2 = {
firstName: "Mary",
lastName: "Anne"
}
fn = person.fullName.bind(person2);
console.log(fn.apply(person1, ["Oslo", "Norway"]));
因此,如果打印出玛丽·安妮(Mary Anne),则this
给出的.bind
的值优先于.apply
给出的值。
做到了!与安妮结婚。因此,我想知道是否还有我不太了解的关于this
的其他规则。例如,您可以在呼叫.bind
之后重新绑定吗?
答案 0 :(得分:3)
除了实现Function.prototype.bind
的方式外,没有什么可以阻止重新绑定的。没错,调用绑定后,this
的值是固定的,Function.prototype.apply
无法覆盖它。
代替使用Function.prototype.bind
,您可以使用它来绑定参数:
Function.prototype.create = function(){
const args = arguments;
const original = this;
return function() {
return original.call(this, ...args, ...arguments);
}
};
但是,修改原型可能会出现问题,因此我会避免创建一个辅助函数。我确信像lodash这样的实用程序库或ramda都可以做到这一点。
您可以像这样使用它:
const fn = function (one, two, three) {
return this + one + two + three;
};
const boundfn = fn.create(1, 2);
const val = boundfn.call(-6, 3);
console.log({val});
是的,我们传递了-6
作为this
的值。 :)
-6 + 6 = 0
注意:避免这样做!玩弄上下文是错误的方法,而且绝对不能起作用。我会避免传递this
,因为它是一个不可见的参数,而且“很难推理”。
答案 1 :(得分:2)
.bind
返回绑定函数。 绑定函数和箭头函数将永远不会再更改其上下文,因此您无法重新.bind
它们或.apply
其他上下文。
如果我们假设.bind
是用JavaScript本身编写的,那么它可能会变得更加清楚……然后它将写为:
function bind(context, ...args) {
const fn = this;
return function(...args2) {
// Note: "this" does not get accessed inside this function, so .bind ing it or .apply ing another context doesnt change anything
return fn.call(context, ...args, ...args2);
}
}
答案 2 :(得分:2)
根据规范:
注2:如果func是箭头功能或绑定功能,则在步骤X中,此[Arg]将被功能[[Call]]忽略。
这适用于所有三个绑定功能。
bind
创建一个绑定函数,该函数不是普通函数(它是exotic object),并且不包含原型。
https://www.ecma-international.org/ecma-262/6.0/#sec-function.prototype.apply
答案 3 :(得分:0)
.bind
创建一个具有添加的this
上下文以及您要 curry 的参数的新函数,并且无法用{{1 }},this
(除非您的apply
方法不是本地的),对于已经提到https://stackoverflow.com/a/31656748/906265
bind
的答案
来自MDN
bind()方法创建一个新函数,该函数在被调用时将其this关键字设置为提供的值,并在调用新函数时提供给定的参数序列。
call
和bind
允许您在调用函数时覆盖函数的.apply
值,但不适用于用ES2015 spec note 2编写的箭头或绑定函数
如果func是箭头函数或绑定函数,则thisArg将被函数忽略