кто я - JQuery, плагин, $ this, $ (this), this, доступ к переменной - PullRequest
0 голосов
/ 30 декабря 2010

У меня проблема с определением объекта, который выполняет функцию

<div id="test1">lorem</div>
<div id="test2">ipsum</div>

<script type="text/javascript">
    $(document).ready(function() {
        $('#test1').plugin(); //alert: I am test1
        $('#test2').plugin(); //alert: I am test2

        $('#test1').plugin.fun(); //alert: I am undefined and I am undefined
        $('#test2').plugin.fun(); //alert: I am undefined and I am undefined
    });
    (function($) {
        $.fn.plugin = function() {
            $this = $(this);
            alert('I am '+$(this).attr('id'));//<-- it works
        }
        $.fn.plugin.fun = function() {
            alert('I am '+$(this).attr('id')); //<-- doesn't work!
            alert('and I am '+$this.attr('id')); //<-- also doesn't work!
        }
    })(jQuery);
</script>

Ответы [ 2 ]

5 голосов
/ 30 декабря 2010

Чтобы понять, что делает $('#test1').plugin.fun();, нам нужно посмотреть, как this устанавливается в функциях JavaScript. Мы начнем с теории, а затем вернемся к вашему плагину.

В JavaScript this полностью определяется как как функция вызывается . Наиболее распространенный способ - установить его как побочный продукт вызова функции из свойства объекта:

var foo = {
    msg: "I'm foo!",
    bar: function() {
        alert(this.msg);
    }
};
foo.bar(); // alerts "I'm foo!"

Эта строка foo.bar(); делает три разные вещи:

  1. Извлекает свойство bar из объекта foo.
  2. Вызывает функцию, на которую ссылается свойство.
  3. Это # 2 таким образом, что this относится к foo.

(Подробнее здесь: Мифические методы .)

Так в звонилке

$('#test1').plugin.fun();

... this в пределах fun будет plugin, потому что мы вызываем fun через свойство plugin.

Вы можете рассмотреть возможность использования mechanims, используемого в jQuery UI, который должен иметь «методы» плагина, доступные через функцию main, с именами в виде строк. Например, в экземпляре jQuery UI Draggable вы можете вызывать такие методы:

$('#test1').draggable('disable');

См. Их Draggable документацию для большего количества примеров, но в основном ваши вызовы будут выглядеть так:

$('#test1').plugin('fun');

Подробнее о вызовах функций:

Существует еще один способ установки this при вызове функции: через функции call и apply в экземпляре функции:

var f = function() {
    alert(this.msg);
};
var foo = {
    msg: "I'm foo!"
};
f.call(foo);  // alerts "I'm foo!"
f.apply(foo); // alerts "I'm foo!" too

call и apply вызывают функцию, устанавливая значение this для первого аргумента, который вы передаете им. Разница между call и apply заключается в том, как вы передаете аргументы целевой функции. С call вы просто добавляете дополнительные аргументы в функцию call; с apply вы передаете массив аргументов в качестве второго аргумента apply. Примеры:

function f(arg1, arg2) {
    alert(this.msg + " (" + arg1 + ", " + arg2 + ")");
}
var foo = {
    msg: "I'm foo!";
};
f.call(foo, "one", "two");    // Alerts "I'm foo! (one, two)"
//          ^-- "one" and "two" are discrete arguments
f.apply(foo, ["one", "two"]); // Alerts the same thing
//           ^------------^-- "one" and "two" are in an array
1 голос
/ 30 декабря 2010

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

Когда вы используете $('#test1').plugin, вы получаете ссылку на эту функцию, и из этого вы получаете доступ к функции fun, но вы получаете просто обычную функцию.С тем же успехом вы можете использовать $.fn.plugin.fun, чтобы добраться до функции, использование объекта jQuery с селектором вообще не имеет никакого значения, если вы получили ссылку на функцию fun.объект на самом деле будет отброшен до вызова функции fun, поэтому его невозможно получить из функции.

...