We use cookies to enhance your experience on the site
CodeWorlds

Function Parameters and Arguments

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.

Basic Parameters

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);

Mismatched Parameter and Argument Count

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 ignored

Default Parameters

Default 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 message

Default Values Can Reference Other Parameters

1function 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)"

Default Values Can Be Expressions or Function Calls

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)

Rest Parameters

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 offline

Rest vs. arguments Object

Before 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 Operator in Function Calls

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)

Spread for Combining Arrays

1const safeZones = ['A', 'B'];
2const dangerZones = ['C', 'D'];
3const allZones = [...safeZones, 'E', ...dangerZones];
4
5console.log(allZones); // ['A', 'B', 'E', 'C', 'D']

Object Destructuring in Parameters

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"

Spread for Combining Objects

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// }

Object Destructuring in Parameters

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 error

Incident Management System Example

Let'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:

  1. Object destructuring for accepting function parameters
  2. Default parameter usage
  3. Rest parameters for handling variable argument counts
  4. Spread operator for passing arguments
  5. Advanced data processing and filtering based on parameters

Summary

Functions in JavaScript offer many powerful mechanisms for working with parameters and arguments, allowing you to create flexible, readable, and easy-to-use APIs:

  • Default parameters simplify handling of optional arguments
  • Rest parameters enable functions to accept variable numbers of arguments
  • Spread operator allows passing array elements as separate arguments
  • Object destructuring makes working with many parameters easier by organizing them into objects

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!"

Go to CodeWorlds