2013-11-26 7 views
4

Я боролся с использованием этих «это» с помощью метода .bind() и использования переменной «self = this». Получая два разных результата, я не понимаю одну концепцию. Дело в том, как следующие:Разница между использованием переменной self vs this

// Defining a callback class to use after retrieving data 
var Callback = (function(){ 
    // UPDATED!! Local vbles 
    var template_to_use, html_element, self; 

    function Callback(){ 
     self = this, 
     template_to_use = null, 
     html_element = null; 
    } 

    var p = Callback.prototype; 
    p.set_template = function(template_funct){ 
     self.template_to_use = template_funct; 
    }; 

    p.set_html_element = function(html_element){ 
     self.html_element = html_element; 
    }; 

    p.use_callback  = function(data){                
     $(self.html_element).append(self.template_to_use(data)); 
    }; 

    return Callback; 
})(); 

Использование этой функции, как следующие:

// Setup callback 1 to call after getting the data 
var callback_1 = new Callback(); 
callback_1.set_template(use_templ_1); 
callback_1.set_html_element("#list"); 

// Get list data 
api_list.get_data(callback_1.use_callback); 


// Setup callback 2 to call after getting more data 
var callback_2 = new Callback(); 
callback_2.set_template(use_templ_2); 
callback_2.set_html_element("#object"); 

// Get object data 
api_object.get_data(callback_2.use_callback); 

Два Аякса вызовы выполняются и как только функция get_data() будет сделано, они будут вызывать функции обратного вызова что я прошел к ним. Проблема, которую я получаю, заключается в том, что после выполнения этих функций обратный вызов всегда упоминает html_element = "#object" с соответствующим шаблоном "use_templ_2".

Если я использую функцию «this» и .bind вместо «self» vble, результаты являются ожидаемыми.

// Get object data 
api_object.get_data(callback_2.use_callback.bind(callback_2)); 

Что мне не хватает? Это может быть концепция ошибки, поскольку, даже если я не новичок в js, я понимаю новое знание самого языка.

+2

Вы не определяете переменную 'self' как локальную переменную, поэтому обе функции используют * такую ​​же * глобальную переменную. – JJJ

+0

Прежде всего, не используйте .bind(), если вам не нужно использовать очень старую версию jQuery. on() - предпочтительный метод. – trysis

+0

@Juhana: похоже, что 'var' отсутствует, есть запятые для всех, кроме последнего. –

ответ

2

Будьте осторожны, self всегда будет относиться к последнему инстанциирован объекта:

var c1 = new Callback(); 
var c2 = new Callback(); // overrides previous self 

Тогда следующая строка фактически устанавливает c2.html_element:

c1.set_html_element(html_element); 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures

Тем не менее, замена this полностью бесполезно в вашем случае.

+0

Я читал ссылку, которую вы передали мне и мне, было бы разумно, если бы я реализовал шаблон модуля, в котором будут разделяться vbles. Мне не хватает какой-то концепции, но я понятия не имею, какой из них. Если есть два объявления, создающие два объекта, почему они не сохраняют свои собственные значения? На самом деле свойства «template_to_use» и «html_element» сохраняют свои собственные значения, но не свойство «self». – kitimenpolku

+1

Существует только одно объявление, которое обертывает переменную self, все объекты на самом деле разделяют общую область: '(function() {...})()'. – leaf

+0

Это довольно сложно объяснить, надеюсь, что люди могут поделиться лучшими ссылками. – leaf

4

Если вы спрашиваете о разнице между self и this, то self используется в качестве ссылки на оригинальный this. Это означает, что даже если содержимое this меняется, то self все еще содержит предыдущий.

Не знаю, достаточно ли это достаточно ясно. Если вы не посмотрите What underlies this JavaScript idiom: var self = this? или Difference between self and this in javascript and when to use either of them.

Также старайтесь избегать использования self в качестве глобальной переменной, поскольку оно используется браузерами в настоящее время для чего-то. Извините, я не помню, для чего - если бы кто-то мог отредактировать эту информацию, это было бы потрясающе.

+2

Вы можете использовать 'window.self' (текущее окно) для сравнения, например,' window.top'.Это не противоречит использованию локального var, называемого 'self', поскольку это будет иметь более высокий приоритет. –

+0

+1 Спасибо за разъяснение! – Dropout

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