Great work!
However, you're going to run into problems if you test your code on strings like:
isBalanced("if (i <= 10) { }");
Personally, I find allowedSymbols = "()[]{}"; more practical
The keyword const
You can use const stack = []; since your pointer never changes from the initial array. The keyword const only cares if the variable is assigned something else. It doesn't matter if the thing it points to is mutated.
Code clarity
I think you could format some of your code more clearly. Specifically, inside the for loop:
for (let i = 0; i < str.length; i++) {
  let c = str[i];
  let symbolPosition = allowedSymbols.indexOf(c);
  if (symbolPosition !== -1) {
    let isOpen = symbolPosition % 2 === 0;
    if (isOpen) {
      stack.push(symbolPosition);
    }
    else {
      let lastPosition = stack.pop(); // If you call pop() on an empty array, it returns undefined.
      if (allowedSymbols.indexOf(lastPosition) !== symbolPosition - 1) {
        return false;
      }
    }
  }
}
This way you avoid using continue, and you don't call pop inside an if statement's conditional.
I would also recommend shorter variable names. Your code is not that long, and a lot of the information about a variable can be deduced from its initialization.
function isBalanced(str) {
  const stack = [];
  const brackets = '()[]<>';
  for (let i = 0; i < str.length; i++) {
    const b = brackets.indexOf(str[i]);
    if (b !== -1) {
      if (b % 2 === 0) { // is open bracket
        stack.push(b);
      }
      else {
        const last = stack.pop();
        if (brackets.indexOf(last) !== b - 1) { // if brackets don't match
          return false;
        }
      }
    }
  }
  return stack.length === 0;
}
Unit Tests
Here's an easy to use, basic testing suite for your code:
// Basic testing suite
function testIsBalanced(input, expectedOutput) {
  if (isBalanced(input) !== expectedOutput) {
    throw "Failed test for input: " + input;
    // console.error("Failed test for input: " + input);
  }
}
testIsBalanced("[]", true);
testIsBalanced("()", true);
testIsBalanced("{}", true);
testIsBalanced("({}[])", true);
testIsBalanced("({([{({()})}])})", true);
testIsBalanced("[&](param1){ std::cout << param1 << std::endl; }", true);
testIsBalanced("{if (x) {objects[i][key] === correct()} else { } {([])} }", true);
testIsBalanced("{[}]", false);
testIsBalanced("{", false);
testIsBalanced(")", false);
testIsBalanced("[{]", false);
console.log("all tests passed");
ES6
If you're feeling frisky, you could use Array.prototype.forEach, and an arrow function for your string to iterate through the chars, but I wouldn't recommend it.
let str = "Hello World";
Array.prototype.forEach.bind(str)((c)=>{
  console.log(c);
});
The biggest reason against it is code clarity. Another reason is that the code runs less efficiently since forEach has to call the lambda (the arrow function) at each step of the iteration. 
     
    
)(looks balanced, but not well-formed. (Andif (!~allowedSymbols.indexOf(c)) continue;suggests significant rather than allowed.) \$\endgroup\$