Они используют довольно сложную систему белых списков, которую можно найти здесь .
По сути, они имеют некоторые встроенные элементы, помеченные как безопасные, и проходят через все внутренние элементы выражения, выходя из него, как только они не знают, безопасно ли что-то или нет.
Что касается объяснения того, почему два выражения, которые вы дали, не дают одинакового результата ... Это может быть довольно сложно.
Но мы уже можем заметить, что оба являются геттерами и, таким образом, оба будут вызывать внутреннюю функцию для возврата вычисленного значения. Эта функция получения может сама запустить некоторый код, который будет иметь некоторые побочные эффекты.
Например,
const o = {
_count: 0,
get count() { return this._count++; }
};
Оттуда, оценка o.count
будет увеличивать свойство _count
, и, таким образом, этот метод получения помечается как небезопасный.
Теперь я должен признать, что я не уверен, что внутренне вызывает .href
, и почему этот алгоритм пометит его как небезопасный, но ясно, что что-то есть ...
И если вы абсолютно хотите знать, что это такое, тогда вы можете проверить document.baseURI
внутренности, которые должны вызываться с .href
и которые помечены как небезопасные.