Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Вопрос по классам и слову this (https://javascript.ru/forum/misc/81018-vopros-po-klassam-i-slovu.html)

igogo333 15.09.2020 13:42

Вопрос по классам и слову this
 
Здравствуйте!
Есть такой класс:
class C1 {
     f1() { console.log("f1"); }
     f2() { console.log("f2"); this.f1(); }
     f3() { console.log("f3"); c1.f1(); }
}
let c1 = new C1();


Вопрос: надо ли использовать всегда this.f1(); или можно всегда использовать c1.f1() ?

Дело в том, что иногда функция f2 вызывается в таком контексте, что this ссылается просто в никуда. А вот f3 вызывается в любом контексте нормально.

voraa 15.09.2020 16:51

Цитата:

Сообщение от igogo333
Вопрос: надо ли использовать всегда this.f1(); или можно всегда использовать c1.f1() ?

Функции (методы класса) вызываются с членом класса.
После c1 = new C1() разумеется надо вызывать c1.f1()
this указывает на текущий член класса внутри методов этого класса.
Если Вы вызвали c1.f2(), то внутри f2 this будет ссылаться на c1.
Внутри метода класса обратиться к текущему члену класса (с которым был вызван метод можно только через this.

Цитата:

Сообщение от igogo333
Дело в том, что иногда функция f2 вызывается в таком контексте, что this ссылается просто в никуда

Это как? Приведите пример. this может ссылаться только на член класса с которым вызван метод f2
Цитата:

Сообщение от igogo333
А вот f3 вызывается в любом контексте нормально.

Это совсем не нормально
А если вы строку 6 переделаете
let c2 = new C1();
Что будет обозначать c1 в методе f3?

igogo333 15.09.2020 18:56

Спасибо за ответ!

Цитата:

Это как? Приведите пример. this может ссылаться только на член класса с которым вызван метод f2
например, вот:

class C1 {

 f1() { console.log(this); console.log("f1"); }

 authInfo(response) {
    if (response.session) {
	if (response.session.user) {
            var user = response.session.user;
        }
    }
    this.f1(); // не работает
    c1.f1(); // работает
 }
}
let c1 = new C1();
VK.Auth.getLoginStatus(c1.authInfo);


здесь или контекст this не передается, если вызывать VK.Auth.getLoginStatus(c1.authInfo);
или аргумент response не передается, если вызывать VK.Auth.getLoginStatus(c1.authInfo());


Цитата:

Это совсем не нормально
А если вы строку 6 переделаете
let c2 = new C1();
Что будет обозначать c1 в методе f3?
Да, это проблема. Но все-таки вопрос: проблема только в потенциальной угрозе переименования?
А если предположить, что имя класса всегда будет одним и тем же, то других проблем нет с тем чтобы использовать всегда имя класса вместо this?
Или там еще какие-то могут вылезти проблемы?

voraa 15.09.2020 19:44

А зачем authInfo делать методом какого то класса?
Методы класса нужны, что бы как то работать с объектами членами класса.
Я так понимаю, что в VK.Auth.getLoginStatus нужно передать какую то функцию, но эта функция никак не связана ни с каким объектом
Если так уж нужно, что бы она как-то имела доступ с какому то объекту, да еще через this то можно так

class C1 {
 
 f1() { console.log(this); console.log("f1"); }
 

}

 authInfo(response) {
    if (response.session) {
    if (response.session.user) {
            var user = response.session.user;
        }
    }
    this.f1(); // работает
    // c1.f1(); // - не нужно
 }

let c1 = new C1();
VK.Auth.getLoginStatus(authInfo.bind(c1));

let c2 = new C1();
VK.Auth.getLoginStatus(authInfo.bind(c2));


Если очень хочется, привязать ее к классу (ну, кажется, что код яснее, понятнее, красивее)
то можно так

class C1 {
 
 f1() { console.log(this); console.log("f1"); }
 
  static authInfo(response) {
    if (response.session) {
    if (response.session.user) {
            var user = response.session.user;
        }
    }
    this.f1(); // будет работать
    // c1.f1(); // не нужно
 }
}
let c1 = new C1();
VK.Auth.getLoginStatus(C1.authInfo.bind(c1));


без bind тут трудно обойтись, т.к. внутри VK.Auth.getLoginStatus переданная функция вызывается без привязки к какому либо объекту.

igogo333 15.09.2020 21:07

Круто. Спасибо!

А еще иногда this не определяется в функциях обратного вызова.

И все-таки вопрос:
Можно ли внутри класса C1 всегда использовать имя класса c1 вместо this?
Проблема только в потенциальной угрозе переименования c2 = new C1() ?
Или там еще какие-то могут вылезти проблемы?

voraa 15.09.2020 21:24

Цитата:

Сообщение от igogo333
А еще иногда this не определяется в функциях обратного вызова.

Это зависит от того, откуда делается обратный вызов. Везде могут быть разные соглашения. Обратный вызов - это просто вызов функции. Но в некоторых случаях АПИ дополнительно передает какой-то объект через this. this в js никак изначально не связан с классами.
Цитата:

Сообщение от igogo333
Можно ли внутри класса C1 всегда использовать имя класса c1 вместо this?

js хорош тем, что в нем много чего можно. Вопрос - зачем.
Если вы используете классы, то это как бы подразумевает, что вы используете концепцию объектно-ориентированного программирования.
Ну так и надо ей следовать. Но совсем не обязательно напяливать классы на то, на что они плохо напяливаются. Особенно там, где приходится использовать различные АПИ, которые по сути не являются объектно ориентированными. Или хитрить различными bind, apply и проч. Для этого их и придумали в js

voraa 15.09.2020 21:31

Цитата:

Сообщение от igogo333
Проблема только в потенциальной угрозе переименования c2 = new C1() ?

А вы предполагаете, что у вас будет только с1?
А зачем тогда класс? Класс чаще всего нужен что бы порождать различные объекты - члены этого класса.

igogo333 16.09.2020 05:16

Понял. Большое спасибо!


Часовой пояс GMT +3, время: 01:21.