Lab 5: Browser Information, Objects, and Script Reuse
This lab covers workbook experiments 9, 10, and 11. You will read live browser data using the navigator object, merge JavaScript objects using the spread operator, and split reusable code into separate .js files — with the exact expected output shown for every experiment.
Workbook Alignment
- Experiment 9: Display browser information
- Experiment 10: Merge properties of two objects
- Experiment 11: Include one JavaScript file into another
Learning Objectives
By the end of this lab, you will be able to:
- read browser details using the built-in
navigatorobject - create and merge JavaScript objects using the spread operator
- organize reusable code across multiple JavaScript files
- control script loading order in HTML
- display dynamic output inside the page
Software and Files Required
- completion of Lab 4
- VS Code or any text editor
- a modern browser with developer tools (F12)
- a folder named
Lab05 - files named
browser-info.html,merge-objects.html,index.html,math-utils.js, andapp.js
Folder Structure
Lab05/
browser-info.html
merge-objects.html
index.html
math-utils.js
app.js
Experiment 9: Display Browser Information
Problem Statement
Create a web page that reads and displays browser details using the JavaScript navigator object.
Procedure
- Create the
Lab05folder. - Add a new file named
browser-info.html. - Create a JavaScript object whose values are read from
navigatorproperties. - Use
Object.entries()to loop over the object and build a list. - Open in a browser and compare with the expected output format below.
Solution Code (browser-info.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Browser Information</title>
</head>
<body>
<h1>Browser Information</h1>
<!-- An empty <ul> — list items will be added by JavaScript -->
<ul id="browserInfo"></ul>
<script>
// Collect five properties from the navigator object into a plain object
const info = {
appName: navigator.appName,
appVersion: navigator.appVersion,
platform: navigator.platform,
language: navigator.language,
userAgent: navigator.userAgent
};
const list = document.getElementById("browserInfo");
// Object.entries(info) converts the object into an array of [key, value] pairs:
// [ ["appName","Netscape"], ["appVersion","5.0 ..."], ... ]
// forEach destructures each pair into key and value
Object.entries(info).forEach(([key, value]) => {
const item = document.createElement("li"); // create a new <li> element
item.textContent = key + ": " + value; // set its text
list.appendChild(item); // add it to the <ul>
});
</script>
</body>
</html>Expected Browser Output
Because navigator reads real browser data, your exact values will differ. The page should display five list items in this format:
appName: Netscape
appVersion: 5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ...
platform: Win32
language: en-US
userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ...
appName Show “Netscape”?
All modern browsers (Chrome, Firefox, Edge, Safari) return "Netscape" for appName for historical compatibility. The userAgent string is the reliable way to identify the actual browser. For example, Chrome’s user-agent contains "Chrome/..." while Firefox contains "Firefox/...".
Open F12 → Console and type navigator.language then press Enter. The console will return the same value that appears in your page — this is a quick way to check any navigator property before writing the code.
Experiment 10: Merge Properties of Two Objects
Problem Statement
Write a JavaScript program that merges the properties of two separate objects into one combined object and displays the result.
What is the Spread Operator ...?
The spread operator (...) was introduced in ES2018 for objects. When used inside {}, it copies all own properties from the source object into the new object:
const merged = { ...objectA, ...objectB };
// ^ copies all properties from objectA
// ^ then copies all properties from objectBIf both objects have a property with the same name, the second object wins and overwrites the first.
Procedure
- Create a file named
merge-objects.html. - Define two objects with related but separate data (
studentandacademic). - Merge them into a third object using the spread operator.
- Display the merged object using
JSON.stringify()for readable, formatted output. - Verify all six properties are present in the output.
Solution Code (merge-objects.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Merge Objects</title>
</head>
<body>
<h1>Merge Two Objects</h1>
<!-- <pre> keeps the indented JSON formatting intact on screen -->
<pre id="mergedOutput"></pre>
<script>
// Object 1: personal details of the student
const student = {
name: "Neha",
rollNumber: "MCA24012"
};
// Object 2: academic details stored separately
const academic = {
course: "BMC201",
semester: 2
};
// Merge: copy all properties from student, then all from academic
// into a brand-new object called merged
const merged = { ...student, ...academic };
// JSON.stringify(value, replacer, indent)
// value = merged object to convert to text
// replacer = null means include all properties
// indent = 2 means use 2-space indentation
document.getElementById("mergedOutput").textContent =
JSON.stringify(merged, null, 2);
</script>
</body>
</html>Expected Browser Output
The <pre> element should display all four properties in formatted JSON:
{
"name": "Neha",
"rollNumber": "MCA24012",
"course": "BMC201",
"semester": 2
}Try adding course: "OLD" to the student object and re-run the page. The output will show "course": "BMC201" — the value from academic — because the second spread overwrites the first. The rule is: the rightmost object wins when property names conflict.
JSON.stringify() Instead of Direct Display?
If you wrote output.textContent = merged, JavaScript would convert the object to the string "[object Object]" — not useful. JSON.stringify() converts each key-value pair into readable text. The third argument 2 adds two-space indentation so the output is easy to read.
Experiment 11: Include One JavaScript File into Another Page
Problem Statement
Create an HTML page that loads utility functions from a separate math-utils.js file and calls them from app.js.
Why Separate JavaScript Files?
Keeping code in separate .js files offers several advantages:
- The same utility functions can be used in multiple HTML pages without copying code
- Each file has a single responsibility — easier to read, test, and fix
- The browser caches
.jsfiles after the first load, so subsequent pages are faster
Procedure
- Create
math-utils.jsand declare the utility functionsadd()andmultiply(). - Create
app.jsand write the page logic that calls those functions. - Create
index.htmland load both scripts using<script src="...">tags. math-utils.jsmust appear beforeapp.jsin the HTML — the browser runs scripts top to bottom, soadd()andmultiply()must already be defined beforeapp.jstries to use them.- Open in a browser and check the output.
math-utils.js
This file only defines functions — it does not run anything itself. It is loaded first so its functions are available to app.js.
// Utility function 1: returns the sum of two numbers
function add(a, b) {
return a + b;
}
// Utility function 2: returns the product of two numbers
function multiply(a, b) {
return a * b;
}app.js
This file calls the functions defined in math-utils.js. The DOMContentLoaded listener ensures the script waits until the <p id="scriptOutput"> element exists in the page before trying to find it.
// DOMContentLoaded fires when the browser has finished parsing the HTML
// and all elements are available in the DOM
window.addEventListener("DOMContentLoaded", function () {
const output = document.getElementById("scriptOutput");
// add() and multiply() are defined in math-utils.js which is loaded first
const sum = add(10, 20); // 10 + 20 = 30
const product = multiply(10, 20); // 10 × 20 = 200
output.textContent = "Sum: " + sum + " | Product: " + product;
});index.html
The two <script> tags at the bottom of <body> load the files in the correct order:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Script Reuse</title>
</head>
<body>
<h1>Including JavaScript Files</h1>
<!-- The paragraph that app.js will write its result into -->
<p id="scriptOutput"></p>
<!-- math-utils.js MUST come first — it defines add() and multiply() -->
<script src="math-utils.js"></script>
<!-- app.js comes second — it calls add() and multiply() from above -->
<script src="app.js"></script>
</body>
</html>Expected Browser Output
The page should display the following line of text inside the <p> element:
Sum: 30 | Product: 200
| Order | What happens |
|---|---|
| 1 | Browser loads index.html and parses the HTML top to bottom |
| 2 | Reaches <script src="math-utils.js"> — downloads and runs it; add() and multiply() are now defined |
| 3 | Reaches <script src="app.js"> — downloads and runs it; registers the DOMContentLoaded listener |
| 4 | Browser finishes parsing HTML; DOMContentLoaded fires |
| 5 | The listener function runs: finds #scriptOutput, calls add(10,20) → 30, calls multiply(10,20) → 200 |
| 6 | Sets the paragraph text to "Sum: 30 | Product: 200" — visible on screen |
If you put <script src="app.js"> before <script src="math-utils.js">, the browser will try to run app.js before add() and multiply() are defined. You will get an error in the browser console:
Uncaught ReferenceError: add is not defined
Always load utility/library scripts before the scripts that depend on them.
Observation Questions
- What is the purpose of the
navigatorobject in JavaScript? - What happens when two merged objects have a property with the same name?
- Why must
math-utils.jsbe loaded beforeapp.jsinindex.html? - What is the difference between
DOMContentLoadedand theloadevent?
Viva Questions
- What is the advantage of placing reusable functions in a separate
.jsfile? - What does
JSON.stringify()do, and why is the third argument useful? - Why does
Object.entries()return an array of arrays? - How can the browser developer tools (F12 → Network tab) help you verify that both
.jsfiles were loaded?
Submission Checklist
browser-info.htmlmerge-objects.htmlindex.htmlmath-utils.jsapp.js- screenshots of all three pages showing the expected output
- short answer file for observation and viva questions
Extension Task
Add two more functions — subtract(a, b) and divide(a, b) — to math-utils.js. Update app.js to display all four calculations. For divide(), add a guard that returns "Cannot divide by zero" when b is 0.