Разница между методом bind, apply и call?
Я искал в stackoverflow и в Интернете, не мог получить правильные результаты или объяснение различий между этими тремя методами.
Насколько я понимаю, все они выполняют то же самое, выполняя function/method in different context.
var google = {
makeBeer : function(arg1,arg2){
alert([arg1, arg2]);
}
}
google.makeBeer('water','soda');
Это моя нормальная функция объекта google. Теперь, когда я использую метод вызова и связывания здесь, вот вывод.
var google = {
makeBeer: function (arg1, arg2) {
alert([arg1, arg2]);
}
}
google.makeBeer('water', 'soda');
function yahoo() {}
var yah = new yahoo();
google.makeBeer.call(yah, 'pepsi', 'coke');
function msn() {
}
var msn = new msn();
google.makeBeer.call(msn, 'sprite', 'limca');
Я все еще не вижу цели сделать это, я могу пойти вперед и вызвать google.makeBeer three times with different arguments.
Может ли кто-нибудь просветить меня по этому поводу.
Ответы
Ответ 1
apply
и call
- это одно и то же, за исключением того, что принимается аргумент, передаваемый функции в виде массива другой в форме параметра.
bind
делает то же самое, что и call
или apply
в зависимости от используемой структуры, но не вызывает функцию сразу, вместо этого возвращает новую функцию с вашими параметрами, привязанными к this
, и когда функция вызывается из новой области или контекста, this
все равно останется тем, с чем вы привязаны к ней. Связывание также позволяет предотвратить "взломать" конструкторы от apply
или call
, поскольку он всегда будет использовать привязанные параметры для this
независимо от того, что кто-то отправляет, чтобы попытаться переопределить this
через call
или apply
.
Вот пример:
function Profile(u) {
this.user = u;
this.getUser = function () {
return this.user;
};
}
function Profile2(u) {
this.user = u;
this.getUser = (function () {
return this.user;
});
}
function Profile3(u) {
this.user = u;
this.getUser = (function () {
return this.user;
});
}
var x = new Profile('guest');
var x2 = new Profile2('guest');
var x3 = new Profile3('guest');
alert(x.getUser.apply({
user: 'Vinoth'
})); // Vinoth
alert(x2.getUser.call({
user: 'Babu'
})); // babu
alert(x3.getUser.bind(x3).call({
user: 'Nandan'
})); // Guest
Ответ 2
bind
создает новую функцию с тем же самым телом функции, а затем возвращает новую функцию
call
вызовы одной и той же функции в другом переданном контексте, и параметры должны быть явно записаны, apply
вызовы одной и той же функции в другом переданном контексте, но параметры должны передаваться в массиве
var f = function(p1, p2) {
var s = this;
}
var newFunc = f.bind(window, 1, 2);
// here newFunc is a function which when you will call will have this as window and p1 = 1 and p2 = 2
f.call(window, 1, 2);
// by executing this line this = window p1 = 1 and p2 = 2
f.call(document, 2, 3);
// by executing this line this = document p1 = 2 and p2 = 3
f.apply(window, [1, 2]);
// by executing this line this = window p1 = 1 and p2 = 2
Ответ 3
Проще говоря, нет никакого различия между apply() и call(), только разные между ними - это аргумент, который вы передаете. В apply() вы должны передать аргумент как массив, где в методе call() вы передаете аргументы в запятая.
Говоря о методе связывания, это новый метод, введенный в EcmaScript5 и специально используемый для разрешения области this
при вызове метода объектов. this
особенно полезен при вызове асинхронного метода.