Можно сказать, своя область видимости есть у каждого константного значения переменной index. Секрет фокуса тут не в инкапсуляции, а в замыкании. Потому что наша функция должна была бы выглядеть как-то так примерно:
function(index){
function(event){
event.preventDefault();
alert(index + 1);
}
}
Но она так не выглядит, потому что когда она вызывается, никакого index во внешнем мире не существует, а вызывается она из элемента, который был когда-то временно прописан в коллекции linksCollection, и получил там значение переменной index, хотя, кажется, там была целая функция.
Но это только так кажется, потому что функция в памяти существует в одном-единственном экземпляре, каждый onclick получает только ссылку на неё, в которую неявно подмыкается значение переменной index, как будто где-то рядом есть такой волшебный цикл, который в момент нажатия на ссылку чудесно оказывается в нужной итерации, но это мираж, потому что цикл уже отработал и ушёл на пенсию.
Беспредел есть только в голове. А в памяти всё как раз оптимальненько, скорее всего.