jsPsych / Behavioral experimentsRead · predict · build · inspect

A compact programming bridge

Allow 30-45 minutes. Read code aloud, predict the result, then try it in the browser Console. These exercises are ungraded. If most concepts are new, complete the foundation route with the instructor.

Files and the browser

index.html loads libraries and your script. app.js contains experiment logic. stimuli.js contains item information. A path is relative to the HTML page for these examples; capital letters matter on many servers. Saving a file changes the disk; refreshing reruns it. Refreshing also clears in-memory experiment data.

HTML describes content: <p>Press <strong>F</strong>.</p>. CSS controls appearance: .stimulus { font-size: 3rem; }. JavaScript controls behavior. The string "<p>Hello</p>" becomes a paragraph only when a plugin inserts it into the page.

Values, arrays, and objects

const duration = 3000;       // Number, in milliseconds in our trials.
const word = "garden";       // String.
const keys = ["f", "j"];     // Array; first element is keys[0].
const item = { text: word, correct_response: "f" }; // Object.
console.log(item.text);      // garden

const prevents reassignment of the variable; it does not freeze an object’s contents. Use let when a counter changes. JavaScript arrays start at 0 (like Python, unlike R’s usual indexing). An object resembles a Python dictionary or a named R list, but property access commonly uses a dot.

Conditions and missing values

const response = null;       // No response, not the string "null".
const correct = response !== null && response === item.correct_response;
console.log(correct);        // false

Use === for strict equality. = assigns. && means AND; ! means NOT. JavaScript uses true, false, and null; these are not Python’s True, False, and None, or R’s TRUE, FALSE, and NA. For keyboard scoring, jsPsych’s compareKeys also handles case consistently; guard a missing response first.

Functions run when called

function label(text) {
  return `<p>${text}</p>`;
}
console.log(label("garden"));
const double = (x) => x * 2;

Backticks allow ${...} interpolation. Ordinary quotes do not. A function definition describes a computation; calling it performs it. A jsPsych dynamic parameter such as stimulus: () => label(...) runs later, when the trial needs its value. on_finish runs after a trial response has been recorded. This distinction matters in Meeting 2.

A loop builds several trials

const items = [{ text: "cat" }, { text: "mep" }];
const labels = [];
for (const item of items) {
  labels.push(label(item.text));
}
console.log(labels.length); // 2

Use for ... of to visit array values. for ... in visits property names and is not the pattern we want here. A JavaScript loop builds the timeline before the experiment starts; a jsPsych procedure schedules trials during execution.

Filtering and averaging (Meeting 2)

const rows = [{ rt: 500, correct: true }, { rt: null, correct: false }];
const usable = rows.filter((row) => row.correct && Number.isFinite(row.rt));
const mean = usable.length
  ? usable.reduce((sum, row) => sum + row.rt, 0) / usable.length
  : null;

filter keeps matching values. map transforms every value. reduce combines values. A missing mean stays null; report N/A instead of inventing a zero. You may use the supplied helper while learning these methods.

Check yourself

  1. What is keys[1]? What does item.correct_response return?
  2. Change the loop so it processes three items. How many labels should appear?
  3. Predict whether "0" === 0 is true. Check it.
  4. Explain why "${word}" is different from a template literal using backticks.
  5. A line says stimulus: greeting(); another says stimulus: () => greeting(). Which calls the function immediately?

Answers: 1. "j", "f". 2. Three. 3. False: types differ. 4. Double quotes leave the placeholder as text. 5. The first. If you cannot yet explain these, that tells us where to start; it does not prevent you from participating.

Further reference: MDN JavaScript first steps.