Вызов функции из массива javascript
У меня есть такой код:
var foo = {
x: 2,
bar: function() {
alert(this.x);
}
};
Почему foo.bar()
предупреждает 2
, а [foo.bar][0]()
предупреждает undefined
?
4 ответа:
Итак, технически
[foo.bar][0]
эквивалентноfoo.bar
, но в момент вызова функцияbar
потеряла "лексическую привязку" с объектомfoo
, поэтому при вызове ее JavaScript фактически выполняет следующее:foo.bar.call([foo.bar]);
В общем случае это выражение:
XXX.yyy(args)
Интерпретируется как:
XXX.yyy.call(XXX, args);
в этом случае
XXX
- это[foo.bar]
, а.yyy
- это[0]
.Чтобы исправить это, вам нужно явно связать
foo
еще раз:[foo.bar][0].call(foo);
Когда вы это сделаете
[foo.bar][0]()
,this
вbar
находится[foo.bar]
, массив, но не объектfoo
.Просто представьте, что имя метода-это число
0
(хотя это неверный синтаксис).([foo.bar]).0(); // you see, `this` became the array object: [foo.bar]
И
[foo.bar].x
естьundefined
.
Это потому, что вы вызываете функцию на объекте массива. Ключевое слово "this"равно массиву.
[foo.bar][0]();
В javascript контекст, в котором вызывается функция, может меняться. Ключевое слово "this" может иметь различные значения в зависимости от того, как оно было вызвано. Если функция вызывается на объекте (включая массивы), язык сделает "this" равным объекту, на который она была вызвана. С другой стороны, вы можете сохранить функцию другого объекта в другую переменную и вызвать оно. Как вы сделали с этим:
var test=[foo.bar][0]; test();`//here is alert "2"
И контекст будет окном.
Исследований и методов в JavaScript. Это откроет вам глаза на то, насколько гибким является ключевое слово "this". Это место большой путаницы среди многих программистов, пришедших из других языков, но как только этот принцип понят, от него исходит много силы. JQuery, например, использует "call" и "apply" для вызова обратных вызовов событий в контексте элемента, который событие было расстреляно.