In Jurassic Park, every procedure requires precise information - what dinosaur, how much food, when to administer, what type. Functions work the same way: parameters are named placeholders in the function definition, while arguments are the actual values passed when calling the function.
1// Parameters: name, species, weight
2function registerDinosaur(name, species, weight) {
3 console.log(`Registering: ${name}`);
4 console.log(`Species: ${species}`);
5 console.log(`Weight: ${weight} kg`);
6}
7
8// Arguments: 'Rex', 'T-Rex', 8000
9registerDinosaur('Rex', 'T-Rex', 8000);
10registerDinosaur('Blue', 'Velociraptor', 15);JavaScript is flexible - you can pass more or fewer arguments than there are parameters:
1function showInfo(name, species, weight) {
2 console.log(name); // always defined
3 console.log(species); // may be undefined
4 console.log(weight); // may be undefined
5}
6
7showInfo('Rex'); // species = undefined, weight = undefined
8showInfo('Rex', 'T-Rex', 8000, 'extra'); // extra argument is ignoredDefault parameters protect us from
undefined - if an argument isn't provided, the default value is used:1function createAlert(type = 'INFO', message = 'No message', priority = 1) {
2 console.log(`[${type}] P${priority}: ${message}`);
3}
4
5createAlert('DANGER', 'Dinosaur escaped!', 5);
6// [DANGER] P5: Dinosaur escaped!
7
8createAlert('WARNING', 'Feeding time');
9// [WARNING] P1: Feeding time
10
11createAlert();
12// [INFO] P1: No message1function createDino(name, species, nickname = `${name}-the-${species}`) {
2 console.log(`${name} (${nickname})`);
3}
4
5createDino('Rex', 'TRex');
6// "Rex (Rex-the-TRex)"
7
8createDino('Blue', 'Velociraptor', 'Blue');
9// "Blue (Blue)"1function generateId() {
2 return `DINO-${Math.floor(Math.random() * 1000)}`;
3}
4
5function registerDino(name, id = generateId()) {
6 console.log(`${name}: ${id}`);
7}
8
9registerDino('Rex', 'DINO-001'); // Rex: DINO-001
10registerDino('Blue'); // Blue: DINO-847 (random)The
... rest operator collects all remaining arguments into an array. There can be only one rest parameter, and it must be last:1function logIncident(reporter, severity, ...details) {
2 console.log(`Reporter: ${reporter}`);
3 console.log(`Severity: ${severity}`);
4 console.log(`Details (${details.length}):`);
5 details.forEach((detail, i) => {
6 console.log(` ${i + 1}. ${detail}`);
7 });
8}
9
10logIncident('Dr. Rex', 'HIGH',
11 'T-Rex escaped from zone A',
12 'Fence damaged at section 7',
13 'Backup power offline'
14);
15// Reporter: Dr. Rex
16// Severity: HIGH
17// Details (3):
18// 1. T-Rex escaped from zone A
19// 2. Fence damaged at section 7
20// 3. Backup power offlineBefore rest parameters existed, functions used the
arguments object - but it has limitations:1// Old approach - arguments object (not available in arrow functions!)
2function oldStyle() {
3 console.log(arguments); // array-like object
4 console.log(Array.isArray(arguments)); // false!
5
6 // Must convert to array to use array methods
7 const arr = Array.from(arguments);
8 arr.forEach(arg => console.log(arg));
9}
10
11// New approach - rest parameters (proper array!)
12function newStyle(...args) {
13 console.log(Array.isArray(args)); // true!
14 args.forEach(arg => console.log(arg));
15}Spread (
...) "unpacks" an array into individual arguments - the opposite of rest:1function calculateDanger(speed, size, intelligence) {
2 const score = speed * 0.4 + size * 0.3 + intelligence * 0.3;
3 return score.toFixed(2);
4}
5
6const tRexStats = [85, 95, 60]; // speed, size, intelligence
7
8// Without spread:
9calculateDanger(tRexStats[0], tRexStats[1], tRexStats[2]);
10
11// With spread:
12calculateDanger(...tRexStats);
13// Equivalent: calculateDanger(85, 95, 60)1const safeZones = ['A', 'B'];
2const dangerZones = ['C', 'D'];
3const allZones = [...safeZones, 'E', ...dangerZones];
4
5console.log(allZones); // ['A', 'B', 'E', 'C', 'D']Instead of accepting a whole object and accessing its properties, you can destructure directly in the parameter list:
1// Without destructuring
2function displayDinoInfo(dino) {
3 console.log(`${dino.name} (${dino.species}) - ${dino.weight}kg`);
4}
5
6// With destructuring in parameters
7function displayDinoDestructured({ name, species, weight = 'unknown' }) {
8 console.log(`${name} (${species}) - ${weight}kg`);
9}
10
11const rex = { name: 'Rex', species: 'T-Rex', weight: 8000 };
12displayDinoDestructured(rex);
13// "Rex (T-Rex) - 8000kg"
14
15displayDinoDestructured({ name: 'Blue', species: 'Velociraptor' });
16// "Blue (Velociraptor) - unknownkg"The spread operator is also useful for merging arrays or objects:
1// Merging dinosaur data from different systems
2const basicDinoData = {
3 id: "VLR-01",
4 name: "Blue",
5 species: "Velociraptor"
6};
7
8const healthData = {
9 weight: 100,
10 health: "Good",
11 lastCheckup: "2023-05-10"
12};
13
14const behavioralData = {
15 temperament: "Aggressive",
16 packStatus: "Beta",
17 trainingLevel: "Advanced"
18};
19
20// Creating a complete dinosaur profile
21const completeProfile = {
22 ...basicDinoData,
23 ...healthData,
24 ...behavioralData,
25 updatedAt: new Date().toISOString()
26};
27
28console.log(completeProfile);
29// {
30// id: "VLR-01",
31// name: "Blue",
32// species: "Velociraptor",
33// weight: 100,
34// health: "Good",
35// lastCheckup: "2023-05-10",
36// temperament: "Aggressive",
37// packStatus: "Beta",
38// trainingLevel: "Advanced",
39// updatedAt: "2023-06-15T10:30:00.000Z"
40// }When functions accept many parameters, it's often easier to pass them as an object. Destructuring (ES6+) allows for elegant extraction of those values:
1// Function accepting an options object
2function createDinosaurEnclosure({ species, capacity, securityLevel, location, features = [] }) {
3 console.log(`Creating enclosure for species: ${species}`);
4 console.log(`Capacity: ${capacity} specimens`);
5 console.log(`Security level: ${securityLevel}/5`);
6 console.log(`Location: ${location}`);
7
8 if (features.length > 0) {
9 console.log("Additional enclosure features:");
10 features.forEach(feature => console.log(`- ${feature}`));
11 }
12
13 return `Enclosure for ${species} created at location ${location}`;
14}
15
16// Calling with options object
17const enclosureResult = createDinosaurEnclosure({
18 species: "Triceratops",
19 capacity: 6,
20 securityLevel: 3,
21 location: "Sector B",
22 features: ["Water reservoir", "Cretaceous-era vegetation", "Observation platform"]
23});
24
25console.log(enclosureResult);
26// "Enclosure for Triceratops created at location Sector B"We can also set default values for the entire object:
1function scheduleLabTest({
2 specimenId,
3 testType = "DNA",
4 priority = "Normal",
5 assignedTo = "Dr. Wu"
6} = {}) { // Default empty object prevents errors when no argument is passed
7
8 console.log(`Scheduled ${testType} test for specimen #${specimenId}`);
9 console.log(`Priority: ${priority}`);
10 console.log(`Assigned to: ${assignedTo}`);
11
12 return `Test scheduled. Test ID: TEST-${specimenId}-${Date.now()}`;
13}
14
15// Calling with all options
16scheduleLabTest({
17 specimenId: "VLR-42",
18 testType: "Genome sequencing",
19 priority: "High",
20 assignedTo: "Dr. Sattler"
21});
22
23// Calling with only the required parameter
24scheduleLabTest({ specimenId: "TRX-05" });
25
26// Calling without arguments (works thanks to the default empty object)
27// scheduleLabTest(); // Without the default empty object, this would throw an errorLet's combine the concepts we've learned by creating a comprehensive incident management system for Jurassic Park:
1// Incident management system
2const incidentManager = (function() {
3 // Private incidents array
4 const incidents = [];
5
6 // Private helper functions
7 function generateIncidentId() {
8 return `INC-${Date.now()}-${Math.floor(Math.random() * 1000)}`;
9 }
10
11 function notifyTeam(incidentType, location, ...personnel) {
12 console.log(`ALERT: Incident of type "${incidentType}" at location "${location}"`);
13
14 if (personnel.length > 0) {
15 console.log(`Notifying personnel: ${personnel.join(', ')}`);
16 } else {
17 console.log("Notifying all security personnel");
18 }
19 }
20
21 // Public API
22 return {
23 // Method for reporting a new incident
24 reportIncident: function({
25 type,
26 location,
27 description,
28 severity = "Medium",
29 reportedBy,
30 affectedAssets = [],
31 notifyPersonnel = []
32 }) {
33 const incidentId = generateIncidentId();
34
35 const incident = {
36 id: incidentId,
37 type,
38 location,
39 description,
40 severity,
41 reportedBy,
42 affectedAssets,
43 status: "New",
44 reportedAt: new Date().toISOString(),
45 resolvedAt: null
46 };
47
48 incidents.push(incident);
49
50 // Notify personnel
51 notifyTeam(type, location, ...notifyPersonnel);
52
53 return {
54 incidentId,
55 message: `Incident #${incidentId} has been registered`
56 };
57 },
58
59 // Method for updating incident status
60 updateIncidentStatus: function(incidentId, newStatus, resolvedBy = null) {
61 const incident = incidents.find(inc => inc.id === incidentId);
62
63 if (!incident) {
64 return { success: false, message: "Incident not found" };
65 }
66
67 incident.status = newStatus;
68
69 if (newStatus === "Resolved") {
70 incident.resolvedAt = new Date().toISOString();
71 incident.resolvedBy = resolvedBy;
72 }
73
74 return {
75 success: true,
76 message: `Incident #${incidentId} status updated to "${newStatus}"`
77 };
78 },
79
80 // Method for retrieving incident information
81 getIncidentInfo: function(incidentId) {
82 const incident = incidents.find(inc => inc.id === incidentId);
83
84 if (!incident) {
85 return null;
86 }
87
88 return { ...incident }; // Return a copy to prevent original modification
89 },
90
91 // Method for retrieving incidents by criteria
92 getIncidents: function({ status, type, severity, limit = 10 } = {}) {
93 let result = [...incidents]; // Copy the array
94
95 // Filter by criteria
96 if (status) {
97 result = result.filter(inc => inc.status === status);
98 }
99
100 if (type) {
101 result = result.filter(inc => inc.type === type);
102 }
103
104 if (severity) {
105 result = result.filter(inc => inc.severity === severity);
106 }
107
108 // Sort by most recent
109 result.sort((a, b) => new Date(b.reportedAt) - new Date(a.reportedAt));
110
111 // Limit results
112 return result.slice(0, limit);
113 }
114 };
115})();
116
117// Example usage
118const breakoutIncident = incidentManager.reportIncident({
119 type: "Dinosaur escape",
120 location: "Velociraptor Enclosure - Sector C",
121 description: "Three velociraptors escaped from the enclosure. Park staff evacuated.",
122 severity: "Critical",
123 reportedBy: "Robert Muldoon",
124 affectedAssets: ["VLR-02", "VLR-03", "VLR-04"],
125 notifyPersonnel: ["Dr. Grant", "John Hammond", "Ellie Sattler", "Ian Malcolm"]
126});
127
128console.log(breakoutIncident.message);
129
130// Update incident status
131const updateResult = incidentManager.updateIncidentStatus(
132 breakoutIncident.incidentId,
133 "In progress",
134 "SWAT Team"
135);
136console.log(updateResult.message);
137
138// Get incident details
139const incidentDetails = incidentManager.getIncidentInfo(breakoutIncident.incidentId);
140console.log(incidentDetails);
141
142// Search incidents by criteria
143const criticalIncidents = incidentManager.getIncidents({
144 severity: "Critical",
145 limit: 5
146});
147console.log(`Found ${criticalIncidents.length} critical incidents`);This example demonstrates:
Functions in JavaScript offer many powerful mechanisms for working with parameters and arguments, allowing you to create flexible, readable, and easy-to-use APIs:
With these mechanisms, we can create functions that are flexible yet simple to use - which is crucial for managing complex systems like our virtual Jurassic Park.
"Function parameters are like the safety protocol checklist" - says Dr. Rex. "Each step (parameter) must be clearly defined, and if something isn't specified, the default procedure kicks in!"