2013-06-21 3 views
9

ли это лучше сделать,Лучше ли связывать это или использовать переменную?

asset.addEventListener("load", function() { 
    this.emit({ 
    type: "load", 
    asset: asset 
    }); 
}.bind(this), false); 

Или

var scope = this; 

asset.addEventListener("load", function() { 
    scope.emit({ 
    type: "load", 
    asset: asset 
    }); 
}, false); 

Это лучше, чтобы связать функцию, или просто сохранить ссылку на this в переменной?

+1

Что вы подразумеваете под "лучше"? Быстрее? – TimWolla

+1

@DanyCaissy JQuery не является ответом на все, особенно если вы хотите изучить базовый javascript, если бы все просто использовали Jquery, который создавал бы новые потрясающие библиотеки, я уверен, что до того, как Jquery выпустят каждый из них, просто используйте someLibrary, но если создатель JQuery сделал что не было бы JQuery! – user2251919

+0

@ user2251919: Это для людей, которые беспомощны без него! –

ответ

2

Я чувствую, что второй вариант лучше, просто чтобы избежать путаницы. Использование this было проблемой многих проблем JavaScript, поэтому, когда вы можете избежать этого, вы должны, на мой взгляд. Кстати, это также делается в таких библиотеках, как Knockout.

Если вы хотите узнать больше о this ключевом слове, это хорошее объяснение различных различных значений this может иметь в разных контекстах: не http://javascriptweblog.wordpress.com/2010/08/30/understanding-javascripts-this/

+0

Я все еще участвую, и есть так много способов сделать что-то, сбивает с толку! Спасибо за Ваш ответ. – user2251919

+0

@ user2251919 Добро пожаловать! –

-1

Ни один из них, потому как создавать анонимные функции, которые вы никогда не удаляется позже.

var scope = this; 
var handler = function() { 
    scope.emit({ 
    type: "load", 
    asset: asset 
    }); 
}; 

asset.addEventListener("load", handler, false); 
+0

Зачем вам нужно удалить слушателя? –

+0

Но с точки зрения привязки и не связывания? – user2251919

+1

Вопрос не в том, что касается слушателей. Речь идет о ссылках на замыкания и связанных ссылках. –

4

Это действительно зависит от целого ряда факторов. Вот несколько соображений:

  • Исторически функция, созданная из .bind() была медленнее.

  • Связанный this не может изменить свое значение, в то время как переменная может. (Угадайте, что вы не увидите здесь изменений.)

  • Вы потеряете ссылку на элемент, хотя вы все равно можете получить ее через event.currentTarget.


Еще одна альтернатива, чтобы рассмотреть, чтобы сделать ваш объект реализации интерфейс Event Listener . Это позволит вам передать объект как обработчик и вызовет вашу реализацию метода handleEvent(), который вы предоставляете.

Тогда значение this будет автоматически вашим объектом.

Так что если ваш this является объект, который приходит из конструктора, вы можете сделать это:

function MyCtor() { 
    // your constructor 
} 
 // This implements the `Event Listener` interface 
MyCtor.prototype.handleEvent = function(event) { 
      // ------v----should be "load" 
    return this[event.type](event) 
}; 
 // This is the `load` handler 
MyCtor.prototype.load = function(event) { 
    this.emit({ 
     type: "load", 
     asset: event.currentTarget 
    }); 
};

А затем связать обработчик вроде этого:

asset.addEventListener("load", this, false); 

Теперь ваше значение в событии handle будет вашим объектом, поэтому вы можете вызвать его другой метод s, и не было ни .bind, ни переменной закрытия.

+0

Спасибо, что это отличное понимание того, как все работает под обложками :) – user2251919

0

Второй вариант совместим с большим количеством браузеров. Функция bind() не поддерживается IE 8 и ниже, если это имеет к вам значение.

Сайт Mozilla на bind имеет pollyfill for the bind function. По моему опыту, обычно это плохая идея добавить к прототипу встроенных объектов. Таким образом, второй вариант «лучше» - просто убедитесь, что вместо дескриптивного имени переменной вместо «этого» или «области». Использование общего имени может ввести в заблуждение, особенно когда вы добавляете больше функций.

+0

Что может быть плохого в том, чтобы заполнить отсутствующий метод в старом браузере? –

+0

@CrazyTrain Расширение не является приватным и отображается в 'for in'. См. [Этот вопрос] (http://stackoverflow.com/questions/1107681/javascript-hiding-prototype-methods-in-for-loop). Одна из главных причин, по которой jQuery предпочитает Prototype. – Luke

+0

Расширения никогда не являются «частными», но да, они могут быть перечислимыми и могут сломать плохо написанный код. Почему кто-то будет использовать 'for-in' на объекте функции вне меня. И когда они делают это на массивах, они просто используют неправильный инструмент. –

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