2013-03-14 4 views
12

Я искал в 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

В не делает разницу в вашем примере, потому что 'google.makeBeer' не использовать' this'. При вызове 'google.makeBeer (...);', 'this' внутри функции будет ссылаться на' google'. Когда вызывается как 'google.makeBeer.call (yah, ...);', 'this' будет ссылаться на' yah'. 'bind' фактически не выполняет функцию, он создает новую функцию, где' this' и необязательно некоторые параметры привязаны к переданным аргументам. См. Https: //developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this и https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind –

+0

Я думаю, что основное различие между DOM методы '.call()' и '.apply()' - количество аргументов, которые могут быть переданы (один из них позволяет, по-моему, еще один). Я не уверен, что относится к '.bind()', но часто относится к событиям, а их обработчики «привязаны». –

ответ

12

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 
3

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 
+0

'.bind' не выполняет функцию. –

+0

yeah sry .. ill edit my ans –

+1

Кроме того, 'this' не является контекстом. Это локальная переменная, заданная вызовом или связыванием. – RobG

2

Просто говоря, что не отличается от применить() и вызов() только разные между ними является аргументом, что вы передаете .В применить() вы должны передать аргумент как массив, где в вызове() метод вы передаете аргументы в форме, разделенной запятыми.

Говоря о методе связывания, это новый метод, введенный в EcmaScript5 и специально используемый для разрешения области this при вызове метода объектов. this особенно полезен при вызове асинхронного метода.

+1

'this' не является областью, это (по существу) локальная переменная, заданная вызовом. – RobG

Смежные вопросы