Правда ли, что в Javascript псевдоним функции работает до тех пор, пока псевдоним функции не касается «this»? - PullRequest
1 голос
/ 06 мая 2010

В Javascript, если мы создаем псевдоним функции (или назначаем «ссылку на функцию» другой переменной), например, в:

f = g;
f = obj.display;
obj.f = foo;

все 3 строки выше, они будут работать до тех пор, пока функция / метод справа не коснется this? Поскольку мы передаем все аргументы, единственный способ, которым он может испортиться, - это когда функция / метод справа использует this?

На самом деле, строка 1, вероятно, в порядке, если g также является свойством window? Если g ссылается на obj.display, то проблема та же.

В строке 2, когда obj.display касается this, это означает obj, но когда вызывается f, this равен window, поэтому они различаются.

В строке 3 то же самое: когда f вызывается внутри кода obj, тогда this равен obj, тогда как foo может использовать this для ссылки на window, если это было свойство window. (глобальная функция).

Строка 2 может быть записана как

f = function() { obj.display.apply(obj, arguments) }

и строка 3:

obj.f = function() { foo.apply(window, arguments) }

Это правильный метод? И есть ли другие способы, кроме этого?

Ответы [ 3 ]

3 голосов
/ 06 мая 2010

В принципе, да, однако, в JavaScript функции являются объектами первого класса, поэтому в действительности это не псевдонимы. То, что вы делаете, это присваиваете значение переменной другой переменной, и в этом случае значение просто оказывается функцией.

Волшебная эта переменная, однако, немного отличается. В JavaScript методы не привязаны к классу или объекту, как в большинстве других языков. Когда вы вызываете метод, this устанавливается оператором точки или apply или , вызывая методы. Это работает так:

var i = 1;
var f = function () { alert(this.i); }
f(); // in a browser, alerts 1, because this will be window if it isn't anything else.

var obj = { i: 10 };
obj.g = f;
obj.g(); // alerts 10, because the dot binds this to obj

var other_obj = { i: 23 };
f.apply(g); // alerts 23, because now apply binds this to other_obj

Вы можете привязать методы к объектам, используя замыкания:

var f = function () { alert(this.i); }
var obj = { i: 10 };

obj.m = function () { f.apply(obj); }
obj.m(); // alerts 10

var g = obj.m;
g(); // alerts 10, because now the closure is called, which binds this correctly.
1 голос
/ 06 мая 2010

«this» будет ссылаться на правильный объект внутри вашей функции, если вы вызываете объект следующим образом:

obj.f();

Это никогда не сработает, поскольку в javascript отсутствует поддержка «связанных функций» (не помнит, к какому объекту принадлежит метод):

var x = context.lineTo;
x(10,10);

lineTo будет сбит с толку, так как «this» теперь указывает на окно или текущий объект функции, а не на ожидаемый контекст. Так что, действительно, вам всегда нужно подавать заявление в вашем случае.

1 голос
/ 06 мая 2010

Значение «this» и областей применения применительно к функциям, особенно обратным вызовам, кажется классическим JavaScript «gotcha».

Dojo имеет метод hitch (), который решает проблему, даваяхороший способ получить ожидаемый контекст для методов обратного вызова.Я полагаю, что не-додзё разработчик мог бы взглянуть на код Dojo hitch (), чтобы позаимствовать идеи.

Эта статья объясняет некоторые аспекты проблемы "this" и способы ее использования.Додзё заминка ().

...