Is JavaScript Learning Progress Normal After 20-25 Hours?
Assess if your JavaScript learning progress and OOP approach is typical after 20-25 hours with Python background. Code review, fixes, roadmap, and tips for beginners tackling JavaScript OOP challenges.
Is my JavaScript learning progress and approach normal after 20-25 hours of study (with 30 hours of prior Python experience)?
Learning Approach:
- Choose a topic from the roadmap.
- Read articles on the topic; ask AI for unclear parts.
- After studying several topics, generate a task using a neural network and solve it.
Current Challenge: Solving an OOP problem for an online school management prototype (code below). Am I progressing at a typical rate?
const prompt = require('prompt-sync')();
//variable block
let arrAllId=[];
begin=true;
dumpsterCourse={};
dumpsterTeacher={};
//function block
function pause(){
return prompt('Press Enter to continue ...');
}
function generateId(length = 5) {
const alphabetId='0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM';
let resultId='';
for(let i=0;i<length;i++){
resultId+=alphabetId[Math.floor(Math.random()*alphabetId.length)];
}
if (arrAllId.indexOf(resultId)==-1){
arrAllId.push(resultId);
return resultId;
}
return generateId();
}
function checkingValidateEmail(){
let email=prompt('Enter your email: ');
if (email.includes('@')){
return email;
}
else{
console.log('Email was entered incorrectly\n');
return checkingValidateEmail();
}
}
function checkingValidateCode(code){
if (code.lengh>10){
console.log('You have successfully added a Secret Code');
return(code);
}
else{
return checkingValidateCode(prompt('Enter secret code: '));
}
}
function checkingNameUniqueness(){
let name=prompt('Enter your name: ');
if (app.allUserNames.indexOf(name)==-1){
return name;
}
else{
console.log('This name is taken\n');
return checkingNameUniqueness();
}
}
function showFirstInterface(){
console.log(
'\n1. Log in to account\n',
'\n2. Registration\n',
'\n3. Exit\n\n',
);
return prompt('Choose an action: ');
}
function showStudentInterface(){
console.log(
'\n1. Find a course\n',
'\n2. Support\n',
'\n3. Log out of account\n\n',
);
return prompt('Choose an action: ');
}
function sentMessageAdmin(mess,sender){
app.baseAdmin[sender]=mess;
let keys=Object.keys(app.admins);
for(let i=0;i<app.admins.length;i++)
app.admins[keys[i]]=mess;
}
function userType(){
let type=prompt('1. Teacher\n2. Student\n3. School Owner\n4. Application Owner\nChoose login role: ');
switch(type){
case '1':
return 'teachers';
case '2':
return 'students';
case '3':
return 'schoolManager';
case '4':
return 'admin';
default:
console.log('No such role');
pause();
return userType();
}
}
function inputAccountStudorTeach(userType){
let userName=prompt('Enter username: ');
let userPass=prompt('Enter your password: ');
if (prompt('Enter yes if you want to go back: ')=='yes'){
return 'no';
}
if(app[userType][userName]!==undefined){
if(app[userType][userName].pass==userPass){
console.log(`Welcome ${userName} `);
pause();
return app[userType][userName];
}
}
else{
console.log('You entered an incorrect username or password\n');
return inputAccount(userType);
}
}
function checkingValidatePass(){
let pass=prompt('Enter password: ');
if (pass.length>=8){
return pass;
}
else{
console.log('Minimum password length is 8 characters\n');
return checkingValidatePass();
}
}
//class block
class User{
constructor(userType,name,email,pass){
this.pass=pass;
this.name = name;
this.email = email;
this.userType=userType;
this.createdAt = new Date();
this.isAcive=true;
this.id=generateId();
}
getInfo() {
return `${this.name} (${this.email}) - ${this.role} (account created ${createdAt})`;
}
}
class Student extends User{
constructor(name,email,pass){
super('student',name,email,pass);
this.balance=0;
this.learnCourses=[];
this.sentComplaint={};
}
getInfo(){
return super.getInfo()+`|| Balance: ${this.balance}`;
}
addCourse(onlineSchoolName,nameCourse){
if (this.balance>=app[onlineSchoolName][nameCourse].price){
this.balance-=app[onlineSchoolName][nameCourse].price;
app[onlineSchoolName][nameCourse].students[this.name]=app.students[this.name];
console.log('You have successfully enrolled in the course');
pause();
}
else{
console.log('You do not have enough funds');
pause();
}
}
addComplaintForTeacher(nameTeacher,description){
if(this.sentComplaint[nameTeacher]!==undefined){
return 'You have already sent a complaint about this teacher';
}
else{
this.sentComplaint[nameTeacher]=true;
app.teachers[nameTeacher].complaint.push(this.name+': '+description,'complaint');
if (app.teachers[nameTeacher].complaint.length>=10 & app.baseAdmin.message[nameTeacher]!==undefined & app.baseAdmin.viewedMessage[nameTeacher]!==undefined){
for(let i=0;i<10;i++){
sentMessageAdmin(app.teachers[nameTeacher][i]);
}
}
return 'Complaint successfully sent for administrative review';
}
}
}
class Teacher extends User{
constructor(name,email,pass,specialty){
super('teacher',name,email,pass);
this.specialty=specialty;
this.rating=0;
this.complaint=[];
}
changeSpecialty(){
console.log(`Your current specialty:\n${this.specialty}`);
this.specialty=prompt('Enter new specialty:\n');
}
getInfo(){
return super.getInfo()+`|| Rating ${this.rating}/5`;
}
}
class Admin{
constructor(){
this.message={};
}
deleteTeacher(name){
}
}
class Course{
constructor(nameCourse,price,description,duration,id){
this.id=id;
this.nameCourse=nameCourse;
this.price=Number(price);
this.description=description;
this.duration=Number(duration);
this.students={};
this.teacher=null;
}
changeDescription(){
console.log(`Current description:\n${this.description}`);
this.description=prompt('Enter new description:\n');
}
changePrice(){
console.log(`Current description: ${this.price}`);
this.priсe=Number(prompt('Enter new price: '));
}
}
class OnlineSchool{
static CourselastId=0;
constructor(name){
this.name=name;
this.teachers=[];
this.students=[];
this.courses=[];
}
createCurse(nameCourse){
CourselastId+=1;
let price=Number(prompt('Enter course price: '));
let description=prompt('Enter description for the course:\n');
let duration=Number(prompt('Enter course duration in number of lessons: '));
this.courses[nameCourse]=new Course(nameCourse,price,description,duration,CourselastId);
}
getStatistics(){
let rate=0;
for (let i =0;i<this.teachers.length;i++){
rate+=this.teachers[i];
}
rate=rate/this.teachers.length;
return `Average teacher rating ${rate} || Number of students enrolled in your school's courses ${this.students.length}`;
}
}
//object where all data will be stored
let app={
baseAdmin:{dewkins:{name: 'dewkins',
pass: '42',//for quick code tests
email: '42', //for quick code tests
message: {},
createSecretCodes(){
app.secretCodes.push(checkingValidateCode(prompt('Enter secret code: ')));
},
}},
admins: {},
teachers: {},
students: {},
onlineSchools: {},
allUserNames:[],
secretCodes:[],
registerTeacher(){
let name=checkingNameUniqueness();
let email=checkingValidateEmail();
let specialty=prompt('Enter your specialty: ');
this.teachers[name]=new Teacher(name,email,pass,specialty);
this.allUserNames.push(name);
},
registerStudent(){
let name=checkingNameUniqueness();
let email=checkingValidateEmail();
let pass=checkingValidatePass();
this.students[name]=new Student(name,email,pass);
},
};
//executable code block
while(begin===true){
switch(showFirstInterface()){
case '1':
let type=userType();
if (type==='teachers' || type==='students'){
let userObj=inputAccountStudorTeach(type);
}
if(userObj==='no'){
continue;
}
break;
case '2':
break;
case '3':
begin=false;
break;
default:
console.log('No such action');
pause();
break;
}
switch(userObj.userType){
case 'student':
showStudentInterface();
break;
case 'teacher':
break;
case 'schoolManager':
break;
case 'admin':
break;
}
}
//cd C:\Users\dewkinz\documents
//node prototype.js
Your javascript обучение / изучение javascript progress is normal: with ~30 hours of prior Python and 20–25 hours of focused JavaScript you’re in the early, productive stage where syntax slips and OOP confusion (prototype vs class, this, small typos) are expected. Your roadmap (pick a topic → read → ask → generate tasks) is sensible — tighten it with focused debugging, small refactors, and unit tests to solidify oop javascript concepts. With steady practice (6–10 hours/week) you can move from this stage to comfortable intermediate OOP and cleaner code in roughly 1–3 months.
Contents
- Is this progress typical? (short answer + evidence)
- Quick code review — what your code reveals
- Practical fixes and a concise refactor (OOP JavaScript)
- Roadmap & realistic timeline for изучение javascript
- How to accelerate learning and get unstuck
- Sources
- Conclusion
Is this progress typical? (short answer + evidence)
Yes — totally typical. Given 30 hours of prior Python, you’ve already internalized programming basics (variables, control flow, functions), so your first 20–25 hours of JavaScript naturally land on syntax, standard library differences, and a few paradigm shifts: prototype-based inheritance, this binding, and the loosely typed nature of JS. Short surveys and learning guides show similar timelines: basic syntax and small projects often appear after a few dozen hours, while intermediate fluency (DOM + async + OOP comfort) commonly takes months of steady practice (freeCodeCamp timeline, Codecademy guidance, GeeksforGeeks estimations).
What to expect next? You’ll hit a stretch where you understand small programs but run into brittle code when you try larger designs (like your school prototype). That’s the signal to slow down and focus: debug systematically, fix one class or function at a time, and add small tests. For concrete OOP mechanics in JS (prototypes vs classes), read the MDN guide on working with objects — it explains the core differences clearly: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_objects.
Quick code review — what your code reveals
Your code shows good instincts (classes, modular idea, data object app) but contains a mix of common beginner problems: typos, inconsistent naming, mixing arrays and objects, and control-flow/variable-scope errors. Fixing those will make the program run and teach you a lot.
Key problems I found (with why and a quick fix):
- Typos in property names and methods
- Problem:
this.isAcivevs intendedisActive;createdAtused withoutthis;this.roleused though constructor setsuserType. - Fix: standardize to
this.isActive,this.createdAt, and usethis.userTypeeverywhere. - Wrong property access / undefined variables
- Problem:
getInfo()uses${this.role}andcreatedAt(undefined). - Fix: return
${this.name} (${this.email}) - ${this.userType} (created ${this.createdAt.toLocaleString()}). - Wrong function/variable names and recursion bugs
- Problem:
checkingValidateCodecheckscode.lengh(typo) and recursion may mis-handle user input.inputAccountStudorTeachcallsinputAccount(userType)(nonexistent). - Fix: use
code.length, and correct recursive calls to the right function names. - Inconsistent singular/plural keys (storage vs userType)
- Problem:
userType()returns'teachers'but your User constructor sets'teacher'as role; app stores users underapp.teachersetc. - Fix: pick a convention (e.g., userType string
'teacher'and store inapp.teachers[name]) and map safely:const store = app[ userType + 's' ]or return singular keys fromuserType(). - Misused data structures (arrays vs objects)
- Problem:
this.teachers = []then laterthis.teachers[name] = ...— mixing array indexing and object maps. - Fix: use
{}(object) when you want name → object mapping, and[]for ordered lists. - Class/static usage errors
- Problem:
OnlineSchoolusesstatic CourselastId=0butcreateCurse()just doesCourselastId += 1(missing class reference). - Fix: use
OnlineSchool.courseLastId += 1(and consistent naming likecourseLastId). - Logical & operator mistakes
- Problem: code uses bitwise
&instead of logical&&in conditions. - Fix: use
&&for boolean logic. - Admin / messaging logic is fragile
- Problem:
sentMessageAdminandapp.baseAdminstructure are inconsistent — methods inside nested objects, iteratingapp.admins.lengthwhenapp.adminsis an object. - Fix: restructure admin store as an object with consistent message API and iterate
Object.keys(...). - Spelling/character issues
- Problem:
this.priсe— sometimes a non-ASCII character sneaks in (e.g., a Cyrillicс) causing hard-to-find bugs. - Fix: linting (ESLint) catches strange identifiers; run linting early.
Want the most impactful fixes first? Fix the naming/typo errors and the flow that reads userObj outside its scope. That will often get your program to run so you can iterate.
Useful references for OOP details and patterns: MDN on objects (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_objects) and the O’Reilly chapter on JS design patterns (https://www.oreilly.com/library/view/learning-javascript-design/9781491904261/ch01.html).
Practical fixes and a concise refactor (OOP JavaScript)
Below are compact corrections you can paste into your file to fix the most common runtime and logic errors. These aren’t a full rewrite, but they show consistent naming, safe storage, and corrected methods.
- Fix User + Student + Teacher basics
class User {
constructor(userType, name, email, pass) {
this.pass = pass;
this.name = name;
this.email = email;
this.userType = userType; // 'student' | 'teacher' | ...
this.createdAt = new Date();
this.isActive = true;
this.id = generateId();
}
getInfo() {
return `${this.name} (${this.email}) - ${this.userType} (created ${this.createdAt.toLocaleString()})`;
}
}
class Student extends User {
constructor(name, email, pass) {
super('student', name, email, pass);
this.balance = 0;
this.learnCourses = {}; // map courseName -> Course
this.sentComplaint = {};
}
getInfo() {
return `${super.getInfo()} || Balance: ${this.balance}`;
}
}
- Fix OnlineSchool static id and course storage
class OnlineSchool {
static courseLastId = 0;
constructor(name) {
this.name = name;
this.teachers = {}; // map name -> Teacher
this.students = {};
this.courses = {}; // map courseName -> Course
}
createCourse(courseName) {
OnlineSchool.courseLastId += 1;
const id = OnlineSchool.courseLastId;
const price = Number(prompt('Enter course price: '));
const description = prompt('Enter description for the course:\n');
const duration = Number(prompt('Enter course duration (lessons): '));
this.courses[courseName] = new Course(courseName, price, description, duration, id);
}
}
- Correct a small utility and validation
function checkingValidateCode(code) {
if (code && code.length > 10) {
console.log('You have successfully added a Secret Code');
return code;
}
const next = prompt('Enter secret code: ');
return checkingValidateCode(next);
}
function checkingValidateEmail() {
let email = prompt('Enter your email: ');
if (/.+@.+..+/.test(email)) return email;
console.log('Email was entered incorrectly\n');
return checkingValidateEmail();
}
Other practical steps:
- Install ESLint and run it to detect typos and unused vars.
- Turn mixed arrays/objects into consistent maps or lists.
- Avoid deep recursion for user prompts when testing — that can mask other bugs.
- Add console logs at function entry/exit while debugging to follow flow.
Roadmap & realistic timeline for изучение javascript (with your Python background)
Short, evidence-based timeline (assuming 6–10 hours/week, focused deliberate practice):
- 0–4 weeks (you): strengthen syntax + small programs. Fix typos, learn console debugging, get comfortable with objects, arrays, and functions. (You’re in this phase now.) See quick estimates: basic syntax in weeks to months (Educative note).
- 1–3 months: OOP in JS,
this, prototypes, ES6 classes, closures, async basics (Promises / async-await). Build a playable prototype (your school manager) and iterate. - 3–6+ months: DOM, full-stack practice, frameworks if wanted (React/Vue), design patterns, and production practices (testing, linting, build tools). Guides: freeCodeCamp, Codecademy, GeeksforGeeks.
Concrete weekly plan (sample)
- Week A: 6 sessions — small algorithms, arrays/objects, 3 tiny functions, 2 bug hunts in your project.
- Week B: Focus OOP — write 3 class-based mini-modules (User, Course, School), test them in Node.
- Week C: Async + I/O — read about Promises, build a fetch-or-simulate-API exercise.
- Week D: Integrate — connect classes with a simple CLI or tiny UI and practice refactoring.
Small wins: fix one bug per day, refactor one function, and write 1-2 unit tests per week.
How to accelerate learning and get unstuck (practical habits)
- Debug surgically: reproduce the bug in a minimal snippet. If your prototype fails, extract the failing class into a tiny file and run it in Node. That isolates causes fast.
- Get faster feedback: run code often. Short edit → run cycles teach more than long reading sessions.
- Use linting & static checks: ESLint catches typos and inconsistent naming early.
- Read canonical docs: MDN for language parts (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_objects), and a patterns chapter (https://www.oreilly.com/library/view/learning-javascript-design/9781491904261/ch01.html) for architecture.
- Use targeted practice: do OOP katas (class design, inheritance, composition), then turn them into tiny features in your app.
- Ask AI effectively: include minimal reproducible code, describe expected vs actual behavior, and paste exact error messages. Use AI to get hints, then implement and test locally.
- Peer review / pair programming: someone else scanning your code finds naming inconsistencies quickly.
- Build tests: even simple assertion checks for
UserandCoursebehaviors prevent regressions. - Prefer iterative refactors: small, tested changes beat big rewrites.
If you want a focused exercise right now: take the User / Student / Teacher classes, extract them into a separate file, and write three assertions: creating a student sets userType === 'student', id is defined and unique after three creations, and getInfo() returns a readable string. That single exercise covers constructors, methods, and your ID generator.
Sources
- https://www.freecodecamp.org/news/how-long-does-it-take-to-learn-javascript/
- https://www.codecademy.com/resources/blog/how-long-to-learn-javascript/
- https://www.geeksforgeeks.org/how-long-does-it-take-to-learn-javascript/
- https://www.w3schools.com/js/js_oop_intro.asp
- https://www.educative.io/answers/how-long-does-it-take-to-learn-javascript
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_objects
- https://www.oreilly.com/library/view/learning-javascript-design/9781491904261/ch01.html
Conclusion
Your javascript обучение and изучение javascript progress is on track. Hitting OOP confusion and tiny runtime bugs after 20–25 hours (with 30 hours of Python before that) is normal — actually a healthy signal that you’re pushing into the right, harder territory. Keep doing short read → implement → debug cycles, apply the concrete fixes above, and follow the weekly roadmap: consistent practice plus deliberate debugging will convert your current effort into reliable oop javascript skills within a few weeks to a few months.