50 JavaScript Questions





Good day, friends!



I bring to your attention a small interactive JavaScript quiz, currently consisting of 50 questions.



In my opinion, solving such problems is the best way to determine your skill level.



Continued here .



Foreword



This part is based on this repository . Its author, Lydia Hallie, positions his project as a list of advanced questions and, indeed, among them there are some that, I think, even an experienced JavaScript developer will find difficult. However, among these questions there are also those for which it is sufficient to have basic knowledge to answer. There is a Russian translation in the repository, but, to put it mildly, it leaves much to be desired, so most of the answers (explanations) had to be translated again.



It should be noted that the explanations (answers) provided do not always fully reveal the essence of the problem. This is due to the form of the project - it is a checklist, not a tutorial. The answers are rather a hint for further searches on MDN orJavascript.ru . However, many of the explanations contain comprehensive answers.



Despite the fact that the code has been tested many times, no one is immune from errors, of course, except for those who do nothing. Therefore, if you find errors, typos, inaccuracies, incorrect wording, etc., as well as if you want to improve the translation, please write in a personal, I will be grateful (activity on GitHub is also encouraged).



Actually, that's all I wanted to say as a preface.



rules



The rules are simple: 50 questions, 3-4 possible answers, rating: number of correct and incorrect answers, progress: number and number of questions.



Based on the results, the percentage of correct answers is determined and a conclusion is made about the level of JavaScript proficiency: more than 80% is excellent, more than 50% is not bad, less than 50% ... well, you understand.



An explanation is attached to each question. If the answer is incorrect, this explanation is disclosed.



Due to the fact that the number of correct and incorrect answers, as well as the serial number of the question, are recorded in the local storage, you have the opportunity to pause, take a break and at any time continue from the place where you left off.



Let's move on from the quiz itself.



Quiz





The project code is here .



We share the results in the comments.



Mechanics



A few words about how the quiz is implemented for those who are interested.



The markup looks like this:



<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>200+   JavaScript</title>
    <!--  -->
    <link href="https://fonts.googleapis.com/css2?family=Ubuntu&display=swap" rel="stylesheet">
    <!--  -->
    <link rel="stylesheet" href="style.css">
    <!--     "" -->
    <script type="module" src="script.js"></script>
</head>
<body></body>


Add minimal styles:



CSS:
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: Ubuntu, sans-serif;
    font-size: 1em;
    text-align: center;
    letter-spacing: 1.05px;
    line-height: 1.5em;
    color: #111;
    user-select: none;
}

@media (max-width: 512px) {
    * {
        font-size: .95em;
    }
}

html {
    position: relative;
}

body {
    padding: 1em;
    min-height: 100vh;
    background: radial-gradient(circle, skyblue, steelblue);
    display: flex;
    flex-direction: column;
    justify-content: start;
    align-items: center;
}

h1 {
    margin: .5em;
    font-size: 1.05em;
}

output {
    margin: .5em;
    display: block;
}

.score {
    font-size: 1.25em;
}

form {
    text-align: left;
}

form p {
    text-align: left;
    white-space: pre;
}

form button {
    position: relative;
    left: 50%;
    transform: translateX(-50%);
}

button {
    margin: 2em 0;
    padding: .4em .8em;
    outline: none;
    border: none;
    background: linear-gradient(lightgreen, darkgreen);
    border-radius: 6px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .4);
    font-size: .95em;
    cursor: pointer;
    transition: .2s;
}

button:hover {
    color: #eee;
}

label {
    cursor: pointer;
}

input {
    margin: 0 10px 0 2em;
    cursor: pointer;
}

details {
    font-size: .95em;
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 90%;
    background: #eee;
    border-radius: 4px;
    cursor: pointer;
}

details h3 {
    margin: .5em;
}

details p {
    margin: .5em 1.5em;
    text-align: justify;
    text-indent: 1.5em;
}

.right {
    color: green;
}

.wrong {
    color: red;
}




Assets are an array of objects, where each object has properties question (question), answers (answers), rightAnswer (correct answer) and explanation (explanation):



[
{
    question: `
        function sayHi() {
            console.log(name);
            console.log(age);
            var name = "Lydia";
            let age = 21;
        }

        sayHi();
    `,
    answers: `
        A: Lydia  undefined
        B: Lydia  ReferenceError
        C: ReferenceError  21
        D: undefined  ReferenceError
    `,
    rightAnswer: `D`,
    explanation: `
              name     var.  ,  name    . Name    undefined   ,       ,     Lydia.     name,      ,    undefined. ,    let ( const),  ,     var,  .      .   "  ".         , JavaScript   ReferenceError.
    `
},
...
]


Main script:



JavaScript
//    - 
import assets from './assets.js'

// IIFE
;((D, B) => {
    //  - 
    const title = D.createElement('h1')
    B.append(title)

    // :     
    const score = D.createElement('output')
    score.className = 'score'
    B.append(score)

    // :   
    const progress = D.createElement('output')
    progress.className = 'progress'
    B.append(progress)

    //   ,       
    const div = D.createElement('div')
    B.append(div)

    //         
    //    0
    let rightAnswers = +localStorage.getItem('rightAnswers') || 0
    let wrongAnswers = +localStorage.getItem('wrongAnswers') || 0

    //      
    //    0
    let i = +localStorage.getItem('i') || 0

    //  
    showQuestion()

    //    
    updateScoreAndProgress()

    function showQuestion() {
        //      
        // ,  ,
        //  
        if (i === assets.length) {
            return showResult()
        }

        // -     -  
        const titleText = {
            4: `   ?`,
            9: ` ?`,
            12: `    `,
            13: `    ?`,
            14: `  ?`,
            20: `  sum?`,
            21: `    cool_secret?`,
            23: `  ?`,
            25: `     :    this`,
            27: `  ?`,
            29: `  ?`,
            30: `   event.target    ?`,
            33: `  ?`,
            34: `    ""?`,
            38: `  JavaScript `,
            39: `  ?`,
            40: `  ?`,
            41: `  setInterval?`,
            42: `  ?`,
            48: `  num?`,
            49: `  ?`
        }
        title.textContent = titleText[i] || `    ?`

        //     -  ,
        //    ,  ,    
        const {
            question,
            rightAnswer,
            explanation
        } = assets[i]

        //    -  input type="radio",
        //      (    - \n)
        //     -  ,
        //      slice(1, -1),
        //   
        const answers = assets[i].answers
            .split('\n')
            .slice(1, -1)
            .map(i => i.trim())

        // HTML-
        const template = `
        <form action="#">
            <p><em>:</em><br> ${question}</p>

            <p><em> :</em></p><br>
            ${answers.reduce((html, item) => html += `<label><input type="radio" name="answer" value="${item}">${item}</label><br>`, '')}

            <button type="submit"></button>
        </form>
        <details>
            <summary>  </summary>
            <section>
                <h3> : ${rightAnswer}</h3>
                <p>${explanation}</p>
            </section>
        </details>`

        //    
        div.innerHTML = template

        //  
        const form = div.querySelector('form')

        //   
        form.querySelector('input').setAttribute('checked', '')

        //   
        form.addEventListener('submit', ev => {
            //   
            ev.preventDefault()

            //    
            const chosenAnswer = form.querySelector('input:checked').value.substr(0, 1)

            //  
            checkAnswer(chosenAnswer, rightAnswer)
        })
    }

    function checkAnswer(chosenAnswer, rightAnswer) {
        //   
        let isRight = true

        //      ,
        //    ,
        //       ,
        //     ,
        //       
        //    false
        if (chosenAnswer === rightAnswer) {
            rightAnswers++
            localStorage.setItem('rightAnswers', rightAnswers)
        } else {
            wrongAnswers++
            localStorage.setItem('wrongAnswers', wrongAnswers)
            isRight = false
        }

        //  
        const button = div.querySelector('button')

        //    
        if (isRight) {
            //   
            title.innerHTML = `<h1 class="right">!</h1>`

            //  
            button.disabled = true

            //    
            //        
            //  
            const timer = setTimeout(() => {
                updateScoreAndProgress()
                showQuestion()
                clearTimeout(timer)
            }, 1000)

            //    
        } else {
            //   
            title.innerHTML = `<h1 class="wrong">!</h1>`

            //  
            div.querySelectorAll('input').forEach(input => input.disabled = true)

            //  
            div.querySelector('details').setAttribute('open', '')

            //   
            button.textContent = ''

            //      
            //        
            //  
            button.addEventListener('click', () => {
                updateScoreAndProgress()
                showQuestion()
            }, {
                once: true
            })
        }

        //   
        i++

        //      
        localStorage.setItem('i', i)
    }

    function updateScoreAndProgress() {
        //  
        score.innerHTML = `<span class="right">${rightAnswers}</span> - <span class="wrong">${wrongAnswers}</span>`

        //  
        progress.innerHTML = `${i + 1} / ${assets.length}`
    }

    function showResult() {
        //    
        const percent = (rightAnswers / assets.length * 100).toFixed()

        //    
        let result

        //      
        //  result  
        if (percent >= 80) {
            result = ` !    JavaScript.`
        } else if (percent > 50) {
            result = ` ,     .`
        } else {
            result = `,     JavaScript.`
        }

        //  
        B.innerHTML = `
        <h1> </h1>
        <div>
            <p> : <span class="right">${rightAnswers}</span></p>
            <p> : <span class="wrong">${wrongAnswers}</span></p>
            <p>  : ${percent}</p>
            <p>${result}</p>
            <button></button>
        </div>
        `

        //    
        //  
        //   ,
        //  
        B.querySelector('button').addEventListener('click', () => {
            localStorage.clear()
            location.reload()
        }, {
            once: true
        })
    }
})(document, document.body)




Thank you for attention.



All Articles