• Assignment to property of function parameter no-param-reassign

avatar

Last updated: Mar 7, 2024 Reading time · 3 min

banner

# Table of Contents

  • Disabling the no-param-reassign ESLint rule for a single line
  • Disabling the no-param-reassign ESLint rule for an entire file
  • Disabling the no-param-reassign ESLint rule globally

# Assignment to property of function parameter no-param-reassign

The ESLint error "Assignment to property of function parameter 'X' eslint no-param-reassign" occurs when you try to assign a property to a function parameter.

To solve the error, disable the ESLint rule or create a new object based on the parameter to which you can assign properties.

assignment to property of function parameter eslint no param reassign

Here is an example of how the error occurs.

The ESLint rule forbids assignment to function parameters because modifying a function's parameters also mutates the arguments object and can lead to confusing behavior.

One way to resolve the issue is to create a new object to which you can assign properties.

We used the spread syntax (...) to unpack the properties of the function parameter into a new object to which we can assign properties.

If you need to unpack an array, use the following syntax instead.

The same approach can be used if you simply need to assign the function parameter to a variable so you can mutate it.

We declared the bar variable using the let keyword and set it to the value of the foo parameter.

We are then able to reassign the bar variable without any issues.

# Disabling the no-param-reassign ESLint rule for a single line

You can use a comment if you want to disable the no-param-reassign ESLint rule for a single line.

Make sure to add the comment directly above the assignment that causes the error.

# Disabling the no-param-reassign ESLint rule for an entire file

You can also use a comment to disable the no-param-reassign ESLint rule for an entire file.

Make sure to add the comment at the top of the file or at least above the function in which you reassign parameters.

The same approach can be used to disable the rule only for a single function.

The first comment disables the no-param-reassign rule and the second comment enables it.

If you try to reassign a parameter after the second comment, you will get an ESLint error.

# Disabling the no-param-reassign ESLint rule globally

If you need to disable the no-param-reassign rule globally, you have to edit your .eslintrc.js file.

disable no param reassign rule globally

If you only want to be able to assign properties to an object parameter, set props to false instead of disabling the rule completely.

The following code is valid after making the change.

If you use a .eslintrc or .eslintrc.json file, make sure to double-quote the properties and values.

If you want to only allow assignment to object parameters, use the following line instead.

Make sure all properties are double-quoted and there are no trailing commas if your config is written in JSON.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

  • eslint is not recognized as an internal or external command
  • Plugin "react" was conflicted between package.json » eslint-config-react-app
  • React: Unexpected use of 'X' no-restricted-globals in ESLint
  • TypeScript ESLint: Unsafe assignment of an any value [Fix]
  • ESLint error Unary operator '++' used no-plusplus [Solved]
  • ESLint Prefer default export import/prefer-default-export
  • Arrow function should not return assignment. eslint no-return-assign
  • TypeError: Cannot redefine property: X in JavaScript [Fixed]
  • ESLint: disable multiple rules or a rule for multiple lines
  • Expected linebreaks to be 'LF' but found 'CRLF' linebreak-style
  • Missing return type on function TypeScript ESLint error

book cover

Borislav Hadzhiev

Web Developer

buy me a coffee

Copyright © 2024 Borislav Hadzhiev

HatchJS Logo

HatchJS.com

Cracking the Shell of Mystery

How to Assign to the Property of a Function Parameter in JavaScript

Avatar

Assignment to Property of Function Parameter

One of the most powerful features of JavaScript is the ability to assign values to the properties of function parameters. This can be used to create complex and dynamic code that can be easily modified.

In this article, we will take a closer look at assignment to property of function parameter. We will discuss what it is, how it works, and how it can be used to improve your code.

We will also provide some examples of how assignment to property of function parameter can be used in practice. By the end of this article, you will have a solid understanding of this important JavaScript concept.

Property Value Example
name “John Doe” function greet(name) {
console.log(`Hello, ${name}`);
}

greet(“John Doe”);

age 25 function calculateAge(birthdate) {
const today = new Date();
const age = today.getFullYear() – birthdate.getFullYear();
return age;
}

const age = calculateAge(new Date(“1997-01-01”));
console.log(age);

In JavaScript, a function parameter is a variable that is declared inside the function’s parentheses. When a function is called, the value of the argument passed to the function is assigned to the function parameter.

For example, the following function takes a string argument and prints it to the console:

js function greet(name) { console.log(`Hello, ${name}`); }

greet(“world”); // prints “Hello, world”

In this example, the `name` parameter is assigned the value of the `”world”` argument.

Assignment to property of function parameter

Assignment to property of function parameter is a JavaScript feature that allows you to assign a value to a property of a function parameter. This can be useful for initializing the value of a parameter or for passing a reference to an object.

For example, the following code assigns the value `”hello”` to the `name` property of the `greet` function parameter:

js function greet(name) { name.value = “hello”; }

greet({ value: “world” }); // prints “hello”

In this example, the `name` parameter is a JavaScript object. The `value` property of the `name` object is assigned the value of the `”hello”` argument.

When to use assignment to property of function parameter?

You should use assignment to property of function parameter when you need to:

  • Initialize the value of a parameter
  • Pass a reference to an object

Avoid creating a new object

Initializing the value of a parameter

You can use assignment to property of function parameter to initialize the value of a parameter. For example, the following code initializes the `name` property of the `greet` function parameter to the value of the `”world”` argument:

js function greet(name) { name.value = “world”; }

Passing a reference to an object

You can use assignment to property of function parameter to pass a reference to an object. For example, the following code passes a reference to the `person` object to the `greet` function:

js function greet(person) { console.log(`Hello, ${person.name}`); }

const person = { name: “John Doe” };

greet(person); // prints “Hello, John Doe”

You can use assignment to property of function parameter to avoid creating a new object. For example, the following code uses assignment to property of function parameter to avoid creating a new object for the `name` parameter:

greet(“John Doe”); // prints “Hello, John Doe”

In this example, the `name` parameter is a string literal. The `name` property of the `name` parameter is assigned the value of the `”John Doe”` string literal. This avoids creating a new object for the `name` parameter.

Assignment to property of function parameter is a JavaScript feature that can be used to initialize the value of a parameter, pass a reference to an object, and avoid creating a new object. It is a powerful feature that can be used to improve the performance and readability of your code.

