Задать вопрос
  • И снова this в javascript?

    @BlackSSA Автор вопроса
    Ребята, всем-всем огромное спасибо! По-моему, после 1000-го раза прочтения Ильи Кантора и перепиской с форумчанами понял! Под "контекстом вызова" понимается простой вызов метода! Я, ошибочно, отождествлял контекст со scope! А оказалось все проще). Напишу для таких-же, как я(если они существуют и основным направлением является что-то типа C# ;)), javascript-кодерам лучше не читать ))) :
    В javascript "контекст вызова" = экземпляру класса, в котором вызван метод. Т.к. глобальный инстанс в web javascript = window, то все функции (в javascript функции и методы - ЭТО РАЗНЫЕ ВЕЩИ!!! Вернее, по мне, так js-"функции" - это те-же методы объекта window, но в документации они разделяются) вызываются под ним. Т.е., если в коде есть:
    function foo()//учел правильную критику Дениса Ишенина с наименованиями
    {
        console.log(this);
    }

    то это равнозначно в шарпе:
    class Window{
    public ... Foo(...)
    }

    и соответственно вызов в js в любом месте кода
    ...
    foo();
    ...

    хоть внутри метода, хоть в внутри другой функции, хоть "в корне" кода - "контекстом вызова"(инстансом по нашему в C#) будет естественно Window. При этом, как ни странно, не важно, где определять функцию! В js ее (именно функцию, а не метод!!!) можно определить даже внутри метода! И она все-равно будет инстансом Window! Ну вот например:
    var foo = {
        someFunc: function(){
            ...
            function innerFunction(){
                console.log(this);
            }
            innerFunction();
        }
    }

    угадайте, что выведет innerFunction? Правильно, "Window"!
    Но есть несколько "но"(как-же без них )):
    1) Если написать "use strict" вначале кода или этой функции, то будет совсем не Window, а undefine
    2) В js метод одного инстанса(1) можно вызвать в другом инстансе(2)(соответственно этот вызов будет видеть переменные этого самого другого инстанса(2)) с помощью bind и т.д.. Мне сложно провести аналогию с C#.
    3) Пока не разобрался с "потерей контекста", но, думаю, завтра на свежую голову, с пониманием, что такое "контекст вызова" - разберусь.
    4) Есть еще "стрелочные функции", но с ними, как ни странно у меня проблем не возникло. )
    P.S. прав был дяденька Декарт, когда сказал, что половину споров на земле не существовало бы, если бы люди знали смысл слов, о которых они спорят ))) Наконец-то я для себя понял(надеюсь, что правильно), как это работает! Два года писал код "как надо", и вот сегодня отважился задать вопрос и благодаря ответам наконец-то разобрался "почему". Еще раз всем огромное спасибо!
    P.P.S. Коллега подсказал, что еще проще понять(и я с ним согласен), если везде, где нет точки при объявлении/вызове функции мысленно писать Window. Т.е., вместо
    function foo()
    {
        console.log(this);
    }

    в голове сразу строится конструкция
    function Window.foo()//учел правильную критику Дениса Ишенина с наименованиями
    {
        console.log(this);
    }
    ,
    а вместо
    var foo = {
        someFunc: function(){
            ...
            function innerFunction(){
                console.log(this);
            }
            innerFunction();
        }
    }

    строится
    var foo = {
        someFunc: function(){
            ...
            function Window.innerFunction(){
                Window.console.log(this);
            }
            Window.innerFunction();
        }
    }

    и тогда инстанс, он-же "контекст вызова" - очевиден ;).
    Еще, kova1ev подсказал в коментах первого ответа про потерю контекста. Рекомендую его ответ, мне он помог!
    Ответ написан
    1 комментарий