The easiest thing you can do, is to create the markup of the modal as a <form>. This will allow you to access both the .modal() and the <form> objects from the various event (e.g. hidden.bs.modal) handlers as this.
When you have access to the form itself, you could either use the .serializeArray() method of jQuery or use the native FormData class like in the example below.
$('#modal-form').on('hidden.bs.modal', function (event) {
// `this` is the modal window, which is also a `<form>` in our case
// Option 1: using `.serializeArray()` of jQuery
var fieldsAsArray = $(this).serializeArray();
console.log('fieldsAsArray', fieldsAsArray);
// Option 2: using native `FormData` object
var fieldsAsFormData = new FormData(this);
console.log('fieldsAsFormData', fieldsAsFormData);
});
<!-- Note the `<form>` tag -->
<form class="modal fade" id="modal-form" tabindex="-1" role="dialog" aria-labelledby="modal-dialogLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modal-dialogLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<!-- actual form markup -->
<div class="form-group">
<label for="field1">Example label</label>
<input name="field1" type="text" class="form-control" id="field1" placeholder="Example input">
</div>
<div class="form-group">
<label for="field2">Another label</label>
<input name="field2" type="text" class="form-control" id="field2" placeholder="Another input">
</div>
<!-- /actual form markup -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button id="save" data-dismiss="modal" type="submit" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</form>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal-form">
Open modal form
</button>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/js/bootstrap.min.js"></script>
Note: Even though the “Save changes” button is of type submit, the form won’t get submitted directly this way, since there is the data-dismiss="modal" attribute as well. That attribute captures the click event with an event.preventDefault(); call. I believe this fits into your scenario as you want to work on the form data without first submitting it.