Каков контекст анонимной функции?

У меня есть такой код:

function demo() {
    this.val=5;
    function() {
        this.val=7;
    }();
}

Теперь, когда я запускаю этот код в консоли Firefox или Chrome, он выдает синтаксическую ошибку. Я не понимаю, почему это ошибка, потому что я читал, что функции javascript являются объектами, поэтому, когда я вызываю анонимную функцию, внутри нее this указывает на демонстрацию функции и должен изменить val на 7, поэтому, если я это сделаю

var x=new demo();
x.val;   //should give 7

но когда я делаю это

function demo() {
    this.val=5;
    var f=function() {
            this.val=7;
    }();
}
window.val;    // gives 7

Я не понимаю, если функции являются объектами, то почему this в анонимной функции указывает на window, а не на demo. Пожалуйста, объясните это.


person lovesh    schedule 22.07.2011    source источник
comment
Именно так это работает. Если вы вызываете функцию в обычном режиме, ключевое слово this будет указывать на глобальный объект...   -  person Šime Vidas    schedule 23.07.2011
comment
@Šime Vidas, что здесь обычно? а функции не объекты?   -  person lovesh    schedule 23.07.2011
comment
обычно = путем добавления скобок к имени функции, например: foo(). Другие способы вызова функции: (1) как конструктор и (2) через call/apply. В этих случаях правила для ключевого слова this отличаются. Да, функции - это объекты.   -  person Šime Vidas    schedule 23.07.2011


Ответы (2)


я не понимаю почему это ошибка

потому что

function() {
    this.val=7;
}();

оценивается как объявление функции, а для объявлений функций требуется имя. Чтобы оно интерпретировалось как функциональное выражение, вам нужно поместить его в круглые скобки:

 (function() {
    this.val=7;
 }());

(что делает его непосредственной функцией)

или присвоить функцию переменной:

var f = function() {....};
f();

То, что вы делаете во втором фрагменте, представляет собой смесь того и другого, и хотя это действительно так, это не имеет особого смысла. f будет иметь значение undefined.

я не понимаю, если функции являются объектами, то почему this в анонимной функции указывает на window, а не на demo.

Функции не наследуют контекст, в котором они вызываются. Каждая функция имеет свой собственный this, и то, на что ссылается this, определяется как вызывается функция. В основном это сводится к:


Дальнейшее чтение:

person Felix Kling    schedule 22.07.2011
comment
Я могу ошибаться, но я думаю, что ваши скобки немного не совпадают с (function() { this.val=7; }());, разве () не стоит после закрывающего )? - person James Montagne; 23.07.2011
comment
@ Феликс Клинг, на что указывает this функции? можете пожалуйста уточнить? - person lovesh; 23.07.2011
comment
@kingjiv: На самом деле это не имеет значения. Но JSLint предпочитает вызывающую скобку внутри. - person Felix Kling; 23.07.2011
comment
@lovesh: я думал, что предоставил достаточно информации. Как я уже сказал, это зависит от того, как вызывается функция. Что непонятно? - person Felix Kling; 23.07.2011
comment
Хорошо знать. Думаю, я просто предположил, что обычно видел это таким образом. - person James Montagne; 23.07.2011

Вы можете сделать то, что вы описали, следующим образом:

function demo() {
    var self=this;

    this.val = 5;

    var f = (function() {
        self.val = 7;
    })();
}
person James Montagne    schedule 22.07.2011
comment
я понимаю, что если я хочу изменить значение, я могу это сделать, но вся моя проблема в том, что если функции являются объектами, то почему this не указывает на функцию, в моем случае (demo) - person lovesh; 23.07.2011
comment
@king Этот код вводит в заблуждение. Внутренняя функция представляет собой IIFE, поэтому значение, которое присваивается переменной f, равно undefined, а не самому функциональному объекту. IIFE должны быть заключены в скобки. - person Šime Vidas; 23.07.2011
comment
Это просто объект, определенный внутри этой функции, на самом деле это не часть объекта, который вы создаете при вызове new demo(). Если бы вы изменили его на this.f = function(), а затем вызвали бы this.f(), он был бы вызван с this в качестве объекта. - person James Montagne; 23.07.2011
comment
@lovesh Почему тот факт, что функции являются объектами, приводит к выводу, что this указывает на сами функции? Эти две вещи никак не связаны... - person Šime Vidas; 23.07.2011
comment
@Šime, честно говоря, я всегда оборачиваю его, но только что взял из его кода. Я думаю, что все равно неправильно понял его непонимание, поэтому я не думаю, что это полезно в любом случае. - person James Montagne; 23.07.2011
comment
@love Ну, это не так. Как вы думаете, почему так должно быть? - person Šime Vidas; 23.07.2011
comment
@Šime Vidas, извините, я ошибся. наверное, я должен разбиться сейчас, это был долгий день, и я веду себя глупо - person lovesh; 23.07.2011
comment
@love Ну, если ты в Индии, то тебе точно пора спать (так как у тебя дома 4 утра) :). - person Šime Vidas; 23.07.2011