Есть ли способ получить значение объекта по умолчанию в глобальной области видимости?
Например, предположим, что мне нужно использовать Math.round
, но Math.round
было перезаписано другим значением. Вот пример того, о чем я говорю:
// script1.js (can't be edited)
Math.round = () => null;
Object.freeze(Math); // delete Math.round method and freeze Math object
// script2.js (loads after script1.js)
console.info(Math.round(3.141592)); // should return 3
Можно ли получить значение по умолчанию, которое устанавливает браузер (function round() { [native code] }
) после его перезаписи в Javascript?
Да, но мне нужно иметь к нему доступ после удаления
Не уверен, что вы имеете в виду под доступом, но если вы заморозите перед тем, как переназначить функцию, то она сохранит свое исходное значение, и вы сможете использовать console.info 3 и использовать функцию, как будто вы никогда ее не редактировали.
@FarazShaikh Я обновил вопрос. По сути, замораживание выполняется в сценарии, который нельзя редактировать и который всегда загружается до того момента, когда мне нужно получить доступ к свойству.
Вы можете использовать iframe и получить его математический объект, а затем сразу удалить iframe. Я бы разместил это решение здесь, но оно не позволяет мне получить доступ к фреймам из-за исключения безопасности.
Единственное решение, которое я могу придумать, это использовать iframes. Каждый iframe будет иметь свой собственный недавно созданный объект окна, который затем можно будет использовать в родительском фрейме (если они имеют одно и то же происхождение).
Math.round = () => null
const frame = document.createElement('iframe')
document.body.appendChild(frame)
Math.round(2.5) // null
frame.contentWindow.Math.round(2.5) // 3
Вы даже можете вызывать функции DOM из iframe для текущей страницы, если вы укажете правильное «это» для функции:
// will return your page's body, not the body in the iframe.
// This is because we're telling it to use our document object as "this", instead of the iframe's document.
frame.contentWindow.document.querySelector.call(document, 'body')
В будущем мы можем получить лучшую поддержку для запуска сценариев в их собственной изолированной «области», где у них может быть свое собственное отдельное глобальное окружение, с которым можно возиться. См. это предстоящее предложение ecmascript, чтобы узнать больше. (на момент написания это находится на стадии 2)
Наконец, я отмечу пару альтернативных решений, которые могут быть лучшим способом в зависимости от ситуации:
+1 за последнюю часть. Либо вы доверяете автору скрипта, чтобы он не связывался с вашей страницей, либо вам вообще не следует запускать его скрипт на своей странице (без изоляции).
Если вы заморозите его перед удалением, оно сохранит исходное значение, если это то, о чем вы просите.