Yes, because "a" is not an object, it is a reference to an object. This reference is passed by value.
This kind of thing is why I'd recommand everybody to know C: when you know pointers there's no magic anywhere anymore
Something like this, without any kind of error checking being done.
#include <stdlib.h>
// assume some hash table library, exercise for the reader
typedef struct{} *hashtable_t;
extern hashtable_t hashtable_init(void);
extern void hashtable_put(hashtable_t hashtable, const char* key, const char* value);
extern void hashtable_dump(hashtable_t hashtable);
typedef struct {
hashtable_t table;
} data_t;
void foo(data_t* a)
{
hashtable_put(a->table, "otherKey", "b");
}
int main(void)
{
// let a = {key: 'a'};
data_t* a = (data_t*) malloc(sizeof(data_t));
a->table = hashtable_init();
hashtable_put(a->table, "key", "a");
foo(a);
// console.log( a );
hashtable_dump(a->table);
return 0;
}
The function foo() gets the numeric value of the a pointer, thus a parameter inside foo() points to the same memory location.
If C had pass-by-reference, it would be possible to give (implicitly) the memory location of the local variable a in main() instead. For example, like in Pascal (var) or C++ (& in function declaration).