Additional resources

  • [MDN: Assignment to property of function parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Assignment_to_property_of_function_parameter)
  • [Stack Overflow: When to use assignment to property of function parameter?](https://stackoverflow.com/questions/1435573/when-to-use-assignment-to-property-of-function-parameter)
  • [Codecademy: Assignment to property of function parameter](https://www.codecademy.com/learn/javascript/lessons/assignment-to-property-of-function-parameter)

3. How to use assignment to property of function parameter?

To use assignment to property of function parameter, you can simply assign a value to the property of the function parameter. For example, the following code assigns the value `”hello”` to the `name` property of the `greet` function parameter:

In this example, the `greet` function is called with the argument `”world”`. The `name` property of the `greet` function parameter is then assigned the value `”hello”`. When the `greet` function is called, the value of the `name` property is used to print the message `”Hello, world”`.

Assignment to property of function parameter can be used to initialize the value of a parameter, pass a reference to an object, or avoid creating a new object.

You can use assignment to property of function parameter to initialize the value of a parameter. For example, the following code initializes the value of the `name` property of the `greet` function parameter to the value of the `name` variable:

js function greet(name) { name = “world”; console.log(`Hello, ${name}`); }

In this example, the `name` variable is assigned the value `”world”` before the `greet` function is called. The `name` property of the `greet` function parameter is then assigned the value of the `name` variable. When the `greet` function is called, the value of the `name` property is used to print the message `”Hello, world”`.

You can use assignment to property of function parameter to pass a reference to an object. For example, the following code passes a reference to the `user` object to the `greet` function:

js function greet(user) { console.log(`Hello, ${user.name}`); }

const user = { name: “John Doe”, };

greet(user); // prints “Hello, John Doe”

In this example, the `user` object is passed to the `greet` function as a parameter. The `greet` function then uses the `name` property of the `user` object to print the message `”Hello, John Doe”`.

Avoiding creating a new object

You can use assignment to property of function parameter to avoid creating a new object. For example, the following code uses assignment to property of function parameter to avoid creating a new object for the `user` variable:

In this example, the `user` variable is assigned the value of the `user` object. The `greet` function then uses the `name` property of the `user` variable to print the message `”Hello, John Doe”`.

By using assignment to property of function parameter, you can avoid creating a new object for the `user` variable. This can improve the performance of your code and reduce the amount of memory that is used.

4. Pitfalls of assignment to property of function parameter

There are a few pitfalls to be aware of when using assignment to property of function parameter:

  • The value of the property may be overwritten. If you assign a value to the property of a function parameter, the value of the property may be overwritten by the next time the function is called. For example, the following code assigns the value `”hello”` to the `name` property of the `greet` function parameter. The next time the `greet` function is called, the value of the `name` property will be overwritten by the value of the `name` argument.

js function greet(name) { name = “hello”; console.log(`Hello, ${name}`); }

greet(“world”); // prints “Hello, hello” greet(“hello”); // prints “Hello, hello”

A: Assignment to property of function parameter occurs when you assign a value to a property of a function parameter. This can be done by using the dot operator (.) to access the property, or by using the bracket operator ([]) to index into the property.

For example, the following code assigns the value “10” to the `x` property of the `foo()` function’s parameter `y`:

const foo = (y) => { y.x = 10; };

foo({ x: 5 }); // { x: 10 }

Q: Why is assignment to property of function parameter dangerous?

A: Assignment to property of function parameter can be dangerous because it can change the value of the property in the calling scope. This can lead to unexpected behavior and errors.

For example, the following code changes the value of the `x` property of the global variable `a`:

foo({ x: 5 }); // a.x is now 10

This behavior can be difficult to debug, as it may not be obvious that the change to the `x` property is being caused by the `foo()` function.

Q: How can I avoid assignment to property of function parameter?

There are a few ways to avoid assignment to property of function parameter. One way is to use the `const` keyword to declare the function parameter as a constant. This will prevent the value of the parameter from being changed.

Another way to avoid assignment to property of function parameter is to use the `readonly` keyword to declare the function parameter as read-only. This will prevent the value of the parameter from being changed, even by assignment to a property of the parameter.

Finally, you can also use the `Object.freeze()` method to freeze the object that is passed as the function parameter. This will prevent any changes to the object, including changes to the values of its properties.

Q: What are the best practices for assignment to property of function parameter?

The best practices for assignment to property of function parameter are as follows:

  • Use the `const` keyword to declare function parameters as constants.
  • Use the `readonly` keyword to declare function parameters as read-only.
  • Use the `Object.freeze()` method to freeze objects that are passed as function parameters.

Here are some key takeaways from this article:

  • Assigning to the property of a function parameter can change the value of the original variable.
  • This can lead to unexpected behavior and security vulnerabilities.
  • To avoid this problem, use the `const` keyword or pass arguments by reference.

By following these tips, you can write more secure and reliable JavaScript code.

Author Profile

Marcus Greenwood

Latest entries

  • December 26, 2023 Error Fixing User: Anonymous is not authorized to perform: execute-api:invoke on resource: How to fix this error
  • December 26, 2023 How To Guides Valid Intents Must Be Provided for the Client: Why It’s Important and How to Do It
  • December 26, 2023 Error Fixing How to Fix the The Root Filesystem Requires a Manual fsck Error
  • December 26, 2023 Troubleshooting How to Fix the `sed unterminated s` Command

Similar Posts

How to convert an int array to a list in java.

Java Int Array to List: A Comprehensive Guide Converting an int array to a list in Java is a common task that can be accomplished in a few different ways. The best method for you will depend on the specific needs of your project. In this guide, we will discuss the different ways to convert…

How to Convert a Java ArrayList to an Int Array

Java ArrayList to Int Array: A Comprehensive Guide In Java, an ArrayList is a data structure that can store a collection of objects. The objects in an ArrayList can be of any type, including primitive types such as int. However, when you need to work with an ArrayList of ints, it can be more efficient…

Java util concurrent RejectedExecutionException: How to Handle It?

Java util concurrent rejectedexecutionexception Every once in a while, you might run into a `RejectedExecutionException` in your Java code. This exception is thrown when a thread pool is unable to accept a new task for execution. There are a few different reasons why this might happen, but the most common is that the thread pool…

Keytool Error: java.io.IOException: Keystore password was incorrect

Keytool Error: java.io.IOException: Keystore password was incorrect Have you ever tried to use the keytool command to manage your Java keystore, only to be met with the error “java.io.IOException: Keystore password was incorrect”? If so, you’re not alone. This is a common error that can be caused by a number of things, from typos to…

AngularJS ng-click not working: Causes and solutions

AngularJS ng-click not working: A comprehensive guide AngularJS ng-click is a directive that allows you to bind a click event to a DOM element. When the element is clicked, the code in the ng-click expression is executed. However, there are a number of reasons why ng-click might not be working as expected. In this comprehensive…

How to Add a Row to a Table in JavaScript

Adding a row to a table in JavaScript Tables are a powerful way to display data in a structured and organized way. In JavaScript, you can easily add a new row to a table using the `insertRow()` method. This method takes two arguments: the index of the row to insert before, and an optional object…

Code Examples for no-param-reassign Rule

When you define a function, you can specify variables that the function will receive as input. These are called parameters. The no-param-reassign rule discourages directly changing the value of these parameters within the function.

There are two reasons for this:

  • Clarity: If you modify a parameter inside the function, it can be confusing for someone reading the code to understand what the function does. They might expect the parameter value to stay the same throughout the function.
  • Unexpected behavior: In JavaScript, there's a concept called the arguments object. This object holds the values of all the arguments passed to a function. If you change a parameter inside the function, it can also unintentionally modify the arguments object, leading to unexpected results.

Are there exceptions?

There are some cases where reassigning a parameter might be necessary. For instance, you might be working with an object and want to modify one of its properties. In these cases, ESLint provides ways to configure the no-param-reassign rule to allow such modifications while still catching unintended changes.

Strict mode and no-param-reassign

If your code is written in strict mode (a more secure way to write JavaScript), the no-param-reassign rule becomes less important. Strict mode already offers some protections against unintended modifications of the arguments object.

  • You'll see an error message from ESLint when you try to directly reassign a parameter value within a function. This typically looks like no-param-reassign: Assignment to function parameter '<parameter_name>' .

Troubleshooting:

Configure no-param-reassign : ESLint allows some configuration for this rule. You can:

  • Ignore Specific Parameters: If certain parameters are meant to be modified (like state in state management libraries), you can configure no-param-reassign to ignore those specific names.
  • Allow Property Modifications: You can allow modifications to properties of objects passed as parameters while still disallowing complete reassignment.

This code triggers a no-param-reassign error because it tries to change the value of the x parameter directly:

Fix: Working with the Parameter's Value

Here, we avoid the error by using the original parameter value ( num ) within the function:

Error: Modifying an Object Property

This code attempts to modify a property ( name ) of the object passed as a parameter, which can also trigger the error in some configurations:

Fix: Ignoring Property Modifications (Configuration)

If modifying object properties is intended, you can configure no-param-reassign to allow it:

Allowed Scenario: Working with Copies (Array)

This code demonstrates a case where creating a copy of the parameter (array) is necessary for modification:

Destructuring with Default Values:

  • When defining the function, you can use destructuring with default values for parameters. This allows you to provide a fallback value if no argument is passed, avoiding the need to reassign later.

Early Return with Modified Copy:

  • If you need to modify data passed as a parameter (like an object or array), consider creating a copy early on and working with the copy. Then, return the modified copy from the function.

Functional Programming Techniques:

Controls which imports are allowed in your JavaScript code.Helps enforce coding standards and prevent potential issues.Use Cases:

ESLint is a popular tool for JavaScript developers that helps enforce coding style and identify potential errors. It does this by following a set of rules that you can configure for your project

What it does: It checks your code for any variables that you use but haven't properly declared using var, let, or const

Here's how it works:The rule scans your code for variable declarations (like let, const, or var).Then it checks if the variable is ever used throughout the code

What it catches: The rule flags any instance where you reference a variable, function, or class before it's formally declared with const

Simply re-throwing the error: If your catch block just catches an error and then throws it again without any modification or handling

Escapes in Strings: In JavaScript, backslashes (\) are used to escape characters that might otherwise have special meanings within strings

JavaScript: Don’t Reassign Your Function Arguments

UPDATE : The point of this post is to raise awareness that reassigning the value of an argument variable mutates the arguments object. The code example is contrived and exists solely to help illustrate that behavior.

Did you know that a JavaScript function’s named parameter variables are synonyms for the corresponding elements in that function’s Arguments object?

I ran into this while experimenting with a function that was written to take either two or three arguments, providing a default for the first argument if only two are passed.

2 3 4 5 6 7 8 9 11 12 13 14 15 16 17 makePerson = function(favoriteColor, name, age) { if (arguments.length < 3) { favoriteColor = "green"; name = arguments[0]; age = arguments[1]; } return { name: name, age: age, favoriteColor: favoriteColor }; }; var person = makePerson("Joe", 18); console.log(JSON.stringify(person)); // => {"name":"green","age":"green","favoriteColor":"green"}

Strangely, all of the values in the result object are set to "green" . I was expecting to see

But when I set favoriteColor to "green" I was also changing arguments[0] to be "green" . The situation only got worse when I set name = arguments[0] effectively changing arguments[1] to be "green" as well.

I had not realized that named arguments are synonyms for the elements of the Arguments object. I found a good explanation on Rx4AJAX:

The numbered properties of the Arguments Object are synonymous with the local variables that hold the named function parameters. They both reference the same address in the stack. If the function body has code that changes the value of a parameter either via a name reference or the arguments[] array reference, both referenced values will reflect the same value.

Regardless of the language, it is generally not a good idea to reassign the parameter variables inside a function. In JavaScript it turns out to be a really bad idea.

Additional information:

  • Check out this jsFiddle to experiment with the code snippet above.
  • A comment on this StackOverflow question describes this “magical behavior” of JavaScript.
  • JavaScript Garden describes this behavior in its section on the arguments object.

Related Posts

Embed payload cms 3.0 admin ui in your next.js app, remix is incredible — if it fits your use case, vercel: a valuable debugging tool, keep up with our latest posts..

We’ll send our latest tips, learnings, and case studies from the Atomic braintrust on a monthly basis.

' src=

So the arguments object isn’t a “real” array, so you run into problems when you treat it as such.

Here’s a working example where you turn the arguments object into an array with Array.prototype.slice()

http://jsfiddle.net/wookiehangover/yZPj8/4/

This is a pretty common beginner’s mistake and is covered in most advanced books, such as Javascript Patterns or High Performance Javascript.

Here’s a good resource about how the arguments object works: https://developer.mozilla.org/en/JavaScript/Reference/functions_and_function_scope/arguments

' src=

If you slice the Arguments, the get aan array, which is not “live”. This way, you can reassign the arguments without any problems. http://jsfiddle.net/Avorin/yZPj8/6/

' src=

When I want to pass a varying number of parameters to a function, I either use a predefined object or an object literal myself to begin with (I presume this example function is simplified).

You can also clutter up the function calls with things like makePerson(null, “Joe”, 18) and test for nulls, too, instead of array lengths.

This is the solution I found, using this. instead of an args array. I’m not sure which solution is better.

http://jsfiddle.net/Q2LMT/

' src=

Or simply refer to the arguments by name when changing their values.

' src=

This article roughly says:

When you misuse the arguments object, unexpected results happen.

The solution: don’t misuse the arguments object. Leave the param list empty and use your logic to fill out variable names if you need that

' src=

This is why I love working with Rails… most Rails functions take hashes as arguments, so you can your real arguments in in any order, and it guarantees code verbosity. Example:

button_to ‘Add to Cart’, line_items_path(:product_id => product), :remote => true

where :remote=>true is the third argument, a hash, and contains all optional parameters you could add (in this case, :method, :disabled, :confirm, and :remote).

' src=

var makePerson = function(favoriteColor, name, age) { if (arguments.length < 3) { favoriteColor = "green"; name = arguments[0]; age = arguments[1]; } return { name: name, age: age, favoriteColor: (arguments.length < 3 ? "green" : favoriteColor) }; };

' src=

How very Perl-ish of Javascript.

Ignore this blog post’s advice. It is perfectly fine to reassign function arguments in Javascript. If you just follow the convention of putting option arguments at the end of the argument list instead of the beginning, you avoid this problem all together and simplify your code:

var makePerson = function(name, age, favoriteColor) { favoriteColor = favoriteColor || “green”; return { name: name, age: age, favoriteColor: favoriteColor }; };

' src=

Who makes the first argument optional? Seriously? There are numerous things wrong with your code.

' src=

What a terrible programming language.

' src=

Larry Clapp, this isn’t perlish at all. In Perl you do named parameters through local variables. They’re duplicated not ref-copied.

use strict; use warnings;

my $makePerson = sub { my ( $favoriteColor, $name, $age ) = @_;

if ( @_ $name , age => $age , favoriteColor => $favoriteColor }

use Data::Dumper; die Dumper $makePerson->(‘Joe’, 18);

What you’re confusing is Perl’s special array variable `@_` which is used to store references to the parameters from the caller, making them accessible in the callee. So the sub implementation themselves are pass-by-reference, but the assignment itself requires a total copy. Not to say you couldn’t achieve the same effect with Perl if you *really wanted too*, but it requires a ton of non-accidental (contrived) work.

my $makePerson = sub { my ( $favoriteColor, $name, $age ) = ( \$_[0], \$_[1], \$_[2] ); #my ( $favoriteColor, $name, $age ) = @_;

if ( length @_ $$name , age => $$age , favoriteColor => $$favoriteColor }

use Data::Dumper; my $name = ‘Joe’; my $age = 18; die Dumper $makePerson->($name, $age);

' src=

How about just using a configuration object?

var person = makePerson({name:”Joe”, age:18})

Inside the function look for the property you want to default.

' src=

JavaScript reveals more and more of its awful design. NaN != NaN ?????

' src=

the problem isn’t with using arguments , the problem is with your use of it.

Writing the code: function example (x, y, z) { x = 1; y = arguments[0]; z = arguments[1]; }

will make every value 1 because I wasn’t very careful about the order of my actions.

As the article you quoted states, the variables x, y, and z are synonymous with arguments [0], [1], and [2] respectively, so if I called example(3,4) all I would be doing in my function is assigning 3 to x and 4 to y with the function call, then assigning 1 to x, the value of x to y, then the value of y to z. All of my values would be the same (and 1) afterwards.

You do the same thing in your code. You pass in (favoriteColor: Joe, name: 18) and then set the favoriteColor to “green” before taking the value of “green” and pasting it on to the name, then taking the new value of name (also “green”) and pasting it in to the value of age. If you had instead written that code in the reverse order, it would have worked as you had initially expected.

[…] service allows you to react immediately to spikes in website traffic. Just recently our blog had a post go viral on Reddit causing an extreme spike in traffic. Using a live information radiator on our office […]

' src=

There are special edge cases like Array.prototype.reduce where assign to accumulator argument passed between iterations is only good practice:

const aggregate = someArray.reduce((acc, item) => { acc[item.prop] = (acc[item.prop] || 0) + 1; }, {} /* this is initial state */);

' src=

Choose Parameters or Arguments….but using both is asking for trouble.

If you are using Parameters defined in the Function signature, then you have no need to refer to the arguments information.

If you plan on using arguments, then do not define Parameters.

Mixing the two, is asking for problems and the reason for the overall purpose of this post.

Comments are closed.

Tell Us About Your Project

We’d love to talk with you about your next great software project. Fill out this form and we’ll get back to you within two business days.

Eliahu Garcia Lozano

Destructuring Assignment In A Function Parameter

Destructuring Assignment In A Function Parameter

Eliahu Garcia Lozano's photo

Have you ever passed an argument as a null or undefined in a function? Since ES2015 (aka ES6) you don’t have to . You can use JavaScript destructuring.

We all have this Utils.js file in our projects where we have all kinds of functions that will be used all over the project. Imagine you have a To-Do app and one of those functions was addTodoItem and you had to call this function in different places.

Function declaration would look like this:

Before calling the function, see the characteristics for each parameter:

  • Title => required.
  • Description => !required.
  • DueDate => !required.

Let’s add a few items to the list now.

If we pay attention to the last example, we can see that on the first day of the month I need to pay my bills. 🤣

Jokes aside, we see that I had to pass the second value as undefined because the function is expecting the description as the second parameter.

For this specific example, if I wanted to pass a dueDate, first I would have to check whether the description is undefined or not before I call the addTodoItem function.

Here is where using destructuring will be very helpful.

This is how the addTodoItem would look now. 👇

Let’s add again the same items as before.

If you pay attention to the last item added, you’ll see that there was no need on adding the undefined for the description. Just title and dueDate.

There is more: not only do you not need to pass undefined anymore, but you can even change the order of how you pass the arguments and it will still work.

That’s it! We saw how to use destructuring when declaring a function and how to call that function and provide the arguments.

Remember that you can get rid of the undefined or null since the order of the arguments doesn’t matter.

PS. Remember to pay your bills. 🤣

If you found it useful, please like, subscribe, and share the knowledge. You might like what I share on my Twitter too.

Disallow Reassignment of Function Parameters (no-param-reassign)

Assignment to variables declared as function parameters can be misleading and lead to confusing behavior, as modifying function parameters will also mutate the arguments object. Often, assignment to function parameters is unintended and indicative of a mistake or programmer error.

This rule can be also configured to fail when function parameters are modified. Side effects on parameters can cause counter-intuitive execution flow and make errors difficult to track down.

Rule Details

This rule aims to prevent unintended behavior caused by modification or reassignment of function parameters.

Examples of incorrect code for this rule:

Examples of correct code for this rule:

This rule takes one option, an object, with a boolean property "props" , and arrays "ignorePropertyModificationsFor" and "ignorePropertyModificationsForRegex" . "props" is false by default. If "props" is set to true , this rule warns against the modification of parameter properties unless they're included in "ignorePropertyModificationsFor" or "ignorePropertyModificationsForRegex" , which is an empty array by default.

Examples of correct code for the default { "props": false } option:

Examples of incorrect code for the { "props": true } option:

Examples of correct code for the { "props": true } option with "ignorePropertyModificationsFor" set:

Examples of correct code for the { "props": true } option with "ignorePropertyModificationsForRegex" set:

When Not To Use It

If you want to allow assignment to function parameters, then you can safely disable this rule.

Further Reading

  • JavaScript: Don’t Reassign Your Function Arguments

This rule was introduced in ESLint 0.18.0.

  • Rule source
  • Documentation source

© OpenJS Foundation and other contributors Licensed under the MIT License. https://eslint.org/docs/rules/no-param-reassign

JS Tutorial

Js versions, js functions, js html dom, js browser bom, js web apis, js vs jquery, js graphics, js examples, js references, javascript function parameters.

A JavaScript function does not perform any checking on parameter values (arguments).

Function Parameters and Arguments

Earlier in this tutorial, you learned that functions can have parameters :

Function parameters are the names listed in the function definition.

Function arguments are the real values passed to (and received by) the function.

Parameter Rules

JavaScript function definitions do not specify data types for parameters.

JavaScript functions do not perform type checking on the passed arguments.

JavaScript functions do not check the number of arguments received.

Default Parameters

If a function is called with missing arguments (less than declared), the missing values are set to undefined .

Sometimes this is acceptable, but sometimes it is better to assign a default value to the parameter:

Default Parameter Values

ES6 allows function parameters to have default values.

If y is not passed or undefined, then y = 10.

Function Rest Parameter

The rest parameter (...) allows a function to treat an indefinite number of arguments as an array:

Advertisement

The Arguments Object

JavaScript functions have a built-in object called the arguments object.

The argument object contains an array of the arguments used when the function was called (invoked).

This way you can simply use a function to find (for instance) the highest value in a list of numbers:

Or create a function to sum all input values:

If a function is called with too many arguments (more than declared), these arguments can be reached using the arguments object .

Arguments are Passed by Value

The parameters, in a function call, are the function's arguments.

JavaScript arguments are passed by value : The function only gets to know the values, not the argument's locations.

If a function changes an argument's value, it does not change the parameter's original value.

Changes to arguments are not visible (reflected) outside the function.

Objects are Passed by Reference

In JavaScript, object references are values.

Because of this, objects will behave like they are passed by reference:

If a function changes an object property, it changes the original value.

Changes to object properties are visible (reflected) outside the function.

Get Certified

COLOR PICKER

colorpicker

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail: [email protected]

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail: [email protected]

Top Tutorials

Top references, top examples, get certified.

no-param-reassign

Disallows reassignment of function parameters.

Assignment to variables declared as function parameters can be misleading and lead to confusing behavior, as modifying function parameters will also mutate the arguments object. Often, assignment to function parameters is unintended and indicative of a mistake or programmer error.

This rule can be also configured to fail when function parameters are modified. Side effects on parameters can cause counter-intuitive execution flow and make errors difficult to track down.

Rule Details

This rule aims to prevent unintended behavior caused by modification or reassignment of function parameters.

Examples of incorrect code for this rule:

Examples of correct code for this rule:

This rule takes one option, an object, with a boolean property "props" , and arrays "ignorePropertyModificationsFor" and "ignorePropertyModificationsForRegex" . "props" is false by default. If "props" is set to true , this rule warns against the modification of parameter properties unless they're included in "ignorePropertyModificationsFor" or "ignorePropertyModificationsForRegex" , which is an empty array by default.

Examples of correct code for the default { "props": false } option:

Examples of incorrect code for the { "props": true } option:

Examples of correct code for the { "props": true } option with "ignorePropertyModificationsFor" set:

Examples of correct code for the { "props": true } option with "ignorePropertyModificationsForRegex" set:

When Not To Use It

If you want to allow assignment to function parameters, then you can safely disable this rule.

Further Reading

  • https://spin.atomicobject.com/2011/04/10/javascript-don-t-reassign-your-function-arguments/

This rule was introduced in ESLint 0.18.0.

  • Rule source
  • Test source
  • Documentation source
  • Skip to main content
  • Skip to search
  • Skip to select language
  • Sign up for free
  • Português (do Brasil)

Generally speaking, a function is a "subprogram" that can be called by code external (or internal, in the case of recursion) to the function. Like the program itself, a function is composed of a sequence of statements called the function body . Values can be passed to a function as parameters, and the function will return a value.

In JavaScript, functions are first-class objects , because they can be passed to other functions, returned from functions, and assigned to variables and properties. They can also have properties and methods just like any other object. What distinguishes them from other objects is that functions can be called.

For more examples and explanations, see the JavaScript guide about functions .

Description

Function values are typically instances of Function . See Function for information on properties and methods of Function objects. Callable values cause typeof to return "function" instead of "object" .

Note: Not all callable values are instanceof Function . For example, the Function.prototype object is callable but not an instance of Function . You can also manually set the prototype chain of your function so it no longer inherits from Function.prototype . However, such cases are extremely rare.

Return value

By default, if a function's execution doesn't end at a return statement, or if the return keyword doesn't have an expression after it, then the return value is undefined . The return statement allows you to return an arbitrary value from the function. One function call can only return one value, but you can simulate the effect of returning multiple values by returning an object or array and destructuring the result.

Note: Constructors called with new have a different set of logic to determine their return values.

Passing arguments

Parameters and arguments have slightly different meanings, but in MDN web docs, we often use them interchangeably. For a quick reference:

In this example, the num variable is called the function's parameter : it's declared in the parenthesis-enclosed list of the function's definition. The function expects the num parameter to be a number — although this is not enforceable in JavaScript without writing runtime validation code. In the formatNumber(2) call, the number 2 is the function's argument : it's the value that is actually passed to the function in the function call. The argument value can be accessed inside the function body through the corresponding parameter name or the arguments object.

Arguments are always passed by value and never passed by reference . This means that if a function reassigns a parameter, the value won't change outside the function. More precisely, object arguments are passed by sharing , which means if the object's properties are mutated, the change will impact the outside of the function. For example:

The this keyword refers to the object that the function is accessed on — it does not refer to the currently executing function, so you must refer to the function value by name, even within the function body.

Defining functions

Broadly speaking, JavaScript has four kinds of functions:

  • Regular function: can return anything; always runs to completion after invocation
  • Generator function: returns a Generator object; can be paused and resumed with the yield operator
  • Async function: returns a Promise ; can be paused and resumed with the await operator
  • Async generator function: returns an AsyncGenerator object; both the await and yield operators can be used

For every kind of function, there are multiple ways to define it:

function , function* , async function , async function*

Function() , GeneratorFunction() , AsyncFunction() , AsyncGeneratorFunction()

In addition, there are special syntaxes for defining arrow functions and methods , which provide more precise semantics for their usage. Classes are conceptually not functions (because they throw an error when called without new ), but they also inherit from Function.prototype and have typeof MyClass === "function" .

All syntaxes do approximately the same thing, but there are some subtle behavior differences.

  • The Function() constructor, function expression, and function declaration syntaxes create full-fledged function objects, which can be constructed with new . However, arrow functions and methods cannot be constructed. Async functions, generator functions, and async generator functions are not constructible regardless of syntax.
  • The function declaration creates functions that are hoisted . Other syntaxes do not hoist the function and the function value is only visible after the definition.
  • The arrow function and Function() constructor always create anonymous functions, which means they can't easily call themselves recursively. One way to call an arrow function recursively is by assigning it to a variable.
  • The arrow function syntax does not have access to arguments or this .
  • The Function() constructor cannot access any local variables — it only has access to the global scope.
  • The Function() constructor causes runtime compilation and is often slower than other syntaxes.

For function expressions, there is a distinction between the function name and the variable the function is assigned to. The function name cannot be changed, while the variable the function is assigned to can be reassigned. The function name can be different from the variable the function is assigned to — they have no relation to each other. The function name can be used only within the function's body. Attempting to use it outside the function's body results in an error (or gets another value, if the same name is declared elsewhere). For example:

On the other hand, the variable the function is assigned to is limited only by its scope, which is guaranteed to include the scope in which the function is declared.

A function declaration also creates a variable with the same name as the function name. Thus, unlike those defined by function expressions, functions defined by function declarations can be accessed by their name in the scope they were defined in, as well as in their own body.

A function defined by new Function will dynamically have its source assembled, which is observable when you serialize it. For example, console.log(new Function().toString()) gives:

This is the actual source used to compile the function. However, although the Function() constructor will create the function with name anonymous , this name is not added to the scope of the body. The body only ever has access to global variables. For example, the following would result in an error:

A function defined by a function expression or by a function declaration inherits the current scope. That is, the function forms a closure. On the other hand, a function defined by a Function constructor does not inherit any scope other than the global scope (which all functions inherit).

Functions defined by function expressions and function declarations are parsed only once, while a function defined by the Function constructor parses the string passed to it each and every time the constructor is called. Although a function expression creates a closure every time, the function body is not reparsed, so function expressions are still faster than new Function(...) . Therefore the Function constructor should generally be avoided whenever possible.

A function declaration may be unintentionally turned into a function expression when it appears in an expression context.

On the other hand, a function expression may also be turned into a function declaration. An expression statement cannot begin with the function or async function keywords, which is a common mistake when implementing IIFEs (Immediately Invoked Function Expressions).

Instead, start the expression statement with something else, so that the function keyword unambiguously starts a function expression. Common options include grouping and using void .

Function parameters

Each function parameter is a simple identifier that you can access in the local scope.

There are three special parameter syntaxes:

  • Default parameters allow formal parameters to be initialized with default values if no value or undefined is passed.
  • The rest parameter allows representing an indefinite number of arguments as an array.
  • Destructuring allows unpacking elements from arrays, or properties from objects, into distinct variables.

There are some consequences if one of the above non-simple parameter syntaxes is used:

  • You cannot apply "use strict" to the function body — this causes a syntax error .
  • Even if the function is not in strict mode , certain strict mode function features apply, including that the arguments object stops syncing with the named parameters, arguments.callee throws an error when accessed, and duplicate parameter names are not allowed.

The arguments object

You can refer to a function's arguments within the function by using the arguments object.

An array-like object containing the arguments passed to the currently executing function.

The currently executing function.

The number of arguments passed to the function.

Getter and setter functions

You can define accessor properties on any standard built-in object or user-defined object that supports the addition of new properties. Within object literals and classes , you can use special syntaxes to define the getter and setter of an accessor property.

Binds an object property to a function that will be called when that property is looked up.

Binds an object property to a function to be called when there is an attempt to set that property.

Note that these syntaxes create an object property , not a method . The getter and setter functions themselves can only be accessed using reflective APIs such as Object.getOwnPropertyDescriptor() .

Block-level functions

In strict mode , functions inside blocks are scoped to that block. Prior to ES2015, block-level functions were forbidden in strict mode.

Block-level functions in non-strict code

In a word: Don't.

In non-strict code, function declarations inside blocks behave strangely. For example:

The semantics of this in strict mode are well-specified — zero only ever exists within that scope of the if block. If shouldDefineZero is false, then zero should never be defined, since the block never executes. However, historically, this was left unspecified, so different browsers implemented it differently in non-strict mode. For more information, see the function declaration reference.

A safer way to define functions conditionally is to assign a function expression to a variable:

Returning a formatted number

The following function returns a string containing the formatted representation of a number padded with leading zeros.

The following statements call the padZeros function.

Determining whether a function exists

You can determine whether a function exists by using the typeof operator. In the following example, a test is performed to determine if the window object has a property called noFunc that is a function. If so, it is used; otherwise, some other action is taken.

Note that in the if test, a reference to noFunc is used — there are no parentheses () after the function name so the actual function is not called.

Specifications

Specification

Function expressions

In JavaScript, a function is not a “magical language structure”, but a special kind of value.

The syntax that we used before is called a Function Declaration :

There is another syntax for creating a function that is called a Function Expression .

It allows us to create a new function in the middle of any expression.

For example:

Here we can see a variable sayHi getting a value, the new function, created as function() { alert("Hello"); } .

As the function creation happens in the context of the assignment expression (to the right side of = ), this is a Function Expression .

Please note, there’s no name after the function keyword. Omitting a name is allowed for Function Expressions.

Here we immediately assign it to the variable, so the meaning of these code samples is the same: "create a function and put it into the variable sayHi ".

In more advanced situations, that we’ll come across later, a function may be created and immediately called or scheduled for a later execution, not stored anywhere, thus remaining anonymous.

Function is a value

Let’s reiterate: no matter how the function is created, a function is a value. Both examples above store a function in the sayHi variable.

We can even print out that value using alert :

Please note that the last line does not run the function, because there are no parentheses after sayHi . There are programming languages where any mention of a function name causes its execution, but JavaScript is not like that.

In JavaScript, a function is a value, so we can deal with it as a value. The code above shows its string representation, which is the source code.

Surely, a function is a special value, in the sense that we can call it like sayHi() .

But it’s still a value. So we can work with it like with other kinds of values.

We can copy a function to another variable:

Here’s what happens above in detail:

  • The Function Declaration (1) creates the function and puts it into the variable named sayHi .
  • Line (2) copies it into the variable func . Please note again: there are no parentheses after sayHi . If there were, then func = sayHi() would write the result of the call sayHi() into func , not the function sayHi itself.
  • Now the function can be called as both sayHi() and func() .

We could also have used a Function Expression to declare sayHi , in the first line:

Everything would work the same.

You might wonder, why do Function Expressions have a semicolon ; at the end, but Function Declarations do not:

The answer is simple: a Function Expression is created here as function(…) {…} inside the assignment statement: let sayHi = …; . The semicolon ; is recommended at the end of the statement, it’s not a part of the function syntax.

The semicolon would be there for a simpler assignment, such as let sayHi = 5; , and it’s also there for a function assignment.

Callback functions

Let’s look at more examples of passing functions as values and using function expressions.

We’ll write a function ask(question, yes, no) with three parameters:

The function should ask the question and, depending on the user’s answer, call yes() or no() :

In practice, such functions are quite useful. The major difference between a real-life ask and the example above is that real-life functions use more complex ways to interact with the user than a simple confirm . In the browser, such functions usually draw a nice-looking question window. But that’s another story.

The arguments showOk and showCancel of ask are called callback functions or just callbacks .

The idea is that we pass a function and expect it to be “called back” later if necessary. In our case, showOk becomes the callback for “yes” answer, and showCancel for “no” answer.

We can use Function Expressions to write an equivalent, shorter function:

Here, functions are declared right inside the ask(...) call. They have no name, and so are called anonymous . Such functions are not accessible outside of ask (because they are not assigned to variables), but that’s just what we want here.

Such code appears in our scripts very naturally, it’s in the spirit of JavaScript.

Regular values like strings or numbers represent the data .

A function can be perceived as an action .

We can pass it between variables and run when we want.

Function Expression vs Function Declaration

Let’s formulate the key differences between Function Declarations and Expressions.

First, the syntax: how to differentiate between them in the code.

Function Declaration: a function, declared as a separate statement, in the main code flow:

Function Expression: a function, created inside an expression or inside another syntax construct. Here, the function is created on the right side of the “assignment expression” = :

The more subtle difference is when a function is created by the JavaScript engine.

A Function Expression is created when the execution reaches it and is usable only from that moment.

Once the execution flow passes to the right side of the assignment let sum = function… – here we go, the function is created and can be used (assigned, called, etc. ) from now on.

Function Declarations are different.

A Function Declaration can be called earlier than it is defined.

For example, a global Function Declaration is visible in the whole script, no matter where it is.

That’s due to internal algorithms. When JavaScript prepares to run the script, it first looks for global Function Declarations in it and creates the functions. We can think of it as an “initialization stage”.

And after all Function Declarations are processed, the code is executed. So it has access to these functions.

For example, this works:

The Function Declaration sayHi is created when JavaScript is preparing to start the script and is visible everywhere in it.

…If it were a Function Expression, then it wouldn’t work:

Function Expressions are created when the execution reaches them. That would happen only in the line (*) . Too late.

Another special feature of Function Declarations is their block scope.

In strict mode, when a Function Declaration is within a code block, it’s visible everywhere inside that block. But not outside of it.

For instance, let’s imagine that we need to declare a function welcome() depending on the age variable that we get during runtime. And then we plan to use it some time later.

If we use Function Declaration, it won’t work as intended:

That’s because a Function Declaration is only visible inside the code block in which it resides.

Here’s another example:

What can we do to make welcome visible outside of if ?

The correct approach would be to use a Function Expression and assign welcome to the variable that is declared outside of if and has the proper visibility.

This code works as intended:

Or we could simplify it even further using a question mark operator ? :

As a rule of thumb, when we need to declare a function, the first thing to consider is Function Declaration syntax. It gives more freedom in how to organize our code, because we can call such functions before they are declared.

That’s also better for readability, as it’s easier to look up function f(…) {…} in the code than let f = function(…) {…}; . Function Declarations are more “eye-catching”.

…But if a Function Declaration does not suit us for some reason, or we need a conditional declaration (we’ve just seen an example), then Function Expression should be used.

  • Functions are values. They can be assigned, copied or declared in any place of the code.
  • If the function is declared as a separate statement in the main code flow, that’s called a “Function Declaration”.
  • If the function is created as a part of an expression, it’s called a “Function Expression”.
  • Function Declarations are processed before the code block is executed. They are visible everywhere in the block.
  • Function Expressions are created when the execution flow reaches them.

In most cases when we need to declare a function, a Function Declaration is preferable, because it is visible prior to the declaration itself. That gives us more flexibility in code organization, and is usually more readable.

So we should use a Function Expression only when a Function Declaration is not fit for the task. We’ve seen a couple of examples of that in this chapter, and will see more in the future.

Lesson navigation

  • © 2007—2024  Ilya Kantor
  • about the project
  • terms of usage
  • privacy policy

Navigation Menu

Search code, repositories, users, issues, pull requests..., provide feedback.

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly.

To see all available qualifiers, see our documentation .

  • Notifications You must be signed in to change notification settings

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why assignment to property of function parameter is bad style. #1217

@zhaoxiongfei

zhaoxiongfei commented Dec 21, 2016 • edited Loading

req, res, next) => { req.user = Guest; return next(); };

Often used, can not be avoided.
How should I do?

  • 👍 4 reactions

@ljharb

ljharb commented Dec 21, 2016

Since express does require this, you currently can only disable the rule entirely, on a per-file basis, or on a per-line/per-function basis.

eslint has an option proposed to cover this:

Once that's enabled, we'll likely enable it by default to cover , , and .

  • 👍 1 reaction

Sorry, something went wrong.

@ljharb

zhaoxiongfei commented Dec 27, 2016

Thank you sir.

@zhaoxiongfei

ljharb commented Dec 27, 2016

(the question's answered, but reopening to track the eslint rule change)

@felixsanz

felixsanz commented Dec 30, 2016 • edited Loading

You are not reassigning the parameter, you are just creating a property on the object.

Because of this, you can allow it today with .

ljharb commented Dec 30, 2016

Yes, but is something that should be strictly enforced everywhere, where a framework requires it, like express. The rule change would be for , but with exceptions for , etc.

  • 👍 3 reactions
  • 👎 1 reaction

@christianbundy

christianbundy commented Mar 2, 2017

Just a quick update, this has been merged and will be released in the next version of ESLint (which I believe is tomorrow):

@christianbundy

shanev commented Mar 7, 2017

Another example is in Koa routing:

.get('/', (ctx) => { ctx.status = 200; });
  • 👍 5 reactions

ljharb commented Mar 16, 2017

The next release of eslint-config-airbnb-base, and likely eslint-config-airbnb, will include this loosening of no-param-reassign.

  • 🎉 5 reactions

@jbruni

jbruni commented Nov 7, 2017

as " " is ok.

as " " means enforces immutability paradigm. It makes a profound design choice for us.

ljharb commented Nov 7, 2017

Airbnb's config makes many profound design choices for you; that's the point. If you don't agree with them, you can easily override rules and/or fork the guide.

@kholiavko-roman

kholiavko-roman commented Feb 14, 2019 • edited Loading

Guys does anybody knows how to set up eslit for showing error if I modify value from param array ?
Here is example:

checkIsValid = (id, array) => { for (let i = 0; i < array.length; i++) { const item = array[i]; if (item.param) { item.value = null; item.payment = null; } } return array; };

ljharb commented Feb 14, 2019

that’s pushing the limits of static analysis; you may want to try eslint-plugin-immutable, but it’s not very reliable due to the way the language works.

@aboyton

aboyton commented Feb 15, 2019

Or try TypeScript and something like .

kholiavko-roman commented Feb 15, 2019

Thanks for reply. I think I will try eslint-plugin-immutable for the first.

@makevoid

Successfully merging a pull request may close this issue.

@shanev

  • Language Reference

Function arguments

Information may be passed to functions via the argument list, which is a comma-delimited list of expressions. The arguments are evaluated from left to right, before the function is actually called ( eager evaluation).

PHP supports passing arguments by value (the default), passing by reference , and default argument values . Variable-length argument lists and Named Arguments are also supported.

Example #1 Passing arrays to functions

As of PHP 8.0.0, the list of function arguments may include a trailing comma, which will be ignored. That is particularly useful in cases where the list of arguments is long or contains long variable names, making it convenient to list arguments vertically.

Example #2 Function Argument List with trailing Comma

Passing arguments by reference

By default, function arguments are passed by value (so that if the value of the argument within the function is changed, it does not get changed outside of the function). To allow a function to modify its arguments, they must be passed by reference.

To have an argument to a function always passed by reference, prepend an ampersand (&) to the argument name in the function definition:

Example #3 Passing function parameters by reference

It is an error to pass a value as argument which is supposed to be passed by reference.

Default argument values

A function may define default values for arguments using syntax similar to assigning a variable. The default is used only when the parameter is not specified; in particular, note that passing null does not assign the default value.

Example #4 Use of default parameters in functions

The above example will output:

Default parameter values may be scalar values, array s, the special type null , and as of PHP 8.1.0, objects using the new ClassName() syntax.

Example #5 Using non-scalar types as default values

Example #6 Using objects as default values (as of PHP 8.1.0)

The default value must be a constant expression, not (for example) a variable, a class member or a function call.

Note that any optional arguments should be specified after any required arguments, otherwise they cannot be omitted from calls. Consider the following example:

Example #7 Incorrect usage of default function arguments

Now, compare the above with this:

Example #8 Correct usage of default function arguments

As of PHP 8.0.0, named arguments can be used to skip over multiple optional parameters.

Example #9 Correct usage of default function arguments

Example #10 Declaring optional arguments after mandatory arguments

Note : As of PHP 7.1.0, omitting a parameter which does not specify a default throws an ArgumentCountError ; in previous versions it raised a Warning.
Note : Arguments that are passed by reference may have a default value.

Variable-length argument lists

PHP has support for variable-length argument lists in user-defined functions by using the ... token.

Example #11 Using ... to access variable arguments

Example #12 Using ... to provide arguments

You may specify normal positional arguments before the ... token. In this case, only the trailing arguments that don't match a positional argument will be added to the array generated by ... .

Example #13 Type declared variable arguments

Finally, variable arguments can also be passed by reference by prefixing the ... with an ampersand ( & ).

Named Arguments

PHP 8.0.0 introduced named arguments as an extension of the existing positional parameters. Named arguments allow passing arguments to a function based on the parameter name, rather than the parameter position. This makes the meaning of the argument self-documenting, makes the arguments order-independent and allows skipping default values arbitrarily.

Named arguments are passed by prefixing the value with the parameter name followed by a colon. Using reserved keywords as parameter names is allowed. The parameter name must be an identifier, specifying dynamically is not allowed.

Example #14 Named argument syntax

Example #15 Positional arguments versus named arguments

The order in which the named arguments are passed does not matter.

Example #16 Same example as above with a different order of parameters

Named arguments can be combined with positional arguments. In this case, the named arguments must come after the positional arguments. It is also possible to specify only some of the optional arguments of a function, regardless of their order.

Example #17 Combining named arguments with positional arguments

Passing the same parameter multiple times results in an Error exception.

Example #18 Error thrown when passing the same parameter multiple times

As of PHP 8.1.0, it is possible to use named arguments after unpacking the arguments. A named argument must not override an already unpacked argument.

Example #19 Use named arguments after unpacking

Improve This Page

User contributed notes 15 notes.

To Top

Inspectopedia Help

Assignment could be replaced with operator assignment.

Reports an assignment operation that can be replaced by an operator assignment to make your code shorter and probably clearer.

x = x + 3; x = x / 3;

After the quick fix is applied the result looks like:

x += 3; x /= 3;

Locating this inspection

Can be used to locate inspection in e.g. Qodana configuration files , where you can quickly enable or disable it, or adjust its settings.

Path to the inspection settings via IntelliJ Platform IDE Settings dialog, when you need to adjust inspection settings directly from your IDE.

Settings or Preferences | Editor | Inspections | JavaScript and TypeScript | Assignment issues

Inspection Details

By default bundled with:

, , , , , , , , , , , , ,

Can be installed with plugin:

JavaScript and TypeScript, 242.22907

Thank you for visiting nature.com. You are using a browser version with limited support for CSS. To obtain the best experience, we recommend you use a more up to date browser (or turn off compatibility mode in Internet Explorer). In the meantime, to ensure continued support, we are displaying the site without styles and JavaScript.

  • View all journals
  • Explore content
  • About the journal
  • Publish with us
  • Sign up for alerts
  • Open access
  • Published: 13 September 2024

A method for compressing AIS trajectory based on the adaptive core threshold difference Douglas–Peucker algorithm

  • Ting Zhang 1 , 2   na1 ,
  • Zhiming Wang 1   na1 &
  • Peiliang Wang 1 , 3  

Scientific Reports volume  14 , Article number:  21408 ( 2024 ) Cite this article

Metrics details

  • Computer science
  • Mathematics and computing
  • Ocean sciences
  • Scientific data

Traditional trajectory compression algorithms, such as the siliding window (SW) algorithm and the Douglas–Peucker (DP) algorithm, typically use static thresholds based on fixed parameters like ship dimensions or predetermined distances, which limits their adaptive capabilities. In this paper, the adaptive core threshold difference-DP (ACTD-DP) algorithm is proposed based on traditional DP algorithm. Firstly, according to the course value of automatic identification system (AIS) data, the original trajectory data is preprocessed and some redundant points are discarded. Then the number of compressed trajectory points corresponding to different thresholds is quantified. The function relationship between them is established by curve fitting method. The characteristics of the function curve are analyzed, and the core threshold and core threshold difference are solved. Finally, the compression factor is introduced to determine the optimal core threshold difference, which is the key parameter to control the accuracy and efficiency of the algorithm. Five different algorithms are used to compress the all ship trajectories in the experimental water area. The average compression ratio (ACR) of the ACTD-DP algorithm is 87.53%, the average length loss ratio (ALLR) is 23.20%, the AMSED (mean synchronous Euclidean distance of all trajectories) is 68.9747 mx, and the TIME is 25.6869 s. Compared with the other four algorithms, the ACTD-DP algorithm shows that the algorithm can not only achieve high compression ratio, but also maintain the integrity of trajectory shape. At the same time, the compression results of four different trajectories show that ACTD-DP algorithm has good robustness and applicability. Therefore, ACTD-DP algorithm has the best compression effect.

Introduction

With the deepening of global economic integration, the maritime industry’s role within the global economic system has become increasingly pivotal. The density of ship traffic in coastal ports, estuarial jetties, and other water areas continues to rise. The complex navigational environment presents novel challenges to maritime traffic supervision authorities and staff 1 , 2 . As an important carrier of ship motion information, AIS facilitates ship supervision and management. In accordance with the requirements of the SOLAS (International Convention for the Safety of Life at Sea), an increasing number of ships are mandated to be equipped with AIS devices to mitigate the risk of maritime collisions 3 .

The massive AIS data information provides significant support for research across various domains, including studies on ship behavior patterns 4 , 5 , maritime route planning 6 , 7 , and navigation safety 8 , 9 , 10 . However, the raw AIS data contains a plethora of redundant information, which can adversely affect the processing time of ship trajectories 11 .Therefore, studies on the characteristic direction of ship trajectory all need to compress AIS data, such as ship navigation prediction 12 and ship abnormal behavior detection 13 , 14 .

Compression algorithms commonly used for AIS data can be categorized into offline and online approaches. Offline compression algorithms include the Douglas–Peucker (DP) algorithm 15 and the TD-TR (top–down time ratio)algorithm 16 etc., while online compression algorithms encompass the Sliding Window (SW) algorithm 17 and the opening window time ratio (OPW-TR) algorithm 18 etc. Among these, the selection of the threshold value is most critical when utilizing algorithms such as DP and SW for the compression of AIS data. The literature 19 synthesized the ship’s course deviation, position deviation and the spatiotemporal characteristics of AIS data to set the threshold value of SW algorithm. This approach facilitates the extraction of key feature points from the ship trajectory, thereby ship trajectory data is compressed. But the choice of distance and angle thresholds needs to be analyzed according to the experimental waters and the type of vessel, the distance threshold in paper was set as [0.731, 1.274] times the ship width, and the Angle threshold was set as [ \(\hbox {3.8}^{\circ }\) , \(\hbox {5.0}^{\circ }\) ]. The literature 20 enhanced the traditional SW algorithm by combining speed values varied significantly. The threshold was dynamically adjusted to reduce the scale deviation caused by the speed difference. Consequently, it more effectively preserved the shape characteristics of the ship trajectory. However, this method is more suitable for trajectories with obvious velocity changes, and the improvement effect may not be as good as expected for trajectories with little velocity changes or simple motion modes. The literature 21 initialized and dynamically adjusted the threshold of DP algorithm to proportion value of the ship’s length, based on the characteristics of ship trajectory.The literature statistically analyzed the relative azimuth differences between trajectory points to identify and order the features points, thereby yielded the final compressed trajectory. The literature uses the parameter self-selection method for the Silhouette Coefficient scores, but the determination of the optimal parameter combination will require extensive experiments and adjustments.Based on the traditional DP algorithm, the literature 22 used the minimum ship domain evaluation method to optimize the threshold setting method, and combined the ship parameters and maneuverability to set the threshold to 0.8 times the ship length. However, the selection of threshold value is based on the empirical method, and the generalization ability of the method is insufficient. Based on the traditional DP algorithm and SW algorithm, literature 23 combined with the space and motion characteristics of the trajectory, applied statistical theory to determine the algorithm threshold for compression. The paper recommended that the distance threshold value for DP algorithm was 0.8 times the ship length and the threshold coefficient of SW algorithm was 1.6.The threshold value in the literature is a fixed value and cannot provide an adaptive adjustment mechanism. The author 24 compressed ship trajectory using DP algorithm, and a novel metric known as ACS(Average Compression Score) was introduced as an evaluative criterion. But the choice of the most threshold is still based on experience, especially the determination of the optimal ACS value. The distance threshold of DP algorithm was set 0.87 nautical miles, the ACS reaches the optimal value of 0.1472, and the compression rate can reach 92.59%. The literature 25 , aiming to facilitate the rapid display of AIS trajectories on ECDIS (Electronic Chart Display and Information System), has utilized DP algorithm for compressing ship trajectory on nautical charts of varying scales. However, the threshold value is obtained based on the test of the research water area, and the generalization ability is weak. The results show that the recommended threshold range was [10,20] meters and the compression ratio was [94%,97%] for charts (scale 1:100,000 to 1:2990,000), while the recommended threshold was 20 meters and the compression ratio was 97% for charts (scale 1:3,000,000). The literature 26 introduced the ADPS (Adaptive Douglas–Peucker with Speed) algorithm, which combined trajectory characteristics, the rate of change of ship speed, and the distances between feature points to automatically calculate and set thresholds suitable for each trajectory. This approach ensured the retention of key features and pertinent information while the trajectory was compressed. However, the performance of the algorithm still depends on the initial setting of some parameters, such as the method of determining the baseline. The literature 27 used DP algorithm with distinct distance thresholds to compress the upbound and down-bound trajectories respectively. The DTW (Dynamic Time Warping) algorithm was used to evaluate the compression effect and solved the optimal compression threshold. However, the threshold determined by this method depends on the set of threshold values, so it is easy to fall into the local optimal value. The literature 28 proposed the MPDP (Multi-Objective Peak Douglas-Peucker) algorithm, which adopted a peak sampling strategy. The three optimization objectives of the trajectory, spatial characteristics, course, and speed, were considered. Additionally, the obstacle detection mechanism was added, aiming to achieve a compression algorithm more suited for curved trajectories. However, the threshold of this method is still a fixed value and lacks adaptability. The literature 29 proposed the PDP(Partition Douglas-Peucker) algorithm, which partitioned ship trajectory shapes and employs dynamic threshold settings to enhance the efficiency and accuracy of trajectory compression. This approach has successfully reduced the time required for compression and minimized data loss. However, the dynamic threshold determination within the PDP algorithm is still anchored to the ship’s length, which limits its adaptiveness. The literature 30 proposed the ADP(Adaptive-threshold Douglas-Peucker) algorithm, which makes the threshold setting more flexible and accurate, and improves the computational efficiency of the algorithm by using matrix operations. However, when the cyclic ship trajectory was compressed by the ADP algorithm, the critical point information was lost more. At the same time, the complexity of ADP algorithm was higher to increase the calculation time and storage cost.

Summarizing the aforementioned research, the selection methods for threshold values in compressing ship trajectories based on DP and SW algorithms are primarily based on expert experience or trial-and-error approaches. The subjective of expert experience method is high, necessitating multiple iterations and experiments to ascertain the threshold values, resulting in low work efficiency. The thresholds set by the trial-and-error method are mostly based on the ship field or the ship static information, such as length and width, which are limited by the sailing waters and ship types. Furthermore, erroneous information within massive AIS datasets can also impact the setting of thresholds, thereby the compression effect can be diminished.

To overcome the deficiencies and limitations of DP algorithm in threshold setting, which is often based on expert experience or trial-and-error approaches, this paper proposes the ACTD-DP (Adaptive Threshold Difference -DP) algorithm. The ACTD-DP algorithm effectively reduces the reliance on experience or static ship information for threshold determination, demonstrating good applicability. Moreover, the ACTD-DP algorithm is suitable for compressing trajectory data of different types of water area and ship types, exhibiting strong robustness.

The remainder of this paper is organized as follows. In “ Methods ”, the traditional DP algorithm , relevant definitions and evaluation metrics are introduced, while the logic and flow of ACTD-DP algorithm are introduced. In “ Experiment and analysis ”, the experimental results of different algorithms are compared and analyzed in the selected research area. In “ Discussion and conclusion ”, this paper is discussed and summarized , and the directions of future research are outlined.

Traditional DP algorithm

The DP algorithm, initially introduced by Douglas and Peucker in 1973 31 , is predicated on the concept of “straightening the curve” by approximating a curve with a series of points and reducing the number of points, which is commonly utilized for simplifying the motion trajectories of objects.

Assuming a curve is constituted by a set of points { \(P_{1},P_{2},P_{3},P_{4},P_{5},P_{6}\) } as shown in Fig. 1 a, with a given threshold . The compression process of the DP algorithm is proceeds as follows:

(1) Connect the beginning and end of the curve \(P_{1}\) - \(P_{6}\) as the baseline line (dashed line in Fig. 1 a), calculate the vertical distance between the remaining points and the reference line, and obtain the maximum distance value \( d_{max1} \) and corresponding points \(P_{4}\) .

(2) If \(d_{max1}< \varepsilon \) , all the intermediate points are removed, and the curve point set is compressed as \(\left\{ P_{1}, P_{6} \right\} \) ; otherwise, save \(P_{4} \) as the key point, and divide the curve into two sub-curve point sets: \(\left\{ P_{1}, P_{2}, P_{3}, P_{4} \right\} \) and \(\left\{ P_{4}, P_{5}, P_{6} \right\} \) , as shown in Fig. 1 b. The reference lines are \(P_{1}\) - \(P_{4}\) and \(P_{4}\) - \(P_{6}\) respectively.

(3) Repeat steps (1) and (2) for the above two sub-curves respectively, as shown in Fig. 1 b, c. Finally, the compression curve is \(\left\{ P_{1}, P_{2}, P_{4}, P_{6} \right\} \) , as shown in Fig. 1 d.

figure 1

DP algorithm.

Relevant definition of trajectory compression

Ship trajectory is similar the curve shown in Fig. 1 , thus by setting an appropriate threshold, the DP algorithm can detect and retain the critical points, discard non-critical points within the ship’s trajectory. During compressing the curve by DP algorithm, distances and thresholds are calculated based on the Cartesian coordinate system. However, ship trajectory point data are typically based on the geographic coordinate system, where the calculation of spherical distances is more complex, particularly when determining the distance between a trajectory point and a line.

Consequently, prior to the compression of ship trajectories by DP algorithm, a transformation from the geographic coordinate system to the Mercator projection coordinate system is required to facilitate the calculation of distance values, which is called projection.

\(\left( \lambda ,\varphi \right) \) denote the longitude and latitude value of the trajectory point in the geographical coordinate system, and \(\left( x,y \right) \) represents the coordinate value projected in the Mercator coordinate system. The conversion formula is as follows:

where, R represents the parallel circle radius of standard latitude; \(\delta \) represents the long radius of the earth’s ellipsoid; \(\varphi _{0} \) represents the standard latitude in the Mercator projection; e represents the first eccentricity of the earth ellipsoid; q represents isometric latitude.

Algorithm performance evaluation metrics

As shown in Fig. 2 , let \(Tra_{org}=\left\{ P_{1},P_{2},\cdots ,P_{n} \right\} \) be the original ship trajectory, \(Tra_{cmp}=\left\{ P_{1},P_{n} \right\} \) , and n be the compressed trajectory and n be the number of trajectory points. Each trajectory point encompasses two fundamental attributes: coordinate values and a timestamp, that is, \(P_{i}=\left\{ x_{i},y_{i},t_{i} \right\} \) .

figure 2

Trajectory compression diagram.

Definition 1

SED (synchronous euclidean distance). SED is generally used to evaluate the effectiveness of compression. SED denotes the Euclidian distance between the point P1 in the original trajectory \(Tra_{org}\) and the corresponding position \(P_{syn} \) in the compressed trajectory \(Tra_{cmp}\) , calculated in proportion to time. \(P_{ped} \) is the foot of \(P_{i} \) on the compression trajectory, \(P_{i}P_{ped} \) length is the vertical Euclidean distance corresponding to \(P_{i} \) , and \(P_{i}P_{syn} \) length is the corresponding to \(P_{i} \) . \(P_{syn} \left( x_{syn},y_{syn} \right) \) coordinates of trajectory points and corresponding SED formulas are as follows:

The mean SED of a single trajectory is denoted as MSED and the mean SED of all trajectories is expressed as AMSED. The formula is as follows:

where, N represents the number of all trajectories.

MSED represents the location discrepancy between the original trajectory and the compressed trajectory, and the smaller the value, the smaller the discrepancy, the smaller the trajectory distortion, and the higher the integrity of the trajectory shape.

Definition 2

CR (compression ratio). CR is the ratio of the number of points discarded during the compression process to the total number of points in the original trajectory. When only the CR is considered, the higher the CR, the better the compression effect of the compression algorithm. The formula is as follows:

ACR (average compression ratio) denotes the average compression ratio of all trajectories. The formula is as follows:

The CR indicates the compression degree of the algorithm on the trajectory. The larger the value, the higher the compression degree of the trajectory, and the simpler the compression trajectory obtained.

LLR (length loss ratio). LLR is the ratio of the reduced length of the compressed trajectory to the length of the original track. The formula is as follows:

where, \(Len_{org}\) represents the length of the original trajectory; \(Len_{cmp}\) represents the length of the compressed trajectory.

ALLR (average length loss ratio) denotes to the mean LLR of all trajectories. The formula is as follows:

The LLR denotes the degree of loss on the track length. The larger the value, the more length information is lost during the compression process, and the greater the probability of deviation of some track features.

Define 4 TIME

TIME is the total time taken by the algorithm to compress all trajectories in the current research area.

  • ACTD-DP algorithm

The purpose of trajectory compression is to reduce the number of trajectory points while maintaining the integrity of the trajectory’s shape, thereby enhancing the velocity of trajectory display and processing. The goal is to achieve an optimal balance between the quantity and the quality of the trajectory points. The compression quality of DP algorithm is predominantly determined by the threshold value. The larger the threshold value, the higher the compression rate and the larger the trajectory distortion; the smaller the threshold value, the lower the compression rate and the smaller the trajectory distortion.

Traditional DP algorithms and the aforementioned studies in references 22 , 23 , 24 , 25 set threshold values based on static information such as ship length, ship width, and fixed distance values, which diminishes the algorithm’s adaptive capacity. The ACTD-DP algorithm is proposed, as depicted in Fig. 6 , drawing on the conceptual frameworks of the PDP algorithm 29 and the APD algorithm 30 . The ACTD-DP algorithm employs an adaptive threshold difference approach, aiming to diminish reliance on static information. Initially, the original trajectory data is preprocessed using the course attribute from AIS data, the certain trajectory points are discarded. Subsequently, a curve fitting method is used to establish a functional relationship between the threshold and the number of trajectory points. The characteristics of the function curve are then analyzed to determine the core threshold and the core threshold difference. Finally, the compression factor is introduced to ascertain the optimal threshold difference, which serves as the key parameter to control the accuracy and efficiency of the algorithm. In comparison with the PDP and ADP algorithms, the ACTD-DP algorithm is capable of achieving a higher compression rate while maintaining the integrity of the trajectory shape. Additionally, the ACTD-DP algorithm demonstrates adaptability across various maritime environments and ship types.

Preprocessing trajectory

Compared with the traditional DP algorithm, ACTD-DP algorithm needs to solve the optimal core threshold difference, which may increase the algorithm’s execution time. To reduce the time consuming of the ACTD-DP algorithm, this paper processes the data and eliminate the noise data, drift data and other outliers in the data. After that, following the approach in reference 17 , this paper preprocesses the data based on the course differences between original trajectory points to reduce the number of trajectory points. The trajectory preprocessing method is as follows:

Let \(Tra_{org}\) be the original trajectory (Fig. 2 ) and \(\theta _{th} \) be the course change threshold . Then \(\left\{ P_{1},P_{n} \right\} \) is saved in the preprocessing trajectory.

Iteratively calculate the course difference between adjacent trajectory points as \(\Delta \theta \) . If \(\Delta \theta > \theta _{th} \) , the point is saved to middle \(Tra_{pre}\) ; Otherwise, the point is discarded.

To ensure data integrity, if the number of points discarded between adjacent two points in \(Tra_{pre}\) is higher than that of \(\Delta n\) (the general value is \(\left[ 10,30\right] \) ), trajectory points are selected from \(Tra_{org}\) in equal proportion with equal proportional interpolation and saved to \(Tra_{pre}\) .

The DR (discard ratio) is the ratio of the number of points discarded during the preprocessing of the trajectory to the total number of points in the original trajectory. Based on the experimental AIS data (as described in “Description of experimental data”), the relationship between DR and AMSED values with respect to threshold \(\theta _{th} \) is depicted in Fig. 3 . When threshold \(\theta _{th} < \hbox {10}^{\circ } \) is set, both DR and AMSED exhibit more pronounced changes. At threshold \(\theta _{th} = \hbox {1}^{\circ } \) , DR is 42.89% and AMSED is 8.5372 m. When threshold \(\theta _{th} = \hbox {10}^{\circ } \) is used, DR increases to 72.30% and AMSED to 17.30 m. At threshold \(\theta _{th} > \hbox {10}^{\circ } \) , the variation in DR is relatively minor. Compared to the data in Table 5 , the AMSED values presented in Fig. 3 are consistently lower, indicating minimal distortion of the trajectory and a minor impact on the trajectory’s shape features due to the discarded points. Consequently, the threshold \(\theta _{th} = \hbox {10}^{\circ } \) and the number of points \(\Delta n=10\) are selected for further analysis.

figure 3

DR and AMSED values with respect to threshold \(\theta _{th} \) .

Fitting thresholds-points function

The threshold of trajectory compression algorithms based on DP algorithm is directly correlated with the number of points in the compressed trajectory, which subsequently affects the quality of the compressed trajectory. To quantify this relationship between the threshold values and the number of trajectory points for the ACTD-DP algorithm, this paper , based on the experimental AIS data(as detailed in “Description of experimental data”), presents a statistical analysis of the total number of compression trajectory points across a threshold range of [0.01, 10] times the ship’s length, as depicted in Fig. 4 a. Statistical analysis demonstrates a nonlinear negative correlation between threshold values and the count of trajectory points. Initially, when the threshold is smaller, there is a significant and rapid decrease in the number of trajectory points. Subsequently, with an increase in the threshold, the rate of reduction in trajectory points attenuates, and in certain regions, there may be observed slight oscillations or a tendency towards rebound.

According to the curve (Fig. 4 a) analysis, the functional relationship between the thresholds and the number of trajectory points may conform to the characteristics of power function and exponential function. Therefore, the fitting function equations can be assumed to be:

where, \(\omega _{i}\left( i=1,2\ldots 6 \right) \) represents the equation parameters.

Then, The equations are solved according to the statistical data, and the parameter values are obtained as shown in Table 1 . The fitting function curves were shown in Fig. 4 b.

figure 4

Thresholds-points function fitting. ( a ) Thresholds-points statistics and ( b ) the fitting function curves.

Finally, the determination coefficient is selected as the Goodness of Fit for the two functions. The determination coefficient, as \(R^2\) , is the description of the degree of variation of the function independent variable and dependent variable, and it is an essential metric for assessing the fit of a regression equation. The formula for its calculation is as follows:

where, \(S_{r}\) represents residual sum of squares; \(S_{t}\) represents total sum of squares; \(y_{i}\) represents the actual value; \(\widehat{y_{i} }\) represents the fitting curve value; \(\overline{y}\) represents the average value.

The determination coefficients for Eq. ( 8 ), \(R^2=0.9872\) , and for Eq. ( 9 ), \(R^2=0.9589\) , indicate that the values derived from Eq. ( 8 ) are closely aligned with the actual data, signifying a higher degree of fit for the curve equation and greater applicability. Consequently, the power function, the thresholds-points function, is selected to represent the functional relationship between the threshold and the number of trajectory points.

Optimal core threshold difference calculating

After the thresholds-points function has been established, the further analysis of the function curve characteristics is necessitated. This is essential for evaluating the compression effectiveness during the trajectory compression process. It is imperative to establish an intrinsic link between the curve and the ACTD-DP algorithm. Additionally, the role of thresholds or differences therein within the algorithm must be explicitly defined.

When the ACTD-DP algorithm compresses the trajectory, the maximum distance of all trajectory points to the baseline (similar to that depicted in Fig. 1 ) within each compressed trajectory segment is calculated. This maximum distance value is hypothesized as the core threshold for that trajectory segment, denoted as .The difference in core thresholds obtained from two consecutive compressions is denoted as the core threshold difference. The formula is as follows:

where, \(\Delta \varepsilon _{k}\) represents the core threshold difference at the second compression; \(\varepsilon _{core}^{k}\) represents the core threshold obtained during the second compression; k represents the compression order.

During the trajectory compression process, the overall trend of the core threshold difference is a gradual decrease (as shown in Fig. 5 a). When \(\Delta \varepsilon _{k} < \Delta \varepsilon _{o} \le \Delta \varepsilon _{k-i} \left( i=1,2\ldots ,k-1 \right) \) is true, it indicates that the change trend of core threshold difference tends to be stable, the trajectory shape changes little, and the trajectory compression ratio also tends to be stable. At this point, \(\Delta \varepsilon _{o} \) is identified as the optimal core threshold difference, achieving the best balance betweenbetween the quantity and the quality of the trajectory points, signifying the completion of trajectory compression. Therefore, the process of balancing between the quantity and the quality of the trajectory points is the process of searching the optimal core threshold difference.

Combined with the curve (Fig. 4 a) analysis of Equation ( 8 ), the core threshold difference corresponds to the derivative of the fitted curve (Fig. 5 a). Consequently, the optimal core threshold difference can be calculated based on the angle difference between two points on the fitting curve (as illustrated in Fig. 5 b), where the core threshold difference at the position of the maximum angle difference of the fitting curve is identified as the optimal core threshold difference. The formulas for calculating the derivative of the fitting curve and the angle difference are as follows:

The analysis (Fig. 5 b) shows that when \(x=0.4\) , the angle difference reaches the maximum, and the corresponding optimal core threshold difference is \(\Delta \varepsilon _{o} =3.097\) .

figure 5

The fitted curve analysis diagram. ( a ) The derivative of the fitted curve and ( b ) the angle difference of the fitted curve.

Compression factor

Different purposes of trajectory research require different compression effects. When studying the traffic flow state of water area, the higher compression ratio is preferred; whereas when examining the ship navigation state, the higher quality of compression is more desirable. To meet the diverse research objectives, this paper introduces a compression factor, denoted as \(\rho \) , based on the optimal core threshold difference, with a default value of 0.5.

In summary, after the optimal core threshold difference is obtained, the trajectory compression can be carried out. The ACTD-DP Algorithm flow is shown in Fig. 6 , and the algorithm code is shown in Algorithm 1.

figure a

ATD-DP (Part 1).

figure 6

Algorithm flow.

figure b

ATD-DP (Part 2).

Experiment and analysis

Description of experimental data.

In order to verify the scientificity of the proposed algorithm, the AIS data of Zhoushan waters in China is selected as the experimental water area shown in Table 2 , and the time range is from 00:00 to 24:00 on May 1st, 2021. According to the ship MMSI statistical analysis, the experimental waters shared 515 ships and 404,646 AIS data. The statistics of ship types are shown in Table 3 , and the statistics of ship dimensions are shown in Table 4 .

The experimental water area and the original ship trajectories are depicted in Fig. 7 a. The raw data contains a significant amount of noise and redundant information. Preprocessing is conducted according to the method described in Section 2.3.1, and the results are presented in Fig. 7 b. The experiment was implemented on the computer(Window64 Intel(R) Xeon(R) Gold 5218R CPU @ 2.10 GHz 2.10 GHz and 32.0 GB of RAM) using MATLAB(version R2024a 32 ).

figure 7

The experimental water area and AIS data (The color curves are ship trajectories. The yellow polygon area is the land part of the experimental area. The white background indicates the experimental water area. The figure is drawn using MATLAB, which version is R2024a 32 .). ( a ) The original trajectories and ( b ) the preprocessing trajectories.

Compression results of all trajectories

To compare the compression effects of different algorithms, the SW algorithm from the reference 19 (with the distance threshold of 0.8 times the ship width), the DP algorithm from the reference 22 (with a distance threshold of 0.8 times the ship length), and the PDP (Peak–Douglas–Peucker) algorithm from the reference 31 (with the distance threshold of 0.5 times the ship length and an angular threshold of \(\hbox {10}^{\circ }\) ) and the ADP algorithm from the reference 30 (with the optimal threshold change rate of 1.36) are selected as the comparative algorithms. All trajectories are compressed by different algorithms, and the evaluation metrics values obtained are shown in Table 5 and Fig. 8 .

figure 8

Evaluation metric values comparison chart.

By analyzing Table 5 and Fig. 8 , it is obvious that the evaluation metric values corresponding to the five types of algorithms are different. The TIME value of the SW, DP, and PDP algorithms are obviously smaller than that of the ADP and ACTD-DP algorithms, indicating that the former trio exhibits lower complexity and superior computational efficiency, while the latter two algorithms, due to their trajectory division requirements, exhibit higher complexity and thus comparatively reduced computational efficiency. ADP algorithm has the lowest computational efficiency.

The SW algorithm exhibits the lowest values in terms of ACR and ALLR, yet it presents a notably high AMSED. This observation indicates that the SW algorithm, during the trajectory compression process, retains a relatively large number of non-critical points, leading to minimal discrepancies in length between the compressed and original trajectories. However, the location discrepancy is significantly pronounced, thereby yielding the least effective trajectory compression outcome among the evaluated methods.

The DP algorithm is characterized by the highest values in ACR,ALLR, and AMSED. These metrics suggest that the DP algorithm achieves a significant reduction in trajectory data, indicative of its pronounced compression efficacy. However, the substantial elimination of critical points results in considerable discrepancies in both length and location discrepancy between the compressed and original trajectories. Consequently, the DP algorithm’s trajectory compression performance is deemed to be of moderate quality.

The PDP algorithm exhibits a high ACR and the lowest ALLR among the evaluated methods, while its AMSED is relatively elevated yet notably lower than that of the DP algorithm. These observations indicate that the PDP algorithm exhibits a marked optimization over the traditional DP algorithm, yielding a more favorable trajectory compression outcome.

The ADP algorithm is distinguished by its higher ACR and ALLR, both of which surpass the corresponding values of the PDP algorithm. Additionally, the ADP algorithm exhibits a lower AMSED, signifying a reduced location discrepancy between the compressed and original trajectories. Collectively, these metric values underscore the ADP algorithm’s notable effectiveness in trajectory compression.

The ACTD-DP algorithm is notable for its minimal AMSED, which is significantly lower than the values observed in other algorithms. This algorithm also presents a higher ACR and a lower ALLR. These metric values indicate that the ACTD-DP algorithm excels in retaining critical points during the trajectory compression process, leading to a relatively higher length discrepancy but a markedly reduced location discrepancy when compared to the original trajectories. Consequently, the ACTD-DP algorithm is recognized for its superior compression performance.

Compression results of different types trajectories

To further demonstrate the robustness and applicability of the ACTD-DP algorithm, four ship trajectories were randomly selected for compression. The information for the chosen ships and their trajectories is presented in Table 6 .

Different algorithms compress the above trajectories respectively, and statistical evaluation metric values are shown in Table 7 . The TIME values corresponding to the compression of different ship trajectories by various algorithms align with the trends observed in Section 3.2, demonstrating that the TIME values for the ADP and ACTD-DP algorithms are significantly higher than those for the other algorithms.

Ship1’s course changes are small, the trajectory shape is simple, and the voyage is almost straight. MSED value of SW algorithm is the largest (62.7271 m, approximately1.1 times the ship length), and CR is suboptimal. The SW algorithm demonstrates the weaker capability in detecting and retaining critical points, particularly in areas where the trajectory’s curvature is low (region A in the Fig. 9 , where only one point is retained), leading to significant distortion in the trajectory. The DP algorithm exhibits the highest values for both CR and LLR, with the suboptimal MSED value. The DP algorithm performs the poorest in detecting and retaining critical points( region A in the Fig. 9 ,where no criticalpoints are retained), leading to the least effective compression effect. The PDP algorithm demonstrates the lowest values for LLR, with the MSED and CR being both smaller. The PDP algorithm demonstrates the stronger capability in detecting and retaining critical points, particularly handling the junctions between straight lines and curves more effectively than the DP algorithm(region A in the Fig. 9 , where three points are retained). The ADP algorithm exhibits the lowest value for CR, and LLR and MSED value are both smaller. APD algorithm has the strongest ability to retain critical points, resulting in an excessive number of trajectory points at the junctions between straight lines and curves (region A in the Fig. 9 , where ten points are retained).The ACTD-DP algorithm exhibits the lowest MSED value (42.907 m, approximately 0.8 times the ship length), CR and LLR are better. The ACTD-DP algorithm exhibits the strongest capability in detecting and retaining critical points, handling the transitions between straight lines and curves effectively ( region A in the Fig. 9 , where three points are retained too), resulting in minimal trajectory distortion and the best compression effect.

Ship2 is the fishing vessel with the lowest number of track points. However, the course changes are large and frequent, there are large angle turning and U-turn phenomena, and the navigation trajectory is the most complicated. Compared with the other three trajectories, the five algorithms yield lower CR and LLR values for this trajectory (with the best CR being 77.58% from the DP algorithm and the best LLR being 4.44% from the ADP algorithm), and the performance of MSED values is poor. The SW algorithm exhibits the lower MSED value (66.0019 m, approximately 1.8 times the ship length), while the DP algorithm exhibits the highest MSED value (155.6476 m, about 4.3 times the ship length). CR and MSED of the ACTD-DP algorithm are suboptimal. Consequently, the ACTD-DP algorithm maintains a good compression effect with the high CR and the low MSED. However, from the evaluation metrics analysis of the four trajectories compressed by ACTD-DP algorithm, the compression effect of this trajectory is the worst.

Ship3’s trajectory is relatively complex, with large course changes and sharp turns. However, due to the large proportion of straight line segments in the trajectory, the compression effect of each algorithm is similar to that of ship1. The CR Value of the SW algorithm is the highest, while its LLR and MSED values are the second highest among the evaluated methods. But the compression effect is poor for the location where the curvature of the trajectory curve changes frequently (region B in the Fig. 9 ). The DP algorithm demonstrates the highest values for CR, LLR and MSED(199.1665 m, approximately 1.3 times the ship length). This indicates a weaker capability in detecting critical points, resulting in the fewest number of critical points retained (region B in the Fig. 9 ). Consequently, the DP algorithm is associated with the poorest compression performance among the evaluated methods. The PDP algorithm exhibits the second lower CR, indicative of a relatively higher retention of trajectory points. Its LLR and MSED values are moderate, reflecting a balanced performance in terms of trajectory fidelity and compression efficiency.The PDP algorithm effectively captures critical points in the trajectory with significant changes in course, yet the fixed threshold discards many critical points (region B in the Fig. 9 ). Despite this, the overall compression performance of the PDP algorithm is commendably effective. The ADP algorithm exhibits the lowest values for CR, LLR and MSED(12.3542 meters, approximately 0.08 times the ship length). Compared to the PDP algorithm, the ADP algorithm demonstrates a heightened ability to detect critical points within the curved segments of the trajectory. However, it is noted that the ADP algorithm retains an excessive number of critical points(region B in the Fig. 9 ). This over-retention, while enhancing detection, may lead to a less efficient compression outcome.The ACTD-DP algorithm is distinguished by a high CR and is second only in terms of the lowest LLR and MSED, with the MSED (20.507 m, approximately 0.14 times the ship length). Comparatively, the ACTD-DP algorithm outperforms the ADP algorithm in the detection of critical points. During the compression of linear segments of trajectories, the algorithm retains a greater number of critical points. In the compression of curved trajectory segments, the number of retained critical points is moderate (region B in the Fig. 9 ). Therefore, the ACTD-DP algorithm is recognized for its superior compression efficacy.

Ship4’s trajectory is relatively simple with distinct boundaries between straight and curved segments. However, there is a high number of anchoring points, constituting 72% of the total number of points. As a result, the compression of the anchoring paths is significant, leading to the higher LLR values.The SW algorithm exhibits the lowest values for both CR(only 22.05%) and LLR, with the relatively large MSED. The ability of SW algorithm to detect the critical points of the line segments and the curve segments is quite different. And the SW algorithm fails to effectively process critical points in anchoring trajectories (region C in the Fig. 9 ), with the CR of less than 1% for such trajectories, thus resulting in the poorest compression performance. The DP algorithm demonstrates the highest values for CR, LLR and MSED(373.5619 meters, approximately 1.7 times the ship length). This indicates a significant reduction in trajectory detail, which adversely affects the detection capability for critical points, particularly in anchoring trajectories(region C in the Fig. 9 ). The DP algorithm’s approach compresses the entire anchoring trajectory into a single critical point, which fails to meet the research requirements for analyzing anchorage stay patterns and utilization rates. The PDP algorithm exhibits a lower CR and a suboptimal MSED, suggesting a more conservative compression strategy. While the PDP algorithm performs well in compressing linear and typical curved trajectories, its heightened sensitivity to transitional segments leads to a less effective compression of anchoring trajectories(region C in the Fig. 9 ).This overemphasis on detecting connections between trajectory segments may compromise the fidelity of the compressed trajectory in representing the original anchoring behavior. The ADP algorithm exhibits moderate values for CR, LLR and MSED. Compared to the PDP algorithm, the ADP algorithm demonstrates enhanced capabilities in detecting and retaining critical points, particularly at the junctions between linear and curved segments of trajectories. However, akin to the DP algorithm, the ADP algorithm struggles to effectively process anchoring trajectories (region C in the Fig. 9 )), thereby limiting its utility in accurately capturing the nuances of such trajectories.The ACTD-DP algorithm is distinguished by the second-highest values for CR and LLR and the lowest MSED (24.9138 m, approximately 0.11 times the ship’s length). This algorithm excels in the detection and retention of critical points, particularly with a uniform distribution of critical points in linear trajectory segments. In comparison to the ADP algorithm, the ACTD-DP algorithm also demonstrates efficacy in handling anchoring trajectories, capturing the typical positions and trajectories during the ship’s anchoring process(region C in the Fig. 9 )). Consequently, upon comprehensive analysis of the compression effects, the ACTD-DP algorithm is concluded to provide the optimal compression performance.

figure 9

Trajectory compression comparison.

Discussion and conclusion

Building upon the traditional DP algorithm 31 and drawing inspiration from the methodology of the PDP algorithm 29 and the ADP algorithm 30 , the ACTD-DP algorithm is proposed and experimental validation is conducted. The threshold values of other comparison algorithms are based on static information (ship length, ship width, fixed distance value, etc.), and the trajectory compression effects are greatly affected by the external environment, and the algorithms have poor adaptive ability. In contrast, the ACTD-DP algorithm employs the optimal threshold difference method, reducing reliance on fixed thresholds and enhancing the robustness and applicability of the algorithm. From the overall analysis of compression effects (Table 5 and Fig. 8 ), compared to the other four algorithms, the ACTD-DP algorithm demonstrates the strongest capability in detecting and retaining key points. It maintains the smallest AMSED value while preserving the higher ACR value, resulting in the best compression performance. Analyzing the evaluation metrics for the four trajectories, the ACTD-DP algorithm exhibits the best compression performance for all trajectories except Ship2’s trajectory, demonstrating strong adaptability to different trajectories.

However, the ACTD-DP algorithm also has a notable drawback. The ACTD-DP algorithm requires curve fitting and the calculation of core thresholds and optimal threshold difference. Consequently, the computational complexity is relatively high, leading to increased algorithmic execution time. Concurrently, the ACTD-DP algorithm yields the lower CR for trajectories with a limited number of points and abrupt changes in course, such as Ship2. The compression performance for these types of trajectories could be further enhanced. These observations also provide directions for future research endeavors.

Data availability

The data that support the findings of this study are available from Shanghai Maritime Safety Administration but restrictions apply to the availability of these data, which were used under license for the current study, and so are not publicly available. The datasets generated and analysed during the current study are not publicly available due data sensitivity but are available from the corresponding author on reasonable request.

Huang, C. et al. A simulation model for marine traffic environment risk assessment in the traffic separation scheme. In 2021 6th International Conference on Transportation Information and Safety (ICTIS) . 213–221 https://doi.org/10.1109/ICTIS54573.2021.9798623 (IEEE, 2021).

Kim, E. et al. Sensitive resource and traffic density risk analysis of marine spill accidents using automated identification system big data. J. Mar. Sci. Appl. 19 , 173–181. https://doi.org/10.1007/s11804-020-00138-2 (2020).

Article   MathSciNet   Google Scholar  

An, K. E-navigation services for non-SOLAS ships. Int. J. e-Navigat. Maritime Econ. 4 , 13–22. https://doi.org/10.1016/j.enavi.2016.06.002 (2016).

Article   Google Scholar  

Barco, S. G., Lockhart, G. G. & Swingle, W. M. Using RADAR & AIS to investigate ship behavior in the Chesapeake Bay ocean approach off of Virginia, USA. In 2012 Oceans . 1–8 https://doi.org/10.1109/OCEANS.2012.6404872 (IEEE, 2012).

Lei, P.-R., Yu, P.-R. & Peng, W.-C. A Framework for maritime anti-collision pattern discovery from AIS network. In 2019 20th Asia-Pacific Network Operations and Management Symposium (APNOMS) . 1–4 https://doi.org/10.23919/APNOMS.2019.8892899 (IEEE, 2019).

Han, P. & Yang, X. Big data-driven automatic generation of ship route planning in complex maritime environments. Acta Oceanol. Sin. 39 , 113–120. https://doi.org/10.1007/s13131-020-1638-5 (2020).

Hao, Y., Zheng, P. & Han, Z. Automatic generation of water route based on AIS big data and ECDIS. Arab. J. Geosci. 14 , 1–8 https://doi.org/10.1007/s12517-021-06930-w (Springer, 2021).

Blindheim, S., Johansen, T. A. & Utne, I. B. Risk-based supervisory control for autonomous ship navigation. J. Mar. Sci. Technol. 28 , 624–648. https://doi.org/10.1007/s00773-023-00945-6 (2023).

Guo, Y. & Ding, Z. Application of big data in analyzing the impact of explosive cyclone on ship navigation safety. In 2021 2nd International Conference on Smart Electronics and Communication (ICOSEC) . 910–913 https://doi.org/10.1109/ICOSEC51865.2021.9591958 (IEEE, 2021).

Liu, Z., Li, Y., Zhang, Z., Yu, W. & Du, Y. Spatial modeling and analysis based on spatial information of the ship encounters for intelligent navigation safety. Reliabil. Eng. Syst. Saf. 238 , 109489. https://doi.org/10.1016/j.ress.2023.109489 (2023).

Makris, A. et al. Evaluating the effect of compressing algorithms for trajectory similarity and classification problems. GeoInformatica 25 , 679–711. https://doi.org/10.1007/s10707-021-00434-1 (2021).

Chen, J., Zhang, J., Chen, H., Zhao, Y. & Wang, H. A TDV attention-based BiGRU network for AIS-based vessel trajectory prediction. iScience 26 , 106383 https://doi.org/10.1016/j.isci.2023.106383 (2023).

Liu, H., Liu, Y. & Zong, Z. Research on ship abnormal behavior detection method based on graph neural network. In 2022 IEEE International Conference on Mechatronics and Automation (ICMA) . 834–838 https://doi.org/10.1109/ICMA54519.2022.9856198 (IEEE, 2022).

Murray, B. & Perera, L. P. Ship behavior prediction via trajectory extraction-based clustering for maritime situation awareness. J. Ocean Eng. Sci. 7 , 1–13. https://doi.org/10.1016/j.joes.2021.03.001 (2022).

Jeong, S. & Kim, T.-W. Generating a path-search graph based on ship-trajectory data: Route search via dynamic programming for autonomous ships. Ocean Eng. 283 , 114503. https://doi.org/10.1016/j.oceaneng.2023.114503 (2023).

Meratnia, N. & De By, R. A. Spatiotemporal compression techniques for moving point objects. In (Goos, G. et al. eds.) Advances in Database Technology-EDBT 2004. Lecture Notes in Computer Science . Vol. 2992. 765–782 https://doi.org/10.1007/978-3-540-24741-8_44 (Springer, 2004).

Jie, G., Xin, S., Xiaowei, S. & Daofang, C. Online compression algorithm of fishing ship trajectories based on improved sliding window. J. Shanghai Maritime Univ. 44 , 17–24 https://doi.org/10.13340/j.jsmu.202208070214 (2023).

Zhu, F. & Ma, Z. Ship trajectory online compression algorithm considering handling patterns. IEEE Access 9 , 70182–70191. https://doi.org/10.1109/ACCESS.2021.3078642 (2021).

Gao, M. & Shi, G.-Y. Ship spatiotemporal key feature point online extraction based on AIS multi-sensor data using an improved sliding window algorithm. Sensors 19 , 2706. https://doi.org/10.3390/s19122706 (2019).

Article   ADS   PubMed   PubMed Central   Google Scholar  

Qi, Z., Yi, C., Li, X. & Wen, G. Improved sliding window trajectory compression algorithm considering motion characteristics. J. Geomat. Sci. Technol. 37 , 622–627 (2020) (5 citations (CNKI)[2024-3-13]).

Bai, X., Xie, Z., Xu, X. & Xiao, Y. An adaptive threshold fast DBSCAN algorithm with preserved trajectory feature points for vessel trajectory clustering. Ocean Eng. 280 , 114930. https://doi.org/10.1016/j.oceaneng.2023.114930 (2023).

Zhang, S.-K., Shi, G.-Y., Liu, Z.-J., Zhao, Z.-W. & Wu, Z.-L. Data-driven based automatic maritime routing from massive AIS trajectories in the face of disparity. Ocean Eng. 155 , 240–250. https://doi.org/10.1016/j.oceaneng.2018.02.060 (2018).

Article   ADS   Google Scholar  

Wei, Z., Xie, X. & Zhang, X. AIS trajectory simplification algorithm considering ship behaviours. Ocean Eng. 216 , 108086. https://doi.org/10.1016/j.oceaneng.2020.108086 (2020).

Huang, C., Qi, X., Zheng, J., Zhu, R. & Shen, J. A maritime traffic route extraction method based on density-based spatial clustering of applications with noise for multi-dimensional data. Ocean Eng. 268 , 113036. https://doi.org/10.1016/j.oceaneng.2022.113036 (2023).

Shukai, Z., Zhengjiang, L., Xianku, Z., Guoyou, S. & Yao, C. A method for AIS track data compression based on Douglas–Peucker algorithm. J. Harbin Eng. Univ. 36 , 595–599 (2015).

Google Scholar  

Li, H. et al. Unsupervised hierarchical methodology of maritime traffic pattern extraction for knowledge discovery. Transport. Res. Part C Emerg. Technol. 143 , 103856. https://doi.org/10.1016/j.trc.2022.103856 (2022).

Cui, C. & Dong, Z. Ship space-time AIS trajectory data compression method. In 2022 7th International Conference on Big Data Analytics (ICBDA) . 40–44 https://doi.org/10.1109/ICBDA55095.2022.9760355 (IEEE, 2022).

Zhou, Z., Zhang, Y., Yuan, X. & Wang, H. Compressing AIS trajectory data based on the multi-objective peak Douglas–Peucker algorithm. IEEE Access 11 , 6802–6821. https://doi.org/10.1109/ACCESS.2023.3234121 (2023).

Zhao, L. & Shi, G. A method for simplifying ship trajectory based on improved Douglas–Peucker algorithm. Ocean Eng. 166 , 37–46. https://doi.org/10.1016/j.oceaneng.2018.08.005 (2018).

Tang, C. et al. A method for compressing AIS trajectory data based on the adaptive-threshold Douglas–Peucker algorithm. Ocean Eng. 232 , 109041. https://doi.org/10.1016/j.oceaneng.2021.109041 (2021).

Douglas, D. H. & Peucker, T. K. Algorithms for the reduction of the number of points required to represent a digitized line or its caricature. In Classics in Cartography (Dodge, M. ed.). 1 Ed. 15–28 https://doi.org/10.1002/9780470669488.ch2 (Wiley, 2011).

MathWorks, I. Matlab . https://www.mathworks.com/products/matlab/ (2024).

Download references

Acknowledgements

This study is supported by the research project “Science and Technology Commission of Shanghai Municipality” (Grant Nos. 22010502000 and 23010501900).

Author information

These authors contributed equally: Ting Zhang, Zhiming Wang.

Authors and Affiliations

Merchant Marine College, Shanghai Maritime University, Shanghai, 201306, China

Ting Zhang, Zhiming Wang & Peiliang Wang

Shandong Transport Vocational College, Weifang, 261206, Shandong, China

Shandong Vocation College of Science and Technology, Weifang, 261053, Shandong, China

Peiliang Wang

You can also search for this author in PubMed   Google Scholar

Corresponding author

Correspondence to Peiliang Wang .

Ethics declarations

Competing interests.

The authors declare no competing interests.

Additional information

Publisher's note.

Springer Nature remains neutral with regard to jurisdictional claims in published maps and institutional affiliations.

Rights and permissions

Open Access This article is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License, which permits any non-commercial use, sharing, distribution and reproduction in any medium or format, as long as you give appropriate credit to the original author(s) and the source, provide a link to the Creative Commons licence, and indicate if you modified the licensed material. You do not have permission under this licence to share adapted material derived from this article or parts of it. The images or other third party material in this article are included in the article’s Creative Commons licence, unless indicated otherwise in a credit line to the material. If material is not included in the article’s Creative Commons licence and your intended use is not permitted by statutory regulation or exceeds the permitted use, you will need to obtain permission directly from the copyright holder. To view a copy of this licence, visit http://creativecommons.org/licenses/by-nc-nd/4.0/ .

Reprints and permissions

About this article

Cite this article.

Zhang, T., Wang, Z. & Wang, P. A method for compressing AIS trajectory based on the adaptive core threshold difference Douglas–Peucker algorithm. Sci Rep 14 , 21408 (2024). https://doi.org/10.1038/s41598-024-71779-4

Download citation

Received : 01 May 2024

Accepted : 30 August 2024

Published : 13 September 2024

DOI : https://doi.org/10.1038/s41598-024-71779-4

Share this article

Anyone you share the following link with will be able to read this content:

Sorry, a shareable link is not currently available for this article.

Provided by the Springer Nature SharedIt content-sharing initiative

  • Ship trajectory
  • Trajectory compression

By submitting a comment you agree to abide by our Terms and Community Guidelines . If you find something abusive or that does not comply with our terms or guidelines please flag it as inappropriate.

Quick links

  • Explore articles by subject
  • Guide to authors
  • Editorial policies

Sign up for the Nature Briefing: Anthropocene newsletter — what matters in anthropocene research, free to your inbox weekly.

assignment to function parameter 'result'

  • Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
  • Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand
  • OverflowAI GenAI features for Teams
  • OverflowAPI Train & fine-tune LLMs
  • Labs The future of collective knowledge sharing
  • About the company Visit the blog

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Get early access and see previews of new features.

assignment operator within function parameter C++

I'm studying data structures (List, Stack, Queue), and this part of code is confusing me.

  • Why there are assignment operators within function parameters?
  • What does Object() call do?
  • assignment-operator
  • function-parameter

Harry Cho's user avatar

3 Answers 3

Those are not assignment operators. Those are default arguments for the function.

A function can have one or more default arguments , meaning that if, at the calling point, no argument is provided, the default is used.

In the example code you posted, the ListNode constructor has two parameters with default arguments. The first default argument is Object() , which simply calls the default constructor for Object . This means that if no Object instance is passed to the ListNode constructor, a default of Object() will be used, which just means a default-constructed Object .

See also: Advantage of using default function parameter Default value of function parameter

M.M's user avatar

  • I'm tempted to up-vote if you would mention that default parameters are one of the more "evil" C++ features. They turn innocent constructors in converting constructors or default constructors. They make it hard to bind functions. The are a hindrance when only some parameters should be specified and others left to default. –  pmr Commented Apr 11, 2012 at 10:56
  • Me neither. One size does not fit all. Sometimes they are very useful. –  Spook Commented Apr 11, 2012 at 11:00
  • @pmr, I don't necessarily agree with you that they are "evil". They are a useful way to avoid repeating yourself by writing multiple constructors, when you can simply provide one constructor with a default parameter. The standard library implementations often take advantage of this by, e.g. vector(const allocator_type& a = allocator_type()); –  Charles Salvia Commented Apr 11, 2012 at 11:08
  • @pmr: I don't necessarily agree they are evil. However I agree that 1. the constructor should be marked explicit if it can be called with a single argument and 2. when parameters abund the function is a pain to use... but neither is specifically linked to default parameters per se. –  Matthieu M. Commented Apr 11, 2012 at 11:50
  • @CharlesSalvia Making objects default constructible is one of the nice use cases for default arguments. I put "evil" in quotes to indicate that there are use cases but that some care has to be taken and they shouldn't be the first option. –  pmr Commented Apr 11, 2012 at 11:56

The assignments in declarations provide default values for optional parameters . Object() means a call to Object 's default constructor.

The effect of the default parameters is as follows: you can invoke ListNode constructor with zero, one, or two parameters. If you specify two parameter expressions, they are passed as usual. If you specify only one expression, its value is passed as the first parameter, and the second one is defaulted to NULL . If you pass no parameters, the first parameter is defaulted to an instance of Object created with its default constructor, and the second one is defaulted to NULL .

Sergey Kalinichenko's user avatar

go to http://www.errorless-c.in/2013/10/operators-and-expressions.html for operators and expressions in c programming language

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged c++ parameters assignment-operator function-parameter or ask your own question .

  • The Overflow Blog
  • One of the best ways to get value for AI coding tools: generating tests
  • The world’s largest open-source business has plans for enhancing LLMs
  • Featured on Meta
  • User activation: Learnings and opportunities
  • Site maintenance - Mon, Sept 16 2024, 21:00 UTC to Tue, Sept 17 2024, 2:00...
  • What does a new user need in a homepage experience on Stack Overflow?
  • Announcing the new Staging Ground Reviewer Stats Widget

Hot Network Questions

  • Difference between 2 version numbers from `adb --version`
  • What would be an appropriate translation of Solitude?
  • Why was Panama Railroad in poor condition when US decided to build Panama Canal in 1904?
  • Should I write an email to a Latino teacher working in the US in English or Spanish?
  • Why were there so many OSes that had the name "DOS" in them?
  • 4/4 time change to 6/8 time
  • Creating good tabularx
  • How can I support a closet rod where there's no shelf?
  • How can a microcontroller (such as an Arduino Uno) that requires 7-21V input voltage be powered via USB-B which can only run 5V?
  • How to expand argument in the Expl3 command \str_if_eq?
  • Why did early ASCII have ← and ↑ but not ↓ or →?
  • Why is resonance such a widespread phenomenon?
  • Negating a multiply quantified statement
  • Why was Esther included in the canon?
  • What is the origin of 找碴?
  • Look for mistakes!
  • "Famous award" - "on ships"
  • Browse a web page through SSH? (Need to access router web interface remotely, but only have SSH access to a different device on LAN)
  • How to apply a squared operator to a function?
  • Non-existence of power divided structure on a maximal ideal of truncated polynomial rings (example from Koblitz)
  • What came of the Trump campaign's complaint to the FEC that Harris 'stole' (or at least illegally received) Biden's funding?
  • Is downsampling a valid approach to compare regression results across groups with different sample sizes? If so, how?
  • Drill perpendicular hole through thick lumber using handheld drill
  • Copyright Fair Use: Is using the phrase "Courtesy of" legally acceptable when no permission has been given?

assignment to function parameter 'result'

COMMENTS

  1. Assignment to property of function parameter (no-param-reassign)

    10. This is a common ESLint issue that appears frequently on old codebase. You have modified the result variable which was passed as parameter. This behavior is prohibited by the rule. To resolve it, copy the argument to a temporary variable and work on it instead: export const fn = article => article.categoryValueDtoSet.reduce((res, item) => {.

  2. Assignment to property of function parameter no-param-reassign

    function createEmployee(emp) { // ⛔️ Assignment to property of function parameter 'emp'. eslint no-param-reassign. emp.name = 'bobby hadz'; emp.salary = 500; return emp; } The ESLint rule forbids assignment to function parameters because modifying a function's parameters also mutates the arguments object and can lead to confusing behavior.

  3. How to Assign to the Property of a Function Parameter in JavaScript

    You can use assignment to property of function parameter to initialize the value of a parameter. For example, the following code initializes the `name` property of the `greet` function parameter to the value of the `"world"` argument: js. function greet (name) {. name.value = "world"; }

  4. no-param-reassign

    If you want to allow assignment to function parameters, then you can safely disable this rule. Strict mode code doesn't sync indices of the arguments object with each parameter binding. Therefore, this rule is not necessary to protect against arguments object mutation in ESM modules or other strict mode functions. Version

  5. Understanding ESLint's `no-param-reassign` Rule for Clearer Functions

    These are called parameters. The no-param-reassign rule discourages directly changing the value of these parameters within the function. There are two reasons for this: Clarity: If you modify a parameter inside the function, it can be confusing for someone reading the code to understand what the function does.

  6. JavaScript: Don't Reassign Your Function Arguments

    As the article you quoted states, the variables x, y, and z are synonymous with arguments [0], [1], and [2] respectively, so if I called example(3,4) all I would be doing in my function is assigning 3 to x and 4 to y with the function call, then assigning 1 to x, the value of x to y, then the value of y to z. All of my values would be the same ...

  7. Destructuring Assignment In A Function Parameter

    Imagine you have a To-Do app and one of those functions was addTodoItem and you had to call this function in different places. Function declaration would look like this: function addTodoItem (title, description, dueDate) { // Your code here} Before calling the function, see the characteristics for each parameter: Title => required.

  8. no-param-reassign

    Rule Details. This rule aims to prevent unintended behavior caused by modification or reassignment of function parameters. Examples of incorrect code for this rule: /*eslint no-param-reassign: "error"*/ function foo (bar) {. bar = 13; } function foo (bar) {. bar++;

  9. Destructuring assignment

    Objects passed into function parameters can also be unpacked into variables, which may then be accessed within the function body. As for object assignment, the destructuring syntax allows for the new variable to have the same name or a different name than the original property, and to assign default values for the case when the original object ...

  10. JavaScript Function Parameters

    The parameters, in a function call, are the function's arguments. JavaScript arguments are passed by value: The function only gets to know the values, not the argument's locations. If a function changes an argument's value, it does not change the parameter's original value. Changes to arguments are not visible (reflected) outside the function.

  11. no-param-reassign

    Side effects on parameters can cause counter-intuitive execution flow and make errors difficult to track down. Rule Details. This rule aims to prevent unintended behavior caused by modification or reassignment of function parameters. Examples of incorrect code for this rule: /*eslint no-param-reassign: "error"*/ function foo (bar) { bar = 13 ...

  12. Functions

    The function square takes one parameter, called number.The function consists of one statement that says to return the parameter of the function (that is, number) multiplied by itself.The return statement specifies the value returned by the function, which is number * number.. Parameters are essentially passed to functions by value — so if the code within the body of a function assigns a ...

  13. Functions

    Generally speaking, a function is a "subprogram" that can be called by code external (or internal, in the case of recursion) to the function. Like the program itself, a function is composed of a sequence of statements called the function body. Values can be passed to a function as parameters, and the function will return a value.

  14. Function expressions

    Here's what happens above in detail: The Function Declaration (1) creates the function and puts it into the variable named sayHi.; Line (2) copies it into the variable func.Please note again: there are no parentheses after sayHi.If there were, then func = sayHi() would write the result of the call sayHi() into func, not the function sayHi itself.; Now the function can be called as both sayHi ...

  15. Why assignment to property of function parameter is bad style

    Use saved searches to filter your results more quickly. Name. Query. To see all available qualifiers, see our documentation. Cancel Create saved search ... Why assignment to property of function parameter is bad style. #1217. Closed zhaoxiongfei opened this issue Dec 21, 2016 · 14 comments · Fixed by #1325.

  16. PHP: Function arguments

    Function arguments. ¶. Information may be passed to functions via the argument list, which is a comma-delimited list of expressions. The arguments are evaluated from left to right, before the function is actually called (eager evaluation). PHP supports passing arguments by value (the default), passing by reference, and default argument values.

  17. Assignment could be replaced with operator assignment

    Assignment could be replaced with operator assignment. Reports an assignment operation that can be replaced by an operator assignment to make your code shorter and probably clearer. Example: x = x + 3; x = x / 3; After the quick fix is applied the result looks like: x += 3; x /= 3; Locating this inspection By ID

  18. How to solve this assignment to property of function parameter

    Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers; Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand; OverflowAI GenAI features for Teams; OverflowAPI Train & fine-tune LLMs; Labs The future of collective knowledge sharing; About the company Visit the blog

  19. A method for compressing AIS trajectory based on the adaptive core

    The literature uses the parameter self-selection method for the Silhouette Coefficient scores, but the determination of the optimal parameter combination will require extensive experiments and ...

  20. assignment operator within function parameter C++

    19. Those are not assignment operators. Those are default arguments for the function. A function can have one or more default arguments, meaning that if, at the calling point, no argument is provided, the default is used. void foo(int x = 10) { std::cout << x << std::endl; } int main()