As you are using a recent ECMAScript 5 method then you may want to consider using Array.map and Array.filter along with a new Harmony proposed method Object.is
Javascript
var func = {}.is,
    is;
if (typeof func === "function") {
    is = func;
} else {
    is = function is(x, y) {
        if (x === y) {
            if (x === 0) {
                return 1 / x === 1 / y;
            }
            return true;
        }
        var x1 = x,
            y1 = y;
        return x !== x1 && y !== y1;
    };
}
function indexesOf(array, value) {
    if (!Array.isArray(array)) {
        throw new TypeError("First attribute must be an array.");
    }
    return array.map(function (element, index) {
        if (is(value, element)) {
            return index;
        }
    }).filter(function (element) {
        return typeof element === "number";
    });
}
var test = [1, 2, 4, 2];
console.log(indexesOf(test, 2));
Output 
[1, 3] 
On jsfiddle
Update: I have been castigated in the past for using loops when people have the strong belief "but this is exactly what these new methods are designed for". So, I am going to present alternative single loop solutions too.
ECMAScript 5 Array.reduce
Javascript
function indexesOf(array, value) {
    if (!Array.isArray(array)) {
        throw new TypeError("First attribute must be an array.");
    }
    return array.reduce(function (previous, current, index) {
        if (is(value, current)) {
            previous.push(index);
        }
        return previous;
    }, []);
}
On jsfiddle
ECMAScript 5 Array.forEach
Javascript
function indexesOf(array, value) {
    if (!Array.isArray(array)) {
        throw new TypeError("First attribute must be an array.");
    }
    var indexes = [];
    array.forEach(function (element, index) {
        if (is(value, element)) {
            indexes.push(index);
        }
    });
    return indexes.
}
On jsfiddle
ECMAScript 5 Array.indexOf
Note: this method is unable to find the indexes of NaN
Could also use Array.lastIndexOf and work in reverse
Javascript
function indexesOf(array, value) {
    if (!Array.isArray(array)) {
        throw new TypeError("First attribute must be an array.");
    }
    var index = array.indexOf(value),
        indexes = [];
    while (index !== -1) {
        indexes.push(index);
        index = array.indexOf(value, index + 1);
    }
    return indexes;
}
On jsfiddle
standard for
Javascript
function indexesOf(array, value) {
    if ({}.toString.call(array) !== "[object Array]") {
        throw new TypeError("First attribute must be an array.");
    }
    var indexes = [],
        length,
        index;
    for (index = 0, length = array.length; index < length; index += 1) {
        if (array.hasOwnProperty(index) && is(value, array[index])) {
            indexes.push(index);
        }
    }
    return indexes;
}
On jsfiddle
Standard while
Javascript
function indexesOf(array, value) {
    if ({}.toString.call(array) !== "[object Array]") {
        throw new TypeError("First attribute must be an array.");
    }
    var length = array.length,
        indexes = []
        index = 0;
    while (index < length) {
        if (array.hasOwnProperty(index) && is(value, array[index])) {
            indexes.push(index);
        }
        index += 1;
    }
    return indexes;
}
On jsfiddle
Standard for...in
Note: This is NOT recommended, but should be fine.
Why is using “for…in” with array iteration such a bad idea?
Javascript
function indexesOf(array, value) {
    if ({}.toString.call(array) !== "[object Array]") {
        throw new TypeError("First attribute must be an array.");
    }
    var indexes = [],
        prop;
    for (prop in array) {
        if (array.hasOwnProperty(prop) && is(+prop, prop >>> 0) && is(value, array[prop])) {
            indexes.push(+prop);
        }
    }
    return indexes;
}
On jsfiddle
Note: All of the solutions here handle both dense and sparse arrays.
And finally a jsperf comparing all of these solutions.