Your quoted code does not behave as you've described. But trying to answer the question anyway, here's your code with some inline explanation:
var process = function (test) {
var i = test;
// Here you're creating a "closure" over the context of
// this specific call to this function. So the `i` local
// variable lives on, even after this function call
// terminates.
this.echo = function () { console.log(i); };
};
// This `test` variable is *completely and totally* unrelated to the
// `test` argument to your function above. They do not interact in
// any way.
var test = 'hai';
// Here, yu're passing the *value* of the `test` variable ("hai")
// into the function. The function has no reference to the `test`
// variable at all (er, not a relevant way; details below). From
// the function's point of view, it's *exactly* like
// `var hai = new process("hai");`
var hai = new process(test);
// This will show "hai"
hai.echo();
// This will also show "hai", because again, the `i` in the `echo`
// function is the local variable in the call to `new process` above;
// it is in no way whatsoever related to the `test` variable here.
test = 'sorry';
hai.echo();
More to explore (in my blog): Closures are not complicated
Details on my note about how the process function doesn't have a relevant reference to the test variable: Technically, the function you're assigning to process does have a reference to the test variable because it's a closure over the scope in which the test variable is defined. But it's not using that, because it has its own test argument and that symbol shadows (overrides) the one from the containing scope. None of which has anything to do with your passing test into the call to the process function, which is why it's irrelevant.