Требуется помощь
Я новичек в программировании под 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, время: 03:24. |