Требуется помощь
Я новичек в программировании под JS. До этого в основном писал на С под микроконтроллеры, и не сразу получается все понять.
Собственно вопрос вот в чем. Приведу абстрактный код который у меня не работает как надо. Это часть скрипта который загружается в браузере.
//*1
function a()
{
let selectCallback=1;
let gFileList;
a.prototype=
{
setSelectCallback: function(value)
{
selectCallback=value;
}
}
//некоторый код который загружает ресурсы с диска используя промисы
getFilesAndFoldersList(gCurentPath).then((res)=>
{
gFileList=res;
},
function(err)
{
let b=err;
});
}
//*2
window.addEventListener("load",function() {
let b=new a();
b.setSelectCallback(function(a)
{
//do something
let c=a;
});
});
Собственно вопрос в том, что при первом вызове из "*2" в отладчике показывает что у переменной b в прототипе нет метода setSelectсallback. При втором вызове он есть, но когда используется внутри функции a значение selectCallback остается равно 1. Собственно почему? если я проходя по отладке вижу, что значение переменной seleckCallback в функции a меняется на нужный мне обработчик, но когда я пытаюсь использовать значение переменной изнутри функции оно всегда равно 1. Сильно не пинайте. Возможно я в принципе неправильно все это пытаюсь сделать, но кучу интернета перерыл ответа на вопрос не нашел. |
Цитата:
JavaScript - интерпретируемый ЯП. Цитата:
Попробуйте так:
function someClass() {
this.selectCallback = 1;
if (!this.gFileList && window.gCurentPath) {
this.__loadFileList(gCurentPath);
}
};
someClass.prototype.gFileList = null;
someClass.prototype.__loadFileList = function (directoryPath) {
if (!directoryPath) {
return Promise.reject();
}
return getFilesAndFoldersList(directoryPath).then(res => {
this.gFileList = res;
});
};
someClass.prototype.setSelectCallback = function (value) {
this.selectCallback = value;
};
window.addEventListener('load', function () {
var someClassInstance = new someClass();
someClassInstance.setSelectCallback(function (a) {
// do something
let c = a;
});
});
P.S. от прямого изменения прототипа можно избавиться с помощью синтаксического сахара добавленного в ES6, т.е. объявить класс с помощью ключ. слова «class». |
Попробовал возникли следующие вопросы:
1. Это общепринятая практика не менять proto функции в ее вызове? 2. Как всегда проблема с this. Он не указывает на someClass. Я хочу использовать переменную selectCallback в обработчике нажатия кнопок, и соответственно this указывает на window а не на someClass. Что делать с этим? bind? Ну и напоследок, все это я ковыряю на KaiOS (основан на FirefoxOS движок Gecko 48), хотя не думаю, что это имеет принципиальное значение. С class у меня не сложилось, если правильно помню, там не получается создавать переменные для экземпляра класса. |
Цитата:
Цитата:
|
Цитата:
Цитата:
Скорее всего Вы пытаетесь забить гвоздь отверткой. Цитата:
|
2 Nexus
1. Это незачем. Просто привычка от C. В вызванной функции делается все, что должно быть сделано, а не кусок кода который загружен в память, нигде не вызывается, но выполняется). 2. Да смысла нет выкладывать весь говнокод. Я просто тренируюсь. После вашей рекомендации вынести proto вне функции с ним все стало нормально, после первого вызова есть нужный метод. this привязал через bind. 3. пробовал писать так:
class a
{
let b=1;
c()
{
alarm(b);
}
}
на let b=1; затык, синтаксическая ошибка, и так и не нашел, как сделать переменную для класса которая была бы доступна всем функциям внутри класса (ну как в c++). А используя функции это возможно. |
rexton, вы можете объявить все нужные переменные при инициализации класса, например ваш пример выше... Синтаксис ES2020
{
class A {
b = 1;
c() {
alarm(this.b);
}
}
function alarm(message) {
alert("⚠️ " + message);
}
const a = new A();
a.c();
}
Если вы хотите использовать более старую спецификацию, то...
{
class A {
constructor() {
this.b = 1;
}
c() {
alarm(this.b);
}
}
function alarm(message) {
alert("⚠️ " + message);
}
const a = new A();
a.c();
}
Цитата:
class A {
constructor() {
let a = 1;
this.a = 2;
}
}
то это тоже самое, что...
function A() {
// if(!new.target) throw new TypeError("Class constructor cannot be invoked without 'new'");
let a = 1;
this.a = 2;
}
Отличие в том, что объявление класса при помощи функции-конструктора требует ручной проверки (если практически необходимо; в примере выше закомментировано) на то, что этот конструктор не будет вызываться как функция, а скорей только как конструктор. (А синтаксис класса предполагает такую проверку автоматически) |
| Часовой пояс GMT +3, время: 08:58. |