📌 How to use
- Go to script.google.com → New project.
- Paste this entire script into
Code.js. - Run
buildJavaScriptQuizForm()once and authorize. - Check the Logs for the edit URL and live URL of the new quiz.
/**
* Builds a 100-question JavaScript multiple-choice quiz as a Google Form.
*/
function buildJavaScriptQuizForm() {
const formTitle = 'JavaScript 100-Question Quiz';
const form = FormApp.create(formTitle)
.setDescription('100-question JavaScript multiple-choice quiz with explanations.')
.setIsQuiz(true);
const QUESTIONS = [
{
question: 'What does typeof 42 return?',
choices: ['"int"', '"number"', '"integer"', '"numeric"'],
correctIndex: 1,
explanation: 'In JavaScript, all numeric values (integers and floats) have the type "number".'
},
{
question: 'What is the result of typeof null?',
choices: ['"null"', '"undefined"', '"object"', '"value"'],
correctIndex: 2,
explanation: 'typeof null returns "object" because of a long-standing historical quirk in JavaScript.'
},
{
question: 'What will console.log(1 + "2") output?',
choices: ['3', '"3"', '"12"', 'NaN'],
correctIndex: 2,
explanation: 'When adding a number and a string, JavaScript coerces the number to a string and concatenates, giving "12".'
},
{
question: 'What does NaN stand for?',
choices: ['Not a Null', 'Not a Number', 'Negative a Number', 'No actual Number'],
correctIndex: 1,
explanation: 'NaN is the special numeric value that represents an invalid number result, such as 0 / 0.'
},
{
question: 'Which of these is NOT a primitive type in JavaScript?',
choices: ['string', 'boolean', 'object', 'symbol'],
correctIndex: 2,
explanation: 'object is not a primitive. Primitive types include string, number, boolean, null, undefined, symbol, and bigint.'
},
{
question: 'What will typeof undefined return?',
choices: ['"null"', '"undefined"', '"object"', '"void"'],
correctIndex: 1,
explanation: 'The primitive value undefined has the type "undefined".'
},
{
question: 'Which operator is used for strict equality comparison?',
choices: ['==', '=', '===', '=>'],
correctIndex: 2,
explanation: '=== compares both value and type with no type coercion.'
},
{
question: 'What is the result of "5" == 5?',
choices: ['true', 'false', 'NaN', 'Throws an error'],
correctIndex: 0,
explanation: '== performs type coercion, converting "5" to number 5, so the comparison is true.'
},
{
question: 'What is the result of "5" === 5?',
choices: ['true', 'false', 'NaN', 'Throws an error'],
correctIndex: 1,
explanation: '=== requires both type and value to be the same; string "5" is not equal to number 5.'
},
{
question: 'Which keyword declares a block-scoped variable?',
choices: ['var', 'let', 'const', 'Both let and const'],
correctIndex: 3,
explanation: 'Both let and const are block scoped, while var is function scoped.'
},
{
question: 'What happens if you access a variable declared with let before its declaration?',
choices: ['Returns undefined', 'Throws a ReferenceError', 'Returns null', 'Returns an empty string'],
correctIndex: 1,
explanation: 'let and const are in the temporal dead zone before declaration and cause a ReferenceError if accessed.'
},
{
question: 'What will this code log: console.log(a); var a = 10;',
choices: ['10', 'undefined', 'null', 'ReferenceError'],
correctIndex: 1,
explanation: 'var declarations are hoisted and initialized with undefined, so the log shows undefined.'
},
{
question: 'What will this code log: console.log(b); let b = 10;',
choices: ['10', 'undefined', 'null', 'ReferenceError'],
correctIndex: 3,
explanation: 'Accessing a let variable before declaration produces a ReferenceError due to the temporal dead zone.'
},
{
question: 'What is a closure?',
choices: [
'A way to close open files',
'A function bundled with its lexical environment',
'A function that always returns another function',
'A method to end a program'
],
correctIndex: 1,
explanation: 'A closure is when a function retains access to variables from its outer scope even after that scope has finished.'
},
{
question: 'Which array method adds one or more elements to the end of an array?',
choices: ['push()', 'pop()', 'shift()', 'unshift()'],
correctIndex: 0,
explanation: 'push() appends elements to the end of an array.'
},
{
question: 'Which array method creates a new array without modifying the original?',
choices: ['push()', 'splice()', 'slice()', 'pop()'],
correctIndex: 2,
explanation: 'slice() returns a new array containing a selected portion, leaving the original unchanged.'
},
{
question: 'What is the result of [1, 2, 3].length?',
choices: ['2', '3', '4', 'undefined'],
correctIndex: 1,
explanation: 'The length property of an array is the number of elements, which is 3 here.'
},
{
question: 'Which method converts a JSON string into an object?',
choices: ['JSON.encode()', 'JSON.parse()', 'JSON.stringify()', 'JSON.toObject()'],
correctIndex: 1,
explanation: 'JSON.parse() converts a JSON string into a JavaScript object.'
},
{
question: 'What is the output of console.log(0 == false)?',
choices: ['true', 'false', 'NaN', 'Throws error'],
correctIndex: 0,
explanation: '== coerces false to 0, so 0 == false is true.'
},
{
question: 'What is the output of console.log(0 === false)?',
choices: ['true', 'false', 'NaN', 'Throws error'],
correctIndex: 1,
explanation: '0 (number) and false (boolean) are different types, so === returns false.'
},
{
question: 'How do you write an arrow function that returns the square of x?',
choices: ['x => { x * x }', 'x => x * x', '(x) => return x * x', 'x -> x * x'],
correctIndex: 1,
explanation: 'For single-expression arrow functions, you can omit braces and return: x => x * x.'
},
{
question: 'What will console.log(typeof (() => {})) output?',
choices: ['"function"', '"object"', '"arrow"', '"undefined"'],
correctIndex: 0,
explanation: 'Arrow functions are still functions in JavaScript, so typeof returns "function".'
},
{
question: 'What does Array.isArray(value) do?',
choices: [
'Checks if value is iterable',
'Checks if value is an array',
'Checks if value is an object',
'Converts value to an array'
],
correctIndex: 1,
explanation: 'Array.isArray() returns true only when the value is an array.'
},
{
question: 'What is the value of Number("hello")?',
choices: ['"hello"', 'NaN', '0', 'undefined'],
correctIndex: 1,
explanation: 'Converting a non-numeric string to a number yields NaN.'
},
{
question: 'Which of these is falsy?',
choices: ['"0"', '[]', '{}', '""'],
correctIndex: 3,
explanation: 'The empty string "" is falsy. "0", [], and {} are truthy.'
},
{
question: 'Which keyword stops a loop immediately?',
choices: ['exit', 'stop', 'break', 'return'],
correctIndex: 2,
explanation: 'break exits the nearest loop or switch statement.'
},
{
question: 'Which keyword skips the current iteration of a loop and continues with the next?',
choices: ['skip', 'next', 'continue', 'pass'],
correctIndex: 2,
explanation: 'continue ends the current iteration and proceeds with the next one.'
},
{
question: 'What is the result of console.log("5" - 2)?',
choices: ['"52"', '3', 'NaN', '"3"'],
correctIndex: 1,
explanation: 'The - operator coerces strings to numbers, so "5" - 2 becomes 5 - 2, which is 3.'
},
{
question: 'What is the result of console.log("5" + 2)?',
choices: ['"52"', '7', 'NaN', '"7"'],
correctIndex: 0,
explanation: 'The + operator with a string performs concatenation, giving "52".'
},
{
question: 'In a browser, what is window?',
choices: [
'A built-in array',
'The global object for browser JavaScript',
'A reserved name for DOM nodes',
'A CSS object'
],
correctIndex: 1,
explanation: 'In browsers, the global scope is represented by the window object.'
},
{
question: 'In strict mode, what happens if you assign to an undeclared variable?',
choices: [
'It creates a global variable',
'It creates a local variable',
'It throws a ReferenceError',
'It is silently ignored'
],
correctIndex: 2,
explanation: 'Strict mode prevents implicit globals and throws a ReferenceError instead.'
},
{
question: 'How do you enable strict mode in a script file?',
choices: [
'enable strict;',
'"use strict"; at the top',
'use strict; without quotes',
'strict_mode(true);'
],
correctIndex: 1,
explanation: 'The directive "use strict"; at the top of a file or function enables strict mode.'
},
{
question: 'What is the output of console.log([] == false)?',
choices: ['true', 'false', 'NaN', 'Throws error'],
correctIndex: 0,
explanation: '[] is coerced to "" then to 0, false is also coerced to 0, so == returns true.'
},
{
question: 'What is the value of typeof NaN?',
choices: ['"nan"', '"number"', '"undefined"', '"object"'],
correctIndex: 1,
explanation: 'NaN is a special numeric value, so typeof NaN is "number".'
},
{
question: 'How do you check if a value is NaN without coercion?',
choices: [
'value == NaN',
'value === NaN',
'isNaN(value)',
'Number.isNaN(value)'
],
correctIndex: 3,
explanation: 'Number.isNaN(value) checks specifically for NaN and does not coerce the argument.'
},
{
question: 'What is the result of console.log([] + [])?',
choices: ['[]', '""', '"[]"', 'NaN'],
correctIndex: 1,
explanation: 'Arrays are converted to strings; [].toString() is "", so "" + "" is an empty string.'
},
{
question: 'What does Array.prototype.map() return?',
choices: ['A new array', 'The modified original array', 'A number', 'An object with keys and values'],
correctIndex: 0,
explanation: 'map() returns a new array of transformed elements and does not mutate the original array.'
},
{
question: 'Which method is best for selecting elements that meet a condition?',
choices: ['forEach()', 'map()', 'filter()', 'reduce()'],
correctIndex: 2,
explanation: 'filter() returns a new array containing only elements for which the callback returns true.'
},
{
question: 'What does Array.prototype.forEach() return?',
choices: ['A new array', 'The original array', 'undefined', 'The number of iterations'],
correctIndex: 2,
explanation: 'forEach() is used for side effects and always returns undefined.'
},
{
question: 'What does Array.prototype.reduce() typically do?',
choices: [
'Sorts an array',
'Flattens nested arrays only',
'Reduces an array to a single value',
'Filters elements'
],
correctIndex: 2,
explanation: 'reduce() combines elements using an accumulator to produce a single output value.'
},
{
question: 'Which operator spreads the elements of an iterable?',
choices: ['...', '*', '&', '=>'],
correctIndex: 0,
explanation: 'The spread syntax ... expands elements of an iterable in array literals, function calls, and so on.'
},
{
question: 'What is destructuring in JavaScript?',
choices: [
'Removing properties from objects',
'Assigning properties or elements from objects or arrays into variables',
'Deleting variables',
'Breaking a loop'
],
correctIndex: 1,
explanation: 'Destructuring lets you extract values from arrays or objects into variables with compact syntax.'
},
{
question: 'Which is valid array destructuring?',
choices: [
'let {a, b} = [1, 2];',
'let [a, b] = [1, 2];',
'let (a, b) = [1, 2];',
'let [a: 1, b: 2];'
],
correctIndex: 1,
explanation: 'Array destructuring uses square brackets, for example let [a, b] = [1, 2];'
},
{
question: 'Which is valid object destructuring?',
choices: [
'let [name] = { name: "Max" };',
'let {name} = { name: "Max" };',
'let (name) = { name: "Max" };',
'let {name: "Max"};'
],
correctIndex: 1,
explanation: 'Object destructuring uses curly braces with property names, for example let {name} = obj;'
},
{
question: 'In non strict mode, what is the default value of this inside a regular function call fn() in a browser?',
choices: ['undefined', 'The global object (window)', 'The function itself', 'null'],
correctIndex: 1,
explanation: 'In non strict mode, this in a plain function call refers to the global object (window in browsers).'
},
{
question: 'In an arrow function, this is:',
choices: [
'Dynamically bound',
'Always window',
'Lexically inherited from the surrounding scope',
'Always undefined'
],
correctIndex: 2,
explanation: 'Arrow functions do not have their own this; they capture this from the enclosing scope.'
},
{
question: 'How do you create a new object using a constructor function Person?',
choices: ['Person()', 'new Person()', 'create Person()', 'Object(Person)'],
correctIndex: 1,
explanation: 'The new keyword creates a new object and calls the constructor Person with this bound to that object.'
},
{
question: 'Which prototype is used when calling a method on an array literal like []?',
choices: ['Object.prototype', 'Array.prototype', 'Function.prototype', 'Prototype.prototype'],
correctIndex: 1,
explanation: 'Arrays inherit methods such as push and map from Array.prototype.'
},
{
question: 'What does Object.create(proto) do?',
choices: [
'Copies all properties deeply from proto',
'Creates an object whose internal prototype is proto',
'Clones proto and adds new methods',
'Creates a new class from proto'
],
correctIndex: 1,
explanation: 'Object.create(proto) returns a new object whose [[Prototype]] is proto.'
},
{
question: 'How do you define a class in modern JavaScript?',
choices: [
'class Person {}',
'function class Person {}',
'Person class {}',
'new class Person {}'
],
correctIndex: 0,
explanation: 'ES6 introduced the class syntax: class Person {}.'
},
{
question: 'How do you define a method inside a class?',
choices: [
'methodName: function() {}',
'function methodName() {}',
'methodName() {}',
'let methodName() {}'
],
correctIndex: 2,
explanation: 'Inside a class body, methods are defined as methodName() { } without the function keyword.'
},
{
question: 'How do you create a subclass from a class Parent?',
choices: [
'class Child: Parent {}',
'class Child extends Parent {}',
'class Child inherits Parent {}',
'class Child Parent {}'
],
correctIndex: 1,
explanation: 'Child extends Parent is the ES6 syntax for class inheritance.'
},
{
question: 'Which keyword calls the parent class constructor?',
choices: ['this()', 'parent()', 'base()', 'super()'],
correctIndex: 3,
explanation: 'super() calls the constructor of the parent class from within a subclass.'
},
{
question: 'What does typeof function() {} return?',
choices: ['"object"', '"function"', '"callable"', '"method"'],
correctIndex: 1,
explanation: 'Regular functions have type "function" when evaluated with typeof.'
},
{
question: 'Which statement about promises is true?',
choices: [
'A promise can be pending, fulfilled, or rejected',
'A promise can only be fulfilled',
'Promises block the main thread',
'Promises replace all callbacks completely'
],
correctIndex: 0,
explanation: 'Promises have three main states: pending, fulfilled, and rejected.'
},
{
question: 'What does Promise.resolve(5) create?',
choices: [
'A rejected promise with value 5',
'A fulfilled promise with value 5',
'A pending promise with value 5',
'A synchronous value 5 only'
],
correctIndex: 1,
explanation: 'Promise.resolve(5) returns a promise that is immediately fulfilled with value 5.'
},
{
question: 'How do you attach a success handler to a promise p?',
choices: ['p.then(onFulfilled)', 'p.success(onFulfilled)', 'p.done(onFulfilled)', 'p.resolve(onFulfilled)'],
correctIndex: 0,
explanation: 'then registers callbacks for fulfilled and optionally rejected states.'
},
{
question: 'How do you handle errors in a promise chain?',
choices: ['With try/catch only', 'With .catch()', 'With .error()', 'With .fail()'],
correctIndex: 1,
explanation: 'catch handles rejected promises and errors thrown in previous then handlers.'
},
{
question: 'Which keyword is used to declare an asynchronous function?',
choices: ['sync', 'await', 'async', 'defer'],
correctIndex: 2,
explanation: 'Prefixing a function with async makes it return a promise and allows await inside it.'
},
{
question: 'What does await do inside an async function?',
choices: [
'Pauses the whole program',
'Pauses only that async function until the promise settles',
'Converts a promise to a callback',
'Makes the function synchronous'
],
correctIndex: 1,
explanation: 'await suspends the async function until the awaited promise resolves or rejects, without blocking the event loop.'
},
{
question: 'What happens if an error is thrown inside an async function?',
choices: [
'It crashes the browser',
'It becomes a rejected promise',
'It is ignored',
'It becomes a fulfilled promise'
],
correctIndex: 1,
explanation: 'Errors thrown in async functions reject the returned promise, which can be caught with catch or try/catch around await.'
},
{
question: 'What does setTimeout(fn, 0) do?',
choices: [
'Executes fn immediately',
'Schedules fn after the current call stack clears',
'Blocks execution until fn completes',
'Throws an error'
],
correctIndex: 1,
explanation: 'setTimeout with 0 ms delays fn until after the current stack and microtasks complete.'
},
{
question: 'Which of these is NOT part of the JavaScript language itself but provided by the browser?',
choices: ['Array', 'Promise', 'document', 'Object'],
correctIndex: 2,
explanation: 'document is part of the DOM API, which is provided by browsers, not the core JS language.'
},
{
question: 'How do you select an element with id "main" in the DOM?',
choices: [
'document.getElement("main")',
'document.getElementById("main")',
'document.query("#main")',
'document.id("main")'
],
correctIndex: 1,
explanation: 'getElementById selects the element whose id matches the given string.'
},
{
question: 'Which method selects the first element matching a CSS selector?',
choices: [
'document.querySelector()',
'document.querySelectorAll()[0] only',
'document.getElementBySelector()',
'document.selectFirst()'
],
correctIndex: 0,
explanation: 'querySelector returns the first matching element or null.'
},
{
question: 'How do you add a click event listener to a button element btn?',
choices: [
'btn.on("click", fn)',
'btn.click(fn)',
'btn.addEventListener("click", fn)',
'btn.addClick(fn)'
],
correctIndex: 2,
explanation: 'addEventListener is the standard way to attach event listeners to DOM elements.'
},
{
question: 'What will document.querySelectorAll(".item") return?',
choices: ['A single element', 'An array', 'A NodeList', 'A string'],
correctIndex: 2,
explanation: 'querySelectorAll returns a NodeList, which is an array-like collection of elements.'
},
{
question: 'Which property changes the text inside an element?',
choices: ['innerText', 'text', 'content', 'valueText'],
correctIndex: 0,
explanation: 'innerText (or textContent) is used to set or get the text inside an element.'
},
{
question: 'How do you prevent a form default submit behavior in an event handler?',
choices: ['event.stop()', 'event.preventDefault()', 'event.cancel()', 'event.stopPropagation()'],
correctIndex: 1,
explanation: 'preventDefault stops the default browser action such as submitting a form.'
},
{
question: 'What does event.stopPropagation() do?',
choices: [
'Prevents default browser behavior',
'Stops the event from bubbling up to parent elements',
'Disables all event listeners',
'Cancels form submission only'
],
correctIndex: 1,
explanation: 'stopPropagation prevents the event from propagating to ancestor elements in the DOM.'
},
{
question: 'What is hoisting?',
choices: [
'Moving files to the top of a project',
'JavaScript moving declarations to the top of their scope before execution',
'Sorting variables alphabetically',
'Loading external scripts earlier'
],
correctIndex: 1,
explanation: 'Hoisting is the behavior where declarations appear to be moved to the top of their scope.'
},
{
question: 'Which are hoisted with their full definitions?',
choices: [
'Function declarations',
'Function expressions',
'Arrow functions assigned to variables',
'Both function expressions and arrow functions'
],
correctIndex: 0,
explanation: 'Function declarations are hoisted entirely; function expressions and arrow functions are hoisted as variables only.'
},
{
question: 'What is the output of console.log(hoisted()); function hoisted() { return "Hello"; }',
choices: ['"Hello"', 'undefined', 'Error', 'null'],
correctIndex: 0,
explanation: 'The function declaration hoisted is fully hoisted, so calling it before its definition works and returns "Hello".'
},
{
question: 'What is the output of console.log(x); let x = 5;',
choices: ['5', 'undefined', 'null', 'ReferenceError'],
correctIndex: 3,
explanation: 'Accessing a let variable before declaration triggers a ReferenceError due to the temporal dead zone.'
},
{
question: 'Which method checks if an array includes a certain value?',
choices: ['arr.contains(value)', 'arr.has(value)', 'arr.includes(value)', 'arr.exists(value)'],
correctIndex: 2,
explanation: 'includes returns true if the array contains the specified value.'
},
{
question: 'Which statement about const is true?',
choices: [
'const variables cannot be reassigned or mutated at all',
'const prevents reassigning the binding but object contents can still change',
'const makes values deeply immutable',
'const is function scoped'
],
correctIndex: 1,
explanation: 'const prevents rebinding the variable, but if it refers to an object or array, its contents can still be mutated.'
},
{
question: 'What is the output of const obj = { a: 1 }; obj.a = 2; console.log(obj.a);',
choices: ['1', '2', 'Error', 'undefined'],
correctIndex: 1,
explanation: 'The reference obj is constant but the object is mutable, so its a property can change to 2.'
},
{
question: 'What is a template literal?',
choices: [
'A precompiled string',
'A string defined with backticks that can include expressions with ${ }',
'A JSON template',
'A string used only for HTML'
],
correctIndex: 1,
explanation: 'Template literals use backticks and support interpolation with ${expression} and multiline strings.'
},
{
question: 'Which is a valid template literal?',
choices: [
'"Hello ${name}"',
'\'Hello ${name}\'',
'`Hello ${name}`',
'Hello ${name}'
],
correctIndex: 2,
explanation: 'Interpolation works inside backtick strings only, so `Hello ${name}` is the valid template literal.'
},
{
question: 'How do you export a named function in ES modules?',
choices: [
'module.export function myFunc() {}',
'export function myFunc() {}',
'exports.myFunc = function() {} in browser modules',
'export: myFunc()'
],
correctIndex: 1,
explanation: 'Named exports use the export keyword before declarations, for example export function myFunc() {}.'
},
{
question: 'How do you import a named function myFunc from ./utils.js?',
choices: [
'import { myFunc } from "./utils.js";',
'require("./utils.js").myFunc; in browser modules',
'import myFunc from "./utils.js"; only',
'include myFunc from "./utils.js";'
],
correctIndex: 0,
explanation: 'Named imports use curly braces: import { myFunc } from "./utils.js";'
},
{
question: 'What is the default export import syntax?',
choices: [
'import { default } from "./mod.js";',
'import * as default from "./mod.js";',
'import something from "./mod.js";',
'import default("./mod.js");'
],
correctIndex: 2,
explanation: 'import something from "./mod.js"; imports the module default export as something.'
},
{
question: 'Which tool checks whether a property exists directly on an object (not its prototype chain)?',
choices: [
'in operator',
'obj.hasOwnProperty("prop")',
'obj.propertyExists("prop")',
'Object.exists(obj, "prop")'
],
correctIndex: 1,
explanation: 'hasOwnProperty checks only own properties of the object, not inherited ones.'
},
{
question: 'What is the result of const a = { x: 1 }; const b = a; b.x = 2; console.log(a.x);',
choices: ['1', '2', 'undefined', 'Error'],
correctIndex: 1,
explanation: 'a and b refer to the same object, so changing b.x also changes a.x.'
},
{
question: 'How do you make a shallow copy of an object obj?',
choices: [
'const copy = obj;',
'const copy = Object.copy(obj);',
'const copy = { ...obj };',
'const copy = new obj();'
],
correctIndex: 2,
explanation: 'The spread operator { ...obj } copies own enumerable properties into a new object (shallow copy).'
},
{
question: 'What is event delegation?',
choices: [
'Assigning one event to multiple elements at once',
'Attaching a single event listener to a parent element to handle events from its children',
'Delegating events from browser to server',
'Combining multiple events into one'
],
correctIndex: 1,
explanation: 'Event delegation uses event bubbling so a single listener on a parent can handle events from many child elements.'
},
{
question: 'Which built-in data structure maintains insertion order and uses key value pairs with keys of any type?',
choices: ['Object', 'Map', 'Set', 'Array'],
correctIndex: 1,
explanation: 'Map allows keys of any type and preserves insertion order.'
},
{
question: 'Which structure holds unique values only (no duplicates)?',
choices: ['Array', 'Map', 'Set', 'Object'],
correctIndex: 2,
explanation: 'Set stores unique values; adding the same value again has no effect.'
},
{
question: 'What does "use strict" mainly help with?',
choices: [
'Faster network requests',
'Cleaner syntax highlighting',
'Catching common mistakes and unsafe actions',
'Making code run in parallel'
],
correctIndex: 2,
explanation: 'Strict mode throws errors for unsafe actions such as implicit globals and disallows some problematic behavior.'
},
{
question: 'What does Symbol() create?',
choices: [
'A unique immutable value usable as an object key',
'A string alias',
'A new numeric data type',
'A private variable that cannot be accessed'
],
correctIndex: 0,
explanation: 'Symbols are unique, immutable primitives often used as object property keys.'
},
{
question: 'What is the main difference between == and ===?',
choices: [
'=== compares only types',
'== compares only values',
'=== compares value and type without coercion',
'They are identical'
],
correctIndex: 2,
explanation: '=== performs strict equality (no coercion) while == allows type coercion.'
},
{
question: 'What does Object.freeze(obj) do?',
choices: [
'Prevents adding, removing, or changing properties of obj',
'Prevents only adding new properties',
'Prevents only deleting properties',
'Makes deep immutable copies of nested objects'
],
correctIndex: 0,
explanation: 'A frozen object cannot have its existing properties changed, added, or removed (shallow freeze).'
},
{
question: 'What is the output of console.log(typeof [].constructor)?',
choices: ['"array"', '"object"', '"function"', '"constructor"'],
correctIndex: 2,
explanation: '[].constructor is Array, which is a function, so typeof returns "function".'
},
{
question: 'What does Object.keys(obj) return?',
choices: [
'All values of obj',
'An array of obj own enumerable property names',
'Prototype chain keys',
'A Map of key value entries'
],
correctIndex: 1,
explanation: 'Object.keys returns an array of own enumerable property names.'
},
{
question: 'What is the main difference between for...in and for...of?',
choices: [
'for...in iterates values; for...of keys',
'for...in iterates keys; for...of iterates values of iterables',
'They are identical',
'for...of only works on plain objects'
],
correctIndex: 1,
explanation: 'for...in loops over enumerable property names, while for...of iterates values of iterables like arrays and strings.'
},
{
question: 'What will console.log("2" * "3") log?',
choices: ['"23"', '6', 'NaN', '"6"'],
correctIndex: 1,
explanation: 'The * operator coerces both strings to numbers, so "2" * "3" becomes 2 * 3 which is 6.'
},
{
question: 'What is the output of console.log(Boolean("false"))?',
choices: ['true', 'false', 'NaN', 'Error'],
correctIndex: 0,
explanation: 'Any non empty string is truthy, so Boolean("false") is true.'
},
{
question: 'What is function currying?',
choices: [
'Combining two functions into one',
'Transforming a multi argument function into a series of functions each taking one argument',
'Removing parameters from a function',
'Overriding built in functions'
],
correctIndex: 1,
explanation: 'Currying transforms a function f(a, b, c) into f(a)(b)(c), enabling partial application.'
},
{
question: 'What is the main purpose of JavaScript in web development?',
choices: [
'Styling web pages',
'Structuring content',
'Adding interactivity and dynamic behavior',
'Serving web pages from the server'
],
correctIndex: 2,
explanation: 'HTML structures content, CSS styles it, and JavaScript adds logic, interactivity, and dynamic behavior.'
}
];
QUESTIONS.forEach(function(q, index) {
const item = form.addMultipleChoiceItem();
item.setTitle((index + 1) + '. ' + q.question)
.setPoints(1);
const choices = q.choices.map(function(choice, i) {
return item.createChoice(choice, i === q.correctIndex);
});
item.setChoices(choices);
const correctFb = FormApp.createFeedback()
.setText('Correct! ' + q.explanation)
.build();
const incorrectFb = FormApp.createFeedback()
.setText('Not quite. ' + q.explanation)
.build();
item.setFeedbackForCorrect(correctFb);
item.setFeedbackForIncorrect(incorrectFb);
});
Logger.log('Edit URL: ' + form.getEditUrl());
Logger.log('Live URL: ' + form.getPublishedUrl());
}