Вызов функции из массива 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 is [foo.bar] массив, а не объект foo.

просто представьте, что имя метода-это число 0 (хотя это неправильный синтаксис).

([foo.bar]).0(); // you see, `this` became the array object: [foo.bar]

и [foo.bar].x is undefined.


потому что вы вызываете функцию для объекта массива. Ключевое слово "this"равно массиву.

[foo.bar][0](); 

в javascript контекст, в котором вызывается функция, может отличаться. Ключевое слово "this" может иметь разные значения в зависимости от того, как оно было вызвано. Если функция вызывается на объекте (включая массивы), язык сделает "это" равным объекту, на который он был вызван. С другой стороны, вы можете сохранить функцию другого объекта в другую переменную и призвать его. Как вы сделали с этим:

var test=[foo.bar][0];
test();`//here is alert "2" 

и контекст будет окно.

исследуйте вызов и применяйте методы в javascript. Это откроет вам глаза на то, насколько гибким является ключевое слово "this". Это место большой путаницы среди многих программистов, происходящих из других языков, но как только этот принцип понят, из него исходит много силы. Например, JQuery использует "call" и "apply" для обратного вызова событий, вызываемых в контекст элемента, на который было запущено событие.


это потому, что когда вы делаете [foo.bar] массив, который вы изолируете от основного объекта (foo), и в своей функции вы предупреждаете this.x и во вновь созданном объекте [foo.bar] this неопределено