Your function:
function(json) {
    data2 = json;
}
is executed after
console.log(data2);
SelectedData = data2;
data2 is not defined yet at that point.
(1) function prepData(){
(2)    data2 = []; 
(3)    $.getJSON('http://localhost/data').done(function(json) {
(4)        data2 =json;
(5)        console.log(data2);
       });
(6)    console.log(data2);
(7)    SelectedData= data2;
(8)    return SelectedData;
   };
Execution order:
1 -> 2 -> 3 -> 6 -> 7 -> 8 -> 4 -> 5
Common practice - Return promise instead of data:
function prepData(){
    return $.getJSON('http://localhost/data');
}
// more code here
prepData().done(function(json){
    console.log(json);
});
Take a look at these more detailed demos.
jQuery on ES5: https://jsfiddle.net/DerekL/xtmy6po0/ 
function timeout(n){
    // create promise
    var defer = $.Deferred();
    // resolve after n milliseconds
    setTimeout(function(){
        defer.resolve(n);
    }, n);
    // return new promise that apply custom text
    return defer.then(function(v){
        return "Resolved after " + (v/1000) + " seconds";
    });
}
timeout(3000).then(function(message){
    // will be executed after 3 seconds
    alert(message);
});
Equivalent ES7: https://jsfiddle.net/DerekL/8kLknbne/
async function timeout(n){
    // create timer
    let timer = () => new Promise(resolve => setTimeout(() => resolve(n), n));
    // return message
    return "Resolved after " + (await timer()/1000) + " seconds";
}
// call
timeout(3000).then(alert